diff --git a/.gitignore b/.gitignore index e78c1e7e24..7fe2778755 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,19 @@ dependency-reduced-pom.xml *.so *.dylib *.dll + +xml/src/test/resources/example_dom4j_new.xml +xml/src/test/resources/example_dom4j_updated.xml +xml/src/test/resources/example_jaxb_new.xml +core-java-io/hard_link.txt +core-java-io/target_link.txt +core-java/src/main/java/com/baeldung/manifest/MANIFEST.MF +ethereum/logs/ +jmeter/src/main/resources/*-JMeter.csv + +**/node_modules/ +**/dist +**/tmp +**/out-tsc +**/nbproject/ +**/nb-configuration.xml \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 9c5cdb8f2d..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "testgitrepo"] - path = testgitrepo - url = /home/prd/Development/projects/idea/tutorials/spring-boot/src/main/resources/testgitrepo/ diff --git a/.travis.yml b/.travis.yml index 4df8a96f6d..5e2d690b4e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ before_install: - echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc install: skip -script: travis_wait 60 mvn -q install +script: travis_wait 60 mvn -q install -Pdefault sudo: required diff --git a/JGit/pom.xml b/JGit/pom.xml index 4feb31b758..176d55d321 100644 --- a/JGit/pom.xml +++ b/JGit/pom.xml @@ -1,11 +1,13 @@ - + 4.0.0 com.baeldung - JGitSnippets + JGit 1.0-SNAPSHOT jar http://maven.apache.org + JGit com.baeldung @@ -45,7 +47,6 @@ - UTF-8 4.5.0.201609210915-r diff --git a/JGit/src/main/resources/logback.xml b/JGit/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/JGit/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 1d916c8409..8e0a5eb9ee 100644 --- a/README.md +++ b/README.md @@ -2,41 +2,27 @@ The "REST with Spring" Classes ============================== -After 5 months of work, here's the Master Class of REST With Spring:
-**[>> THE REST WITH SPRING MASTER CLASS](http://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** +Here's the Master Class of REST With Spring (along with the newly announced Boot 2 material):
+**[>> THE REST WITH SPRING - MASTER CLASS](http://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** And here's the Master Class of Learn Spring Security:
-**[>> LEARN SPRING SECURITY MASTER CLASS](http://www.baeldung.com/learn-spring-security-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=lss#master-class)** +**[>> LEARN SPRING SECURITY - MASTER CLASS](http://www.baeldung.com/learn-spring-security-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=lss#master-class)** -Spring Tutorials +Java and Spring Tutorials ================ -This project is **a collection of small and focused tutorials** each covering a single and well defined area of development. -Most of the tutorial projects are focused on the `Spring Framework` (and `Spring Security`). +This project is **a collection of small and focused tutorials** - each covering a single and well defined area of development in the Java ecosystem. +A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Securiyt. In additional to Spring, the following technologies are in focus: `core Java`, `Jackson`, `HttpClient`, `Guava`. + Building the project ==================== -To do the full build, do: `mvn install -Dgib.enabled=false` +To do the full build, do: `mvn install -Pdefault -Dgib.enabled=false` -Working with the code in Eclipse -================================ -Any IDE can be used to work with the projects, but if you're using Eclipse, consider the following. - -- import the included **formatter** in Eclipse: -`https://github.com/eugenp/tutorials/tree/master/eclipse` - - -CI - Jenkins -================================ -This tutorials project is being built **[>> HERE](https://rest-security.ci.cloudbees.com/job/tutorials-unit/)** - -### Relevant Articles: -================================ - -- [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) +Building a single module +==================== +To build a specific module run the command: `mvn clean install -Dgib.enabled=false` in the module directory diff --git a/Twitter4J/pom.xml b/Twitter4J/pom.xml index 0b581a5d43..982c1adc23 100644 --- a/Twitter4J/pom.xml +++ b/Twitter4J/pom.xml @@ -1,12 +1,9 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.mabsisa Twitter4J jar - 1.0-SNAPSHOT Twitter4J - http://maven.apache.org com.baeldung @@ -14,39 +11,16 @@ 1.0.0-SNAPSHOT - - UTF-8 - UTF-8 - 1.8 - - org.twitter4j twitter4j-stream - 4.0.6 + ${twitter4j-stream.version} - - ${project.artifactId} - - - src/main/resources - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - **/ApplicationTest.java - - - - - + + 4.0.6 + diff --git a/Twitter4J/src/main/resources/logback.xml b/Twitter4J/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/Twitter4J/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/activejdbc/pom.xml b/activejdbc/pom.xml index f6e21edeb1..542e674ff3 100644 --- a/activejdbc/pom.xml +++ b/activejdbc/pom.xml @@ -1,7 +1,6 @@ + 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 activejdbc 1.0-SNAPSHOT jar @@ -15,12 +14,6 @@
- - junit - junit - ${junit.version} - test - org.javalite activejdbc @@ -85,58 +78,12 @@ - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - brief - true - false - - **/*Spec*.java - **/*Test*.java - - - **/helpers/* - **/*$* - - - - - - snapshots1 - JavaLite Snapshots1 - http://repo.javalite.io/ - - true - always - warn - - - - - - - snapshots2 - JavaLite Snapshots2 - http://repo.javalite.io/ - - true - always - warn - - - - - UTF-8 - 1.4.13 + 2.0 development.test,development - 1.7.9 5.1.34 diff --git a/activejdbc/src/main/java/com/baeldung/model/Employee.java b/activejdbc/src/main/java/com/baeldung/model/Employee.java index b7fa8aaf1f..e6e9be2aac 100644 --- a/activejdbc/src/main/java/com/baeldung/model/Employee.java +++ b/activejdbc/src/main/java/com/baeldung/model/Employee.java @@ -16,4 +16,8 @@ public class Employee extends Model { set("created_by",createdBy); } + public String getLastName() { + return getString("last_name"); + } + } diff --git a/activejdbc/src/main/java/com/baeldung/model/Role.java b/activejdbc/src/main/java/com/baeldung/model/Role.java index 3f425dbe6b..bbd5a7d169 100644 --- a/activejdbc/src/main/java/com/baeldung/model/Role.java +++ b/activejdbc/src/main/java/com/baeldung/model/Role.java @@ -15,4 +15,8 @@ public class Role extends Model { set("role_name",role); set("created_by",createdBy); } + + public String getRoleName() { + return getString("role_name"); + } } diff --git a/activejdbc/src/main/resources/logback.xml b/activejdbc/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/activejdbc/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java b/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppManualTest.java similarity index 97% rename from activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java rename to activejdbc/src/test/java/com/baeldung/ActiveJDBCAppManualTest.java index 316dc34712..22eb87f930 100644 --- a/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java +++ b/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppManualTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import java.util.List; -public class ActiveJDBCAppTest extends DBSpec +public class ActiveJDBCAppManualTest extends DBSpec { @Test public void ifEmployeeCreated_thenIsValid() { diff --git a/akka-streams/pom.xml b/akka-streams/pom.xml index 3142e4e68a..a885753ce2 100644 --- a/akka-streams/pom.xml +++ b/akka-streams/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 akka-streams akka-streams diff --git a/akka-streams/src/main/resources/logback.xml b/akka-streams/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/akka-streams/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/algorithms/README.md b/algorithms/README.md index 50cdfbbd4f..9d347869bd 100644 --- a/algorithms/README.md +++ b/algorithms/README.md @@ -5,7 +5,6 @@ - [Ant Colony Optimization](http://www.baeldung.com/java-ant-colony-optimization) - [Validating Input With Finite Automata in Java](http://www.baeldung.com/java-finite-automata) - [Introduction to Jenetics Library](http://www.baeldung.com/jenetics) -- [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers) - [Example of Hill Climbing Algorithm](http://www.baeldung.com/java-hill-climbing-algorithm) - [Monte Carlo Tree Search for Tic-Tac-Toe Game](http://www.baeldung.com/java-monte-carlo-tree-search) - [String Search Algorithms for Large Texts](http://www.baeldung.com/java-full-text-search-algorithms) @@ -21,4 +20,14 @@ - [Create a Sudoku Solver in Java](http://www.baeldung.com/java-sudoku) - [Displaying Money Amounts in Words](http://www.baeldung.com/java-money-into-words) - [A Collaborative Filtering Recommendation System in Java](http://www.baeldung.com/java-collaborative-filtering-recommendations) -- [Find All Pairs of Numbers in an Array That Add Up to a Given Sum](http://www.baeldung.com/java-algorithm-number-pairs-sum) +- [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic) +- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity) +- [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element) +- [An Introduction to the Theory of Big-O Notation](http://www.baeldung.com/big-o-notation) +- [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap) +- [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points) +- [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines) +- [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters) +- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred) +- [Merge Sort in Java](https://www.baeldung.com/java-merge-sort) +- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage) diff --git a/algorithms/pom.xml b/algorithms/pom.xml index fdc8931f04..db4a1c2eff 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -1,5 +1,5 @@ + 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 algorithms @@ -17,6 +17,11 @@ commons-math3 ${commons-math3.version} + + commons-codec + commons-codec + ${commons-codec.version} + org.projectlombok lombok @@ -79,13 +84,13 @@ - 1.5.0 1.16.12 3.6.1 1.0.1 3.7.0 1.0.1 3.9.0 + 1.11 \ No newline at end of file diff --git a/algorithms/roundUpToHundred/.gitignore b/algorithms/roundUpToHundred/.gitignore new file mode 100644 index 0000000000..ae3c172604 --- /dev/null +++ b/algorithms/roundUpToHundred/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundred.java b/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundred.java new file mode 100644 index 0000000000..f5024c227d --- /dev/null +++ b/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundred.java @@ -0,0 +1,20 @@ +package com.java.src; + +import java.util.Scanner; + +public class RoundUpToHundred { + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + double input = scanner.nextDouble(); + scanner.close(); + + RoundUpToHundred.round(input); + } + + static long round(double input) { + long i = (long) Math.ceil(input); + return ((i + 99) / 100) * 100; + }; + +} diff --git a/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundredTest.java b/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundredTest.java new file mode 100644 index 0000000000..f35a9a249f --- /dev/null +++ b/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundredTest.java @@ -0,0 +1,14 @@ +package com.java.src; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class RoundUpToHundredTest { + @Test + public void givenInput_whenRound_thenRoundUpToTheNearestHundred() { + assertEquals("Rounded up to hundred", 100, RoundUpToHundred.round(99)); + assertEquals("Rounded up to three hundred ", 300, RoundUpToHundred.round(200.2)); + assertEquals("Returns same rounded value", 400, RoundUpToHundred.round(400)); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/RunAlgorithm.java b/algorithms/src/main/java/com/baeldung/algorithms/RunAlgorithm.java index c82883425d..ce04d26db3 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/RunAlgorithm.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/RunAlgorithm.java @@ -6,7 +6,6 @@ import com.baeldung.algorithms.ga.annealing.SimulatedAnnealing; import com.baeldung.algorithms.ga.ant_colony.AntColonyOptimization; import com.baeldung.algorithms.ga.binary.SimpleGeneticAlgorithm; import com.baeldung.algorithms.slope_one.SlopeOne; -import com.baeldung.algorithms.pairsaddupnumber.FindPairs; public class RunAlgorithm { @@ -39,12 +38,6 @@ public class RunAlgorithm { case 5: System.out.println("Please run the DijkstraAlgorithmTest."); break; - case 6: - final FindPairs findPairs = new FindPairs(); - final int[] input = {1, 4, 3, 2, 1, 4, 4, 3, 3}; - final int sum = 6; - findPairs.execute(input, sum); - break; default: System.out.println("Unknown option"); break; diff --git a/algorithms/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java b/algorithms/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java new file mode 100644 index 0000000000..d3e251d3fd --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/conversion/HexStringConverter.java @@ -0,0 +1,110 @@ +package com.baeldung.algorithms.conversion; + +import java.math.BigInteger; + +import javax.xml.bind.DatatypeConverter; + +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; + +import com.google.common.io.BaseEncoding; + +public class HexStringConverter { + + /** + * Create a byte Array from String of hexadecimal digits using Character conversion + * @param hexString - Hexadecimal digits as String + * @return Desired byte Array + */ + public byte[] decodeHexString(String hexString) { + if (hexString.length() % 2 == 1) { + throw new IllegalArgumentException("Invalid hexadecimal String supplied."); + } + byte[] bytes = new byte[hexString.length() / 2]; + + for (int i = 0; i < hexString.length(); i += 2) { + bytes[i / 2] = hexToByte(hexString.substring(i, i + 2)); + } + return bytes; + } + + /** + * Create a String of hexadecimal digits from a byte Array using Character conversion + * @param byteArray - The byte Array + * @return Desired String of hexadecimal digits in lower case + */ + public String encodeHexString(byte[] byteArray) { + StringBuffer hexStringBuffer = new StringBuffer(); + for (int i = 0; i < byteArray.length; i++) { + hexStringBuffer.append(byteToHex(byteArray[i])); + } + return hexStringBuffer.toString(); + } + + public String byteToHex(byte num) { + char[] hexDigits = new char[2]; + hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16); + hexDigits[1] = Character.forDigit((num & 0xF), 16); + return new String(hexDigits); + } + + public byte hexToByte(String hexString) { + int firstDigit = toDigit(hexString.charAt(0)); + int secondDigit = toDigit(hexString.charAt(1)); + return (byte) ((firstDigit << 4) + secondDigit); + } + + private int toDigit(char hexChar) { + int digit = Character.digit(hexChar, 16); + if(digit == -1) { + throw new IllegalArgumentException("Invalid Hexadecimal Character: "+ hexChar); + } + return digit; + } + + public String encodeUsingBigIntegerToString(byte[] bytes) { + BigInteger bigInteger = new BigInteger(1, bytes); + return bigInteger.toString(16); + } + + public String encodeUsingBigIntegerStringFormat(byte[] bytes) { + BigInteger bigInteger = new BigInteger(1, bytes); + return String.format("%0" + (bytes.length << 1) + "x", bigInteger); + } + + public byte[] decodeUsingBigInteger(String hexString) { + byte[] byteArray = new BigInteger(hexString, 16).toByteArray(); + if (byteArray[0] == 0) { + byte[] output = new byte[byteArray.length - 1]; + System.arraycopy(byteArray, 1, output, 0, output.length); + return output; + } + return byteArray; + } + + public String encodeUsingDataTypeConverter(byte[] bytes) { + return DatatypeConverter.printHexBinary(bytes); + } + + public byte[] decodeUsingDataTypeConverter(String hexString) { + return DatatypeConverter.parseHexBinary(hexString); + } + + public String encodeUsingApacheCommons(byte[] bytes) throws DecoderException { + return Hex.encodeHexString(bytes); + } + + public byte[] decodeUsingApacheCommons(String hexString) throws DecoderException { + return Hex.decodeHex(hexString); + } + + public String encodeUsingGuava(byte[] bytes) { + return BaseEncoding.base16() + .encode(bytes); + } + + public byte[] decodeUsingGuava(String hexString) { + return BaseEncoding.base16() + .decode(hexString.toUpperCase()); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java b/algorithms/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java new file mode 100644 index 0000000000..0c8eb86a38 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java @@ -0,0 +1,38 @@ +package com.baeldung.algorithms.distancebetweenpoints; + +import java.awt.geom.Point2D; + +public class DistanceBetweenPointsService { + + public double calculateDistanceBetweenPoints( + double x1, + double y1, + double x2, + double y2) { + + return Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1)); + } + + public double calculateDistanceBetweenPointsWithHypot( + double x1, + double y1, + double x2, + double y2) { + + double ac = Math.abs(y2 - y1); + double cb = Math.abs(x2 - x1); + + return Math.hypot(ac, cb); + } + + public double calculateDistanceBetweenPointsWithPoint2D( + double x1, + double y1, + double x2, + double y2) { + + return Point2D.distance(x1, y1, x2, y2); + + } + +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/insertionsort/InsertionSort.java b/algorithms/src/main/java/com/baeldung/algorithms/insertionsort/InsertionSort.java new file mode 100644 index 0000000000..02dd485cf1 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/insertionsort/InsertionSort.java @@ -0,0 +1,41 @@ +package com.baeldung.algorithms.insertionsort; + +public class InsertionSort { + + public static void insertionSortImperative(int[] input) { + for (int i = 1; i < input.length; i++) { + int key = input[i]; + int j = i - 1; + while (j >= 0 && input[j] > key) { + input[j + 1] = input[j]; + j = j - 1; + } + input[j + 1] = key; + } + } + + public static void insertionSortRecursive(int[] input) { + insertionSortRecursive(input, input.length); + } + + private static void insertionSortRecursive(int[] input, int i) { + // base case + if (i <= 1) { + return; + } + + // sort the first i - 1 elements of the array + insertionSortRecursive(input, i - 1); + + // then find the correct position of the element at position i + int key = input[i - 1]; + int j = i - 2; + // shifting the elements from their position by 1 + while (j >= 0 && input[j] > key) { + input[j + 1] = input[j]; + j = j - 1; + } + // inserting the key at the appropriate position + input[j + 1] = key; + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java b/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java index 822abdae02..7054979ada 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java @@ -98,7 +98,7 @@ public class FindKthLargest { private int randomPartition(Integer arr[], int left, int right) { int n = right - left + 1; - int pivot = (int) (Math.random()) % n; + int pivot = (int) (Math.random() * n); swap(arr, left + pivot, right); return partition(arr, left, right); } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java b/algorithms/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java new file mode 100644 index 0000000000..35d6c8b424 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java @@ -0,0 +1,21 @@ +package com.baeldung.algorithms.linesintersection; + +import java.awt.Point; +import java.util.Optional; + +public class LinesIntersectionService { + + public Optional calculateIntersectionPoint(double m1, double b1, double m2, double b2) { + + if (m1 == m2) { + return Optional.empty(); + } + + double x = (b2 - b1) / (m1 - m2); + double y = m1 * x + b1; + + Point point = new Point(); + point.setLocation(x, y); + return Optional.of(point); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java index f428df45d3..a4918f674d 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java @@ -10,7 +10,7 @@ public class MonteCarloTreeSearch { private static final int WIN_SCORE = 10; private int level; - private int oponent; + private int opponent; public MonteCarloTreeSearch() { this.level = 3; @@ -32,11 +32,11 @@ public class MonteCarloTreeSearch { long start = System.currentTimeMillis(); long end = start + 60 * getMillisForCurrentLevel(); - oponent = 3 - playerNo; + opponent = 3 - playerNo; Tree tree = new Tree(); Node rootNode = tree.getRoot(); rootNode.getState().setBoard(board); - rootNode.getState().setPlayerNo(oponent); + rootNode.getState().setPlayerNo(opponent); while (System.currentTimeMillis() < end) { // Phase 1 - Selection @@ -93,7 +93,7 @@ public class MonteCarloTreeSearch { State tempState = tempNode.getState(); int boardStatus = tempState.getBoard().checkStatus(); - if (boardStatus == oponent) { + if (boardStatus == opponent) { tempNode.getParent().getState().setWinScore(Integer.MIN_VALUE); return boardStatus; } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java index d855f775a8..5d4b265500 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java @@ -87,7 +87,7 @@ public class State { void randomPlay() { List availablePositions = this.board.getEmptyPositions(); int totalPossibilities = availablePositions.size(); - int selectRandom = (int) (Math.random() * ((totalPossibilities - 1) + 1)); + int selectRandom = (int) (Math.random() * totalPossibilities); this.board.performMove(this.playerNo, availablePositions.get(selectRandom)); } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java index 20f9e992b5..0ad6510e50 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java @@ -65,7 +65,7 @@ public class Node { public Node getRandomChildNode() { int noOfPossibleMoves = this.childArray.size(); - int selectRandom = (int) (Math.random() * ((noOfPossibleMoves - 1) + 1)); + int selectRandom = (int) (Math.random() * noOfPossibleMoves); return this.childArray.get(selectRandom); } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/mergesort/MergeSort.java b/algorithms/src/main/java/com/baeldung/algorithms/mergesort/MergeSort.java new file mode 100644 index 0000000000..0deb48b6a0 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/mergesort/MergeSort.java @@ -0,0 +1,50 @@ +package com.baeldung.algorithms.mergesort; + +public class MergeSort { + + public static void main(String[] args) { + int[] a = { 5, 1, 6, 2, 3, 4 }; + mergeSort(a, a.length); + for (int i = 0; i < a.length; i++) + System.out.println(a[i]); + } + + public static void mergeSort(int[] a, int n) { + if (n < 2) + return; + int mid = n / 2; + int[] l = new int[mid]; + int[] r = new int[n - mid]; + + for (int i = 0; i < mid; i++) { + l[i] = a[i]; + } + for (int i = mid; i < n; i++) { + r[i - mid] = a[i]; + } + mergeSort(l, mid); + mergeSort(r, n - mid); + + merge(a, l, r, mid, n - mid); + } + + public static void merge(int[] a, int[] l, int[] r, int left, int right) { + + int i = 0, j = 0, k = 0; + + while (i < left && j < right) { + + if (l[i] < r[j]) + a[k++] = l[i++]; + else + a[k++] = r[j++]; + + } + + while (i < left) + a[k++] = l[i++]; + + while (j < right) + a[k++] = r[j++]; + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java b/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java deleted file mode 100644 index 48d51a8848..0000000000 --- a/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.baeldung.algorithms.prime; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -public class PrimeGenerator { - public static List sieveOfEratosthenes(int n) { - final boolean prime[] = new boolean[n + 1]; - Arrays.fill(prime, true); - - for (int p = 2; p * p <= n; p++) { - if (prime[p]) { - for (int i = p * 2; i <= n; i += p) - prime[i] = false; - } - } - - final List primes = new LinkedList<>(); - for (int i = 2; i <= n; i++) { - if (prime[i]) - primes.add(i); - } - return primes; - } - - public static List primeNumbersBruteForce(int max) { - final List primeNumbers = new LinkedList(); - for (int i = 2; i <= max; i++) { - if (isPrimeBruteForce(i)) { - primeNumbers.add(i); - } - } - return primeNumbers; - } - - private static boolean isPrimeBruteForce(int x) { - for (int i = 2; i < x; i++) { - if (x % i == 0) { - return false; - } - } - return true; - } - - public static List primeNumbersTill(int max) { - return IntStream.rangeClosed(2, max) - .filter(x -> isPrime(x)) - .boxed() - .collect(Collectors.toList()); - } - - private static boolean isPrime(int x) { - return IntStream.rangeClosed(2, (int) (Math.sqrt(x))) - .allMatch(n -> x % n != 0); - } -} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java b/algorithms/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java new file mode 100644 index 0000000000..e113cc3242 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/quicksort/QuickSort.java @@ -0,0 +1,39 @@ +package com.baeldung.algorithms.quicksort; + +public class QuickSort { + + public static void quickSort(int arr[], int begin, int end) + { + if (begin < end) { + int partitionIndex = partition(arr, begin, end); + + // Recursively sort elements of the 2 sub-arrays + quickSort(arr, begin, partitionIndex-1); + quickSort(arr, partitionIndex+1, end); + } + } + + private static int partition(int arr[], int begin, int end) + { + int pivot = arr[end]; + int i = (begin-1); + + for (int j=begin; j other.topRight.getY()) { + return false; + } + // one rectangle is to the left of the other + if (this.topRight.getX() < other.bottomLeft.getX() || this.bottomLeft.getX() > other.topRight.getX()) { + return false; + } + return true; + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java b/algorithms/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java new file mode 100644 index 0000000000..2dd1fdcb75 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/string/EnglishAlphabetLetters.java @@ -0,0 +1,35 @@ +package com.baeldung.algorithms.string; + +public class EnglishAlphabetLetters { + + public static boolean checkStringForAllTheLetters(String input) { + boolean[] visited = new boolean[26]; + + int index = 0; + + for (int id = 0; id < input.length(); id++) { + if ('a' <= input.charAt(id) && input.charAt(id) <= 'z') { + index = input.charAt(id) - 'a'; + } else if ('A' <= input.charAt(id) && input.charAt(id) <= 'Z') { + index = input.charAt(id) - 'A'; + } + visited[index] = true; + } + + for (int id = 0; id < 26; id++) { + if (!visited[id]) { + return false; + } + } + return true; + } + + public static boolean checkStringForAllLetterUsingStream(String input) { + long c = input.toLowerCase().chars().filter(ch -> ch >= 'a' && ch <= 'z').distinct().count(); + return c == 26; + } + + public static void main(String[] args) { + checkStringForAllLetterUsingStream("intit"); + } +} \ No newline at end of file diff --git a/algorithms/src/main/resources/logback.xml b/algorithms/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/algorithms/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/algorithms/src/test/java/algorithms/AntColonyOptimizationLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java similarity index 94% rename from algorithms/src/test/java/algorithms/AntColonyOptimizationLongRunningUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java index b0218ae23e..2ac7adc3aa 100644 --- a/algorithms/src/test/java/algorithms/AntColonyOptimizationLongRunningUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/AntColonyOptimizationLongRunningUnitTest.java @@ -1,4 +1,4 @@ -package algorithms; +package com.baeldung.algorithms; import org.junit.Assert; import org.junit.Test; diff --git a/algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java similarity index 92% rename from algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java index fa8ecdee77..e819da4b36 100644 --- a/algorithms/src/test/java/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmLongRunningUnitTest.java @@ -1,4 +1,4 @@ -package algorithms; +package com.baeldung.algorithms; import org.junit.Assert; import org.junit.Test; diff --git a/algorithms/src/test/java/algorithms/DijkstraAlgorithmLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java similarity index 98% rename from algorithms/src/test/java/algorithms/DijkstraAlgorithmLongRunningUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java index 68386278fc..bbc4d4f398 100644 --- a/algorithms/src/test/java/algorithms/DijkstraAlgorithmLongRunningUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/DijkstraAlgorithmLongRunningUnitTest.java @@ -1,4 +1,4 @@ -package algorithms; +package com.baeldung.algorithms; import org.junit.Test; diff --git a/algorithms/src/test/java/algorithms/HillClimbingAlgorithmUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java similarity index 98% rename from algorithms/src/test/java/algorithms/HillClimbingAlgorithmUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java index e4746b521c..e817d195b3 100644 --- a/algorithms/src/test/java/algorithms/HillClimbingAlgorithmUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/HillClimbingAlgorithmUnitTest.java @@ -1,4 +1,4 @@ -package algorithms; +package com.baeldung.algorithms; import com.baeldung.algorithms.hillclimbing.HillClimbing; import com.baeldung.algorithms.hillclimbing.State; diff --git a/algorithms/src/test/java/algorithms/MiddleElementLookupUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java similarity index 99% rename from algorithms/src/test/java/algorithms/MiddleElementLookupUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java index 01f9ca2f76..2cda0ccb36 100644 --- a/algorithms/src/test/java/algorithms/MiddleElementLookupUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/MiddleElementLookupUnitTest.java @@ -1,4 +1,4 @@ -package algorithms; +package com.baeldung.algorithms; import com.baeldung.algorithms.middleelementlookup.MiddleElementLookup; import com.baeldung.algorithms.middleelementlookup.Node; diff --git a/algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java similarity index 98% rename from algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java index 99e962773f..fddccfcd9f 100644 --- a/algorithms/src/test/java/algorithms/RtFiniteStateMachineLongRunningUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/RtFiniteStateMachineLongRunningUnitTest.java @@ -1,4 +1,4 @@ -package algorithms; +package com.baeldung.algorithms; import com.baeldung.algorithms.automata.*; import org.junit.Test; diff --git a/algorithms/src/test/java/algorithms/SimulatedAnnealingLongRunningUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java similarity index 90% rename from algorithms/src/test/java/algorithms/SimulatedAnnealingLongRunningUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java index 6ee129ece9..2ce7d75e43 100644 --- a/algorithms/src/test/java/algorithms/SimulatedAnnealingLongRunningUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/SimulatedAnnealingLongRunningUnitTest.java @@ -1,4 +1,4 @@ -package algorithms; +package com.baeldung.algorithms; import org.junit.Assert; import org.junit.Test; diff --git a/algorithms/src/test/java/algorithms/StringSearchAlgorithmsUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java similarity index 94% rename from algorithms/src/test/java/algorithms/StringSearchAlgorithmsUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java index c98a8a53f3..dfe015aad2 100755 --- a/algorithms/src/test/java/algorithms/StringSearchAlgorithmsUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java @@ -1,4 +1,4 @@ -package algorithms; +package com.baeldung.algorithms; import org.junit.Assert; diff --git a/algorithms/src/test/java/algorithms/binarysearch/BinarySearchUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java similarity index 95% rename from algorithms/src/test/java/algorithms/binarysearch/BinarySearchUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java index 74db4236b9..826682d373 100644 --- a/algorithms/src/test/java/algorithms/binarysearch/BinarySearchUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java @@ -1,4 +1,4 @@ -package algorithms.binarysearch; +package com.baeldung.algorithms.binarysearch; import java.util.Arrays; import java.util.List; diff --git a/algorithms/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java new file mode 100644 index 0000000000..be61802705 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/conversion/ByteArrayConverterUnitTest.java @@ -0,0 +1,127 @@ +package com.baeldung.algorithms.conversion; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.apache.commons.codec.DecoderException; +import org.hamcrest.text.IsEqualIgnoringCase; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.algorithms.conversion.HexStringConverter; + +public class ByteArrayConverterUnitTest { + + private HexStringConverter hexStringConverter; + + @Before + public void setup() { + hexStringConverter = new HexStringConverter(); + } + + @Test + public void shouldEncodeByteArrayToHexStringUsingBigIntegerToString() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + if(hexString.charAt(0) == '0') { + hexString = hexString.substring(1); + } + String output = hexStringConverter.encodeUsingBigIntegerToString(bytes); + assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString)); + } + + @Test + public void shouldEncodeByteArrayToHexStringUsingBigIntegerStringFormat() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + String output = hexStringConverter.encodeUsingBigIntegerStringFormat(bytes); + assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString)); + } + + @Test + public void shouldDecodeHexStringToByteArrayUsingBigInteger() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + byte[] output = hexStringConverter.decodeUsingBigInteger(hexString); + assertArrayEquals(bytes, output); + } + + @Test + public void shouldEncodeByteArrayToHexStringUsingCharacterConversion() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + String output = hexStringConverter.encodeHexString(bytes); + assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString)); + } + + @Test + public void shouldDecodeHexStringToByteArrayUsingCharacterConversion() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + byte[] output = hexStringConverter.decodeHexString(hexString); + assertArrayEquals(bytes, output); + } + + @Test(expected=IllegalArgumentException.class) + public void shouldDecodeHexToByteWithInvalidHexCharacter() { + hexStringConverter.hexToByte("fg"); + } + + @Test + public void shouldEncodeByteArrayToHexStringDataTypeConverter() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + String output = hexStringConverter.encodeUsingDataTypeConverter(bytes); + assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString)); + } + + @Test + public void shouldDecodeHexStringToByteArrayUsingDataTypeConverter() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + byte[] output = hexStringConverter.decodeUsingDataTypeConverter(hexString); + assertArrayEquals(bytes, output); + } + + @Test + public void shouldEncodeByteArrayToHexStringUsingGuava() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + String output = hexStringConverter.encodeUsingGuava(bytes); + assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString)); + } + + @Test + public void shouldDecodeHexStringToByteArrayUsingGuava() { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + byte[] output = hexStringConverter.decodeUsingGuava(hexString); + assertArrayEquals(bytes, output); + } + + @Test + public void shouldEncodeByteArrayToHexStringUsingApacheCommons() throws DecoderException { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + String output = hexStringConverter.encodeUsingApacheCommons(bytes); + assertThat(output, IsEqualIgnoringCase.equalToIgnoringCase(hexString)); + } + + @Test + public void shouldDecodeHexStringToByteArrayUsingApacheCommons() throws DecoderException { + byte[] bytes = getSampleBytes(); + String hexString = getSampleHexString(); + byte[] output = hexStringConverter.decodeUsingApacheCommons(hexString); + assertArrayEquals(bytes, output); + } + + private String getSampleHexString() { + return "0af50c0e2d10"; + } + + private byte[] getSampleBytes() { + return new byte[] { 10, -11, 12, 14, 45, 16 }; + } + +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java new file mode 100644 index 0000000000..785afdbb2b --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.algorithms.distancebetweenpoints; + +import org.junit.Test; + +import com.baeldung.algorithms.distancebetweenpoints.DistanceBetweenPointsService; + +import static org.junit.Assert.assertEquals; + +public class DistanceBetweenPointsServiceUnitTest { + + private DistanceBetweenPointsService service = new DistanceBetweenPointsService(); + + @Test + public void givenTwoPoints_whenCalculateDistanceByFormula_thenCorrect() { + + double x1 = 3; + double y1 = 4; + double x2 = 7; + double y2 = 1; + + double distance = service.calculateDistanceBetweenPoints(x1, y1, x2, y2); + + assertEquals(distance, 5, 0.001); + + } + + @Test + public void givenTwoPoints_whenCalculateDistanceWithHypot_thenCorrect() { + + double x1 = 3; + double y1 = 4; + double x2 = 7; + double y2 = 1; + + double distance = service.calculateDistanceBetweenPointsWithHypot(x1, y1, x2, y2); + + assertEquals(distance, 5, 0.001); + + } + + @Test + public void givenTwoPoints_whenCalculateDistanceWithPoint2D_thenCorrect() { + + double x1 = 3; + double y1 = 4; + double x2 = 7; + double y2 = 1; + + double distance = service.calculateDistanceBetweenPointsWithPoint2D(x1, y1, x2, y2); + + assertEquals(distance, 5, 0.001); + + } +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java new file mode 100644 index 0000000000..b3d7e8c534 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/insertionsort/InsertionSortUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.algorithms.insertionsort; + +import com.baeldung.algorithms.insertionsort.InsertionSort; +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; + +public class InsertionSortUnitTest { + + @Test + public void givenUnsortedArray_whenInsertionSortImperative_thenSortedAsc() { + int[] input = {6, 2, 3, 4, 5, 1}; + InsertionSort.insertionSortImperative(input); + int[] expected = {1, 2, 3, 4, 5, 6}; + assertArrayEquals("the two arrays are not equal", expected, input); + } + + @Test + public void givenUnsortedArray_whenInsertionSortRecursive_thenSortedAsc() { + int[] input = {6, 4, 5, 2, 3, 1}; + InsertionSort.insertionSortRecursive(input); + int[] expected = {1, 2, 3, 4, 5, 6}; + assertArrayEquals("the two arrays are not equal", expected, input); + } +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java new file mode 100644 index 0000000000..22371107f3 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.algorithms.linesintersection; + +import java.awt.Point; +import java.util.Optional; + +import org.junit.Test; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; + +public class LinesIntersectionServiceUnitTest { + private LinesIntersectionService service = new LinesIntersectionService(); + + @Test + public void givenNotParallelLines_whenCalculatePoint_thenPresent() { + + double m1 = 0; + double b1 = 0; + double m2 = 1; + double b2 = -1; + + Optional point = service.calculateIntersectionPoint(m1, b1, m2, b2); + + assertTrue(point.isPresent()); + assertEquals(point.get().getX(), 1, 0.001); + assertEquals(point.get().getY(), 0, 0.001); + } + + @Test + public void givenParallelLines_whenCalculatePoint_thenEmpty() { + double m1 = 1; + double b1 = 0; + double m2 = 1; + double b2 = -1; + + Optional point = service.calculateIntersectionPoint(m1, b1, m2, b2); + + assertFalse(point.isPresent()); + } +} diff --git a/algorithms/src/test/java/algorithms/mcts/MCTSUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java similarity index 98% rename from algorithms/src/test/java/algorithms/mcts/MCTSUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java index edbf21390d..59afed65de 100644 --- a/algorithms/src/test/java/algorithms/mcts/MCTSUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java @@ -1,4 +1,4 @@ -package algorithms.mcts; +package com.baeldung.algorithms.mcts; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/algorithms/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java new file mode 100644 index 0000000000..5cd14b7bd0 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/mergesort/MergeSortUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.algorithms.mergesort; + +import org.junit.Assert; + +import org.junit.Test; + +public class MergeSortUnitTest { + + @Test + public void positiveTest() { + int[] actual = { 5, 1, 6, 2, 3, 4 }; + int[] expected = { 1, 2, 3, 4, 5, 6 }; + MergeSort.mergeSort(actual, actual.length); + Assert.assertArrayEquals(expected, actual); + } + +} diff --git a/algorithms/src/test/java/algorithms/minimax/MinimaxUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java similarity index 95% rename from algorithms/src/test/java/algorithms/minimax/MinimaxUnitTest.java rename to algorithms/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java index c07975bca0..59f0fcf053 100644 --- a/algorithms/src/test/java/algorithms/minimax/MinimaxUnitTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/minimax/MinimaxUnitTest.java @@ -1,4 +1,4 @@ -package algorithms.minimax; +package com.baeldung.algorithms.minimax; import org.junit.Before; import org.junit.Test; diff --git a/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorUnitTest.java deleted file mode 100644 index ffa1404eac..0000000000 --- a/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorUnitTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.algorithms.prime; - -import static com.baeldung.algorithms.prime.PrimeGenerator.*; - -import java.util.Arrays; -import java.util.List; -import org.junit.Test; -import static org.junit.Assert.*; - -public class PrimeGeneratorUnitTest { - @Test - public void whenBruteForced_returnsSuccessfully() { - final List primeNumbers = primeNumbersBruteForce(20); - assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); - } - - @Test - public void whenOptimized_returnsSuccessfully() { - final List primeNumbers = primeNumbersTill(20); - assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); - } - - @Test - public void whenSieveOfEratosthenes_returnsSuccessfully() { - final List primeNumbers = sieveOfEratosthenes(20); - assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); - } -} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java new file mode 100644 index 0000000000..c9af5b4bf8 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/quicksort/QuickSortUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.algorithms.quicksort; + +import com.baeldung.algorithms.quicksort.QuickSort; +import org.junit.Assert; +import org.junit.Test; + +public class QuickSortUnitTest { + + @Test + public void givenIntegerArray_whenSortedWithQuickSort_thenGetSortedArray() { + int[] actual = { 9, 5, 1, 0, 6, 2, 3, 4, 7, 8 }; + int[] expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + QuickSort.quickSort(actual, 0, actual.length-1); + Assert.assertArrayEquals(expected, actual); + } + +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java new file mode 100644 index 0000000000..cd8c7c1241 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/quicksort/ThreeWayQuickSortUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.algorithms.quicksort; + +import org.junit.Assert; +import org.junit.Test; + +public class ThreeWayQuickSortUnitTest { + + @Test + public void givenIntegerArray_whenSortedWithThreeWayQuickSort_thenGetSortedArray() { + int[] actual = { 3, 5, 5, 5, 3, 7, 7, 3, 5, 5, 7, 3, 3 }; + int[] expected = { 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 7, 7, 7 }; + ThreeWayQuickSort.threeWayQuickSort(actual, 0, actual.length-1); + Assert.assertArrayEquals(expected, actual); + } +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java new file mode 100644 index 0000000000..6707b34477 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.algorithms.rectanglesoverlap; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import org.junit.Test; + +import com.baeldung.algorithms.rectanglesoverlap.Point; +import com.baeldung.algorithms.rectanglesoverlap.Rectangle; + +public class RectangleUnitTest { + + @Test + public void givenTwoOverlappingRectangles_whenisOverlappingCalled_shouldReturnTrue() { + Rectangle rectangle1 = new Rectangle(new Point(2, 1), new Point(4, 3)); + Rectangle rectangle2 = new Rectangle(new Point(1, 1), new Point(6, 4)); + assertTrue(rectangle1.isOverlapping(rectangle2)); + + rectangle1 = new Rectangle(new Point(-5, -2), new Point(2, 3)); + rectangle2 = new Rectangle(new Point(-2, -1), new Point(5, 2)); + assertTrue(rectangle1.isOverlapping(rectangle2)); + + rectangle1 = new Rectangle(new Point(-5, 1), new Point(2, 4)); + rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, 5)); + assertTrue(rectangle1.isOverlapping(rectangle2)); + } + + @Test + public void givenTwoNonOverlappingRectangles_whenisOverlappingCalled_shouldReturnFalse() { + Rectangle rectangle1 = new Rectangle(new Point(-5, 1), new Point(-3, 4)); + Rectangle rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, 5)); + assertFalse(rectangle1.isOverlapping(rectangle2)); + + rectangle1 = new Rectangle(new Point(-5, 1), new Point(3, 4)); + rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, -1)); + assertFalse(rectangle1.isOverlapping(rectangle2)); + + rectangle1 = new Rectangle(new Point(-2, 1), new Point(0, 3)); + rectangle2 = new Rectangle(new Point(3, 1), new Point(5, 4)); + assertFalse(rectangle1.isOverlapping(rectangle2)); + } + +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java new file mode 100644 index 0000000000..54863cddc8 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/string/EnglishAlphabetLettersUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.algorithms.string; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class EnglishAlphabetLettersUnitTest { + + @Test + void givenString_whenContainsAllCharacter_thenTrue() { + String input = "Farmer jack realized that big yellow quilts were expensive"; + Assertions.assertTrue(EnglishAlphabetLetters.checkStringForAllTheLetters(input)); + } + + @Test + void givenString_whenContainsAllCharacter_thenUsingStreamExpectTrue() { + String input = "Farmer jack realized that big yellow quilts were expensive"; + Assertions.assertTrue(EnglishAlphabetLetters.checkStringForAllLetterUsingStream(input)); + } + +} diff --git a/animal-sniffer-mvn-plugin/pom.xml b/animal-sniffer-mvn-plugin/pom.xml index 9ccc7354af..cdfb1fb2a3 100644 --- a/animal-sniffer-mvn-plugin/pom.xml +++ b/animal-sniffer-mvn-plugin/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung animal-sniffer-mvn-plugin @@ -14,15 +14,6 @@ 1.0.0-SNAPSHOT - - - junit - junit - ${junit.version} - test - - - diff --git a/animal-sniffer-mvn-plugin/src/main/resources/logback.xml b/animal-sniffer-mvn-plugin/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/animal-sniffer-mvn-plugin/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java b/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java similarity index 81% rename from animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java rename to animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java index 8ecb1bc629..dcfd22ff87 100644 --- a/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java +++ b/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppUnitTest.java @@ -7,7 +7,7 @@ import junit.framework.TestSuite; /** * Unit test for simple App. */ -public class AppTest +public class AppUnitTest extends TestCase { /** @@ -15,7 +15,7 @@ public class AppTest * * @param testName name of the test case */ - public AppTest( String testName ) + public AppUnitTest( String testName ) { super( testName ); } @@ -25,7 +25,7 @@ public class AppTest */ public static Test suite() { - return new TestSuite( AppTest.class ); + return new TestSuite( AppUnitTest.class ); } /** diff --git a/annotations/annotation-processing/pom.xml b/annotations/annotation-processing/pom.xml index 39a644905d..8e53334521 100644 --- a/annotations/annotation-processing/pom.xml +++ b/annotations/annotation-processing/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 annotation-processing diff --git a/annotations/annotation-processing/src/main/resources/logback.xml b/annotations/annotation-processing/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/annotations/annotation-processing/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/annotations/annotation-user/pom.xml b/annotations/annotation-user/pom.xml index 5a00951a18..07ea9a5b5a 100644 --- a/annotations/annotation-user/pom.xml +++ b/annotations/annotation-user/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 annotation-user diff --git a/annotations/annotation-user/src/main/resources/logback.xml b/annotations/annotation-user/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/annotations/annotation-user/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/annotations/pom.xml b/annotations/pom.xml index 52508e5bfc..2c73d3d91b 100644 --- a/annotations/pom.xml +++ b/annotations/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 annotations pom diff --git a/antlr/README.md b/antlr/README.md new file mode 100644 index 0000000000..419d9ddfbb --- /dev/null +++ b/antlr/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Java with ANTLR](http://www.baeldung.com/java-antlr) diff --git a/antlr/pom.xml b/antlr/pom.xml index 15fe79afca..ac66891598 100644 --- a/antlr/pom.xml +++ b/antlr/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 antlr antlr @@ -45,22 +45,14 @@ - - org.antlr - antlr4-runtime - ${antlr.version} - - junit - junit - ${junit.version} - test + org.antlr + antlr4-runtime + ${antlr.version} - 1.8 4.7.1 - 4.12 3.0.0 \ No newline at end of file diff --git a/antlr/src/main/resources/logback.xml b/antlr/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/antlr/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-avro/README.md b/apache-avro/README.md new file mode 100644 index 0000000000..32d84ecc76 --- /dev/null +++ b/apache-avro/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Guide to Apache Avro](http://www.baeldung.com/java-apache-avro) diff --git a/apache-avro/pom.xml b/apache-avro/pom.xml new file mode 100644 index 0000000000..ddf5844271 --- /dev/null +++ b/apache-avro/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + com.baeldung + apache-avro + 0.0.1-SNAPSHOT + Apache Avro + + + UTF-8 + 3.5 + 1.8.2 + 1.8 + 1.7.25 + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + junit + junit + 4.10 + test + + + org.slf4j + slf4j-simple + ${slf4j.version} + compile + + + org.apache.avro + avro + ${avro.version} + + + org.apache.avro + avro-compiler + ${avro.version} + + + + org.apache.avro + avro-maven-plugin + ${avro.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${compiler-plugin.version} + + ${java.version} + ${java.version} + + + + org.apache.avro + avro-maven-plugin + ${avro.version} + + + schemas + generate-sources + + schema + protocol + idl-protocol + + + ${project.basedir}/src/main/resources/ + ${project.basedir}/src/main/java/ + + + + + + + diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java b/apache-avro/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java new file mode 100644 index 0000000000..718b62a752 --- /dev/null +++ b/apache-avro/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java @@ -0,0 +1,14 @@ +package com.baeldung.avro.util; + +import org.apache.avro.Schema; +import org.apache.avro.compiler.specific.SpecificCompiler; + +import java.io.File; +import java.io.IOException; + +public class AvroClassGenerator { + public void generateAvroClasses() throws IOException { + SpecificCompiler compiler = new SpecificCompiler(new Schema.Parser().parse(new File("src/main/resources/avroHttpRequest-schema.avsc"))); + compiler.compileToDestination(new File("src/main/resources"), new File("src/main/java")); + } +} diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java b/apache-avro/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java new file mode 100644 index 0000000000..4a1314cd00 --- /dev/null +++ b/apache-avro/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java @@ -0,0 +1,24 @@ +package com.baeldung.avro.util; + + +import org.apache.avro.Schema; +import org.apache.avro.SchemaBuilder; + +public class AvroSchemaBuilder { + + public Schema createAvroHttpRequestSchema(){ + + Schema clientIdentifier = SchemaBuilder.record("ClientIdentifier").namespace("com.baeldung.avro.model") + .fields().requiredString("hostName").requiredString("ipAddress").endRecord(); + + Schema avroHttpRequest = SchemaBuilder.record("AvroHttpRequest").namespace("com.baeldung.avro.model").fields() + .requiredLong("requestTime") + .name("clientIdentifier").type(clientIdentifier).noDefault() + .name("employeeNames").type().array().items().stringType().arrayDefault(null) + .name("active").type().enumeration("Active").symbols("YES", "NO").noDefault() + .endRecord(); + return avroHttpRequest; + } +} + + diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/Active.java b/apache-avro/src/main/java/com/baeldung/avro/util/model/Active.java new file mode 100644 index 0000000000..3ae0508394 --- /dev/null +++ b/apache-avro/src/main/java/com/baeldung/avro/util/model/Active.java @@ -0,0 +1,13 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.baeldung.avro.util.model; +@SuppressWarnings("all") +@org.apache.avro.specific.AvroGenerated +public enum Active { + YES, NO ; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"enum\",\"name\":\"Active\",\"namespace\":\"com.baeldung.avro.model\",\"symbols\":[\"YES\",\"NO\"]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } +} diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java b/apache-avro/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java new file mode 100644 index 0000000000..56b36050a5 --- /dev/null +++ b/apache-avro/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java @@ -0,0 +1,491 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.baeldung.avro.util.model; + +import org.apache.avro.specific.SpecificData; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +@SuppressWarnings("all") +@org.apache.avro.specific.AvroGenerated +public class AvroHttpRequest extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = -8649010116827875312L; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"AvroHttpRequest\",\"namespace\":\"com.baeldung.avro.model\",\"fields\":[{\"name\":\"requestTime\",\"type\":\"long\"},{\"name\":\"clientIdentifier\",\"type\":{\"type\":\"record\",\"name\":\"ClientIdentifier\",\"fields\":[{\"name\":\"hostName\",\"type\":\"string\"},{\"name\":\"ipAddress\",\"type\":\"string\"}]}},{\"name\":\"employeeNames\",\"type\":{\"type\":\"array\",\"items\":\"string\"},\"default\":null},{\"name\":\"active\",\"type\":{\"type\":\"enum\",\"name\":\"Active\",\"symbols\":[\"YES\",\"NO\"]}}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static SpecificData MODEL$ = new SpecificData(); + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageDecoder instance used by this class. + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** Serializes this AvroHttpRequest to a ByteBuffer. */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** Deserializes a AvroHttpRequest from a ByteBuffer. */ + public static AvroHttpRequest fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + @Deprecated public long requestTime; + @Deprecated public ClientIdentifier clientIdentifier; + @Deprecated public java.util.List employeeNames; + @Deprecated public Active active; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public AvroHttpRequest() {} + + /** + * All-args constructor. + * @param requestTime The new value for requestTime + * @param clientIdentifier The new value for clientIdentifier + * @param employeeNames The new value for employeeNames + * @param active The new value for active + */ + public AvroHttpRequest(java.lang.Long requestTime, ClientIdentifier clientIdentifier, java.util.List employeeNames, Active active) { + this.requestTime = requestTime; + this.clientIdentifier = clientIdentifier; + this.employeeNames = employeeNames; + this.active = active; + } + + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return requestTime; + case 1: return clientIdentifier; + case 2: return employeeNames; + case 3: return active; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: requestTime = (java.lang.Long)value$; break; + case 1: clientIdentifier = (ClientIdentifier)value$; break; + case 2: employeeNames = (java.util.List)value$; break; + case 3: active = (Active)value$; break; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + /** + * Gets the value of the 'requestTime' field. + * @return The value of the 'requestTime' field. + */ + public java.lang.Long getRequestTime() { + return requestTime; + } + + /** + * Sets the value of the 'requestTime' field. + * @param value the value to set. + */ + public void setRequestTime(java.lang.Long value) { + this.requestTime = value; + } + + /** + * Gets the value of the 'clientIdentifier' field. + * @return The value of the 'clientIdentifier' field. + */ + public ClientIdentifier getClientIdentifier() { + return clientIdentifier; + } + + /** + * Sets the value of the 'clientIdentifier' field. + * @param value the value to set. + */ + public void setClientIdentifier(ClientIdentifier value) { + this.clientIdentifier = value; + } + + /** + * Gets the value of the 'employeeNames' field. + * @return The value of the 'employeeNames' field. + */ + public java.util.List getEmployeeNames() { + return employeeNames; + } + + /** + * Sets the value of the 'employeeNames' field. + * @param value the value to set. + */ + public void setEmployeeNames(java.util.List value) { + this.employeeNames = value; + } + + /** + * Gets the value of the 'active' field. + * @return The value of the 'active' field. + */ + public Active getActive() { + return active; + } + + /** + * Sets the value of the 'active' field. + * @param value the value to set. + */ + public void setActive(Active value) { + this.active = value; + } + + /** + * Creates a new AvroHttpRequest RecordBuilder. + * @return A new AvroHttpRequest RecordBuilder + */ + public static AvroHttpRequest.Builder newBuilder() { + return new AvroHttpRequest.Builder(); + } + + /** + * Creates a new AvroHttpRequest RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new AvroHttpRequest RecordBuilder + */ + public static AvroHttpRequest.Builder newBuilder(AvroHttpRequest.Builder other) { + return new AvroHttpRequest.Builder(other); + } + + /** + * Creates a new AvroHttpRequest RecordBuilder by copying an existing AvroHttpRequest instance. + * @param other The existing instance to copy. + * @return A new AvroHttpRequest RecordBuilder + */ + public static AvroHttpRequest.Builder newBuilder(AvroHttpRequest other) { + return new AvroHttpRequest.Builder(other); + } + + /** + * RecordBuilder for AvroHttpRequest instances. + */ + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private long requestTime; + private ClientIdentifier clientIdentifier; + private ClientIdentifier.Builder clientIdentifierBuilder; + private java.util.List employeeNames; + private Active active; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(AvroHttpRequest.Builder other) { + super(other); + if (isValidValue(fields()[0], other.requestTime)) { + this.requestTime = data().deepCopy(fields()[0].schema(), other.requestTime); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.clientIdentifier)) { + this.clientIdentifier = data().deepCopy(fields()[1].schema(), other.clientIdentifier); + fieldSetFlags()[1] = true; + } + if (other.hasClientIdentifierBuilder()) { + this.clientIdentifierBuilder = ClientIdentifier.newBuilder(other.getClientIdentifierBuilder()); + } + if (isValidValue(fields()[2], other.employeeNames)) { + this.employeeNames = data().deepCopy(fields()[2].schema(), other.employeeNames); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.active)) { + this.active = data().deepCopy(fields()[3].schema(), other.active); + fieldSetFlags()[3] = true; + } + } + + /** + * Creates a Builder by copying an existing AvroHttpRequest instance + * @param other The existing instance to copy. + */ + private Builder(AvroHttpRequest other) { + super(SCHEMA$); + if (isValidValue(fields()[0], other.requestTime)) { + this.requestTime = data().deepCopy(fields()[0].schema(), other.requestTime); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.clientIdentifier)) { + this.clientIdentifier = data().deepCopy(fields()[1].schema(), other.clientIdentifier); + fieldSetFlags()[1] = true; + } + this.clientIdentifierBuilder = null; + if (isValidValue(fields()[2], other.employeeNames)) { + this.employeeNames = data().deepCopy(fields()[2].schema(), other.employeeNames); + fieldSetFlags()[2] = true; + } + if (isValidValue(fields()[3], other.active)) { + this.active = data().deepCopy(fields()[3].schema(), other.active); + fieldSetFlags()[3] = true; + } + } + + /** + * Gets the value of the 'requestTime' field. + * @return The value. + */ + public java.lang.Long getRequestTime() { + return requestTime; + } + + /** + * Sets the value of the 'requestTime' field. + * @param value The value of 'requestTime'. + * @return This builder. + */ + public AvroHttpRequest.Builder setRequestTime(long value) { + validate(fields()[0], value); + this.requestTime = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'requestTime' field has been set. + * @return True if the 'requestTime' field has been set, false otherwise. + */ + public boolean hasRequestTime() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'requestTime' field. + * @return This builder. + */ + public AvroHttpRequest.Builder clearRequestTime() { + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'clientIdentifier' field. + * @return The value. + */ + public ClientIdentifier getClientIdentifier() { + return clientIdentifier; + } + + /** + * Sets the value of the 'clientIdentifier' field. + * @param value The value of 'clientIdentifier'. + * @return This builder. + */ + public AvroHttpRequest.Builder setClientIdentifier(ClientIdentifier value) { + validate(fields()[1], value); + this.clientIdentifierBuilder = null; + this.clientIdentifier = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'clientIdentifier' field has been set. + * @return True if the 'clientIdentifier' field has been set, false otherwise. + */ + public boolean hasClientIdentifier() { + return fieldSetFlags()[1]; + } + + /** + * Gets the Builder instance for the 'clientIdentifier' field and creates one if it doesn't exist yet. + * @return This builder. + */ + public ClientIdentifier.Builder getClientIdentifierBuilder() { + if (clientIdentifierBuilder == null) { + if (hasClientIdentifier()) { + setClientIdentifierBuilder(ClientIdentifier.newBuilder(clientIdentifier)); + } else { + setClientIdentifierBuilder(ClientIdentifier.newBuilder()); + } + } + return clientIdentifierBuilder; + } + + /** + * Sets the Builder instance for the 'clientIdentifier' field + * @param value The builder instance that must be set. + * @return This builder. + */ + public AvroHttpRequest.Builder setClientIdentifierBuilder(ClientIdentifier.Builder value) { + clearClientIdentifier(); + clientIdentifierBuilder = value; + return this; + } + + /** + * Checks whether the 'clientIdentifier' field has an active Builder instance + * @return True if the 'clientIdentifier' field has an active Builder instance + */ + public boolean hasClientIdentifierBuilder() { + return clientIdentifierBuilder != null; + } + + /** + * Clears the value of the 'clientIdentifier' field. + * @return This builder. + */ + public AvroHttpRequest.Builder clearClientIdentifier() { + clientIdentifier = null; + clientIdentifierBuilder = null; + fieldSetFlags()[1] = false; + return this; + } + + /** + * Gets the value of the 'employeeNames' field. + * @return The value. + */ + public java.util.List getEmployeeNames() { + return employeeNames; + } + + /** + * Sets the value of the 'employeeNames' field. + * @param value The value of 'employeeNames'. + * @return This builder. + */ + public AvroHttpRequest.Builder setEmployeeNames(java.util.List value) { + validate(fields()[2], value); + this.employeeNames = value; + fieldSetFlags()[2] = true; + return this; + } + + /** + * Checks whether the 'employeeNames' field has been set. + * @return True if the 'employeeNames' field has been set, false otherwise. + */ + public boolean hasEmployeeNames() { + return fieldSetFlags()[2]; + } + + + /** + * Clears the value of the 'employeeNames' field. + * @return This builder. + */ + public AvroHttpRequest.Builder clearEmployeeNames() { + employeeNames = null; + fieldSetFlags()[2] = false; + return this; + } + + /** + * Gets the value of the 'active' field. + * @return The value. + */ + public Active getActive() { + return active; + } + + /** + * Sets the value of the 'active' field. + * @param value The value of 'active'. + * @return This builder. + */ + public AvroHttpRequest.Builder setActive(Active value) { + validate(fields()[3], value); + this.active = value; + fieldSetFlags()[3] = true; + return this; + } + + /** + * Checks whether the 'active' field has been set. + * @return True if the 'active' field has been set, false otherwise. + */ + public boolean hasActive() { + return fieldSetFlags()[3]; + } + + + /** + * Clears the value of the 'active' field. + * @return This builder. + */ + public AvroHttpRequest.Builder clearActive() { + active = null; + fieldSetFlags()[3] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public AvroHttpRequest build() { + try { + AvroHttpRequest record = new AvroHttpRequest(); + record.requestTime = fieldSetFlags()[0] ? this.requestTime : (java.lang.Long) defaultValue(fields()[0]); + if (clientIdentifierBuilder != null) { + record.clientIdentifier = this.clientIdentifierBuilder.build(); + } else { + record.clientIdentifier = fieldSetFlags()[1] ? this.clientIdentifier : (ClientIdentifier) defaultValue(fields()[1]); + } + record.employeeNames = fieldSetFlags()[2] ? this.employeeNames : (java.util.List) defaultValue(fields()[2]); + record.active = fieldSetFlags()[3] ? this.active : (Active) defaultValue(fields()[3]); + return record; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + +} diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java b/apache-avro/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java new file mode 100644 index 0000000000..503dde40df --- /dev/null +++ b/apache-avro/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java @@ -0,0 +1,308 @@ +/** + * Autogenerated by Avro + * + * DO NOT EDIT DIRECTLY + */ +package com.baeldung.avro.util.model; + +import org.apache.avro.specific.SpecificData; +import org.apache.avro.message.BinaryMessageEncoder; +import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; + +@SuppressWarnings("all") +@org.apache.avro.specific.AvroGenerated +public class ClientIdentifier extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord { + private static final long serialVersionUID = 8754570983127295424L; + public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"ClientIdentifier\",\"namespace\":\"com.baeldung.avro.model\",\"fields\":[{\"name\":\"hostName\",\"type\":\"string\"},{\"name\":\"ipAddress\",\"type\":\"string\"}]}"); + public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; } + + private static SpecificData MODEL$ = new SpecificData(); + + private static final BinaryMessageEncoder ENCODER = + new BinaryMessageEncoder(MODEL$, SCHEMA$); + + private static final BinaryMessageDecoder DECODER = + new BinaryMessageDecoder(MODEL$, SCHEMA$); + + /** + * Return the BinaryMessageDecoder instance used by this class. + */ + public static BinaryMessageDecoder getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + */ + public static BinaryMessageDecoder createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver); + } + + /** Serializes this ClientIdentifier to a ByteBuffer. */ + public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { + return ENCODER.encode(this); + } + + /** Deserializes a ClientIdentifier from a ByteBuffer. */ + public static ClientIdentifier fromByteBuffer( + java.nio.ByteBuffer b) throws java.io.IOException { + return DECODER.decode(b); + } + + @Deprecated public java.lang.CharSequence hostName; + @Deprecated public java.lang.CharSequence ipAddress; + + /** + * Default constructor. Note that this does not initialize fields + * to their default values from the schema. If that is desired then + * one should use newBuilder(). + */ + public ClientIdentifier() {} + + /** + * All-args constructor. + * @param hostName The new value for hostName + * @param ipAddress The new value for ipAddress + */ + public ClientIdentifier(java.lang.CharSequence hostName, java.lang.CharSequence ipAddress) { + this.hostName = hostName; + this.ipAddress = ipAddress; + } + + public org.apache.avro.Schema getSchema() { return SCHEMA$; } + // Used by DatumWriter. Applications should not call. + public java.lang.Object get(int field$) { + switch (field$) { + case 0: return hostName; + case 1: return ipAddress; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + // Used by DatumReader. Applications should not call. + @SuppressWarnings(value="unchecked") + public void put(int field$, java.lang.Object value$) { + switch (field$) { + case 0: hostName = (java.lang.CharSequence)value$; break; + case 1: ipAddress = (java.lang.CharSequence)value$; break; + default: throw new org.apache.avro.AvroRuntimeException("Bad index"); + } + } + + /** + * Gets the value of the 'hostName' field. + * @return The value of the 'hostName' field. + */ + public java.lang.CharSequence getHostName() { + return hostName; + } + + /** + * Sets the value of the 'hostName' field. + * @param value the value to set. + */ + public void setHostName(java.lang.CharSequence value) { + this.hostName = value; + } + + /** + * Gets the value of the 'ipAddress' field. + * @return The value of the 'ipAddress' field. + */ + public java.lang.CharSequence getIpAddress() { + return ipAddress; + } + + /** + * Sets the value of the 'ipAddress' field. + * @param value the value to set. + */ + public void setIpAddress(java.lang.CharSequence value) { + this.ipAddress = value; + } + + /** + * Creates a new ClientIdentifier RecordBuilder. + * @return A new ClientIdentifier RecordBuilder + */ + public static ClientIdentifier.Builder newBuilder() { + return new ClientIdentifier.Builder(); + } + + /** + * Creates a new ClientIdentifier RecordBuilder by copying an existing Builder. + * @param other The existing builder to copy. + * @return A new ClientIdentifier RecordBuilder + */ + public static ClientIdentifier.Builder newBuilder(ClientIdentifier.Builder other) { + return new ClientIdentifier.Builder(other); + } + + /** + * Creates a new ClientIdentifier RecordBuilder by copying an existing ClientIdentifier instance. + * @param other The existing instance to copy. + * @return A new ClientIdentifier RecordBuilder + */ + public static ClientIdentifier.Builder newBuilder(ClientIdentifier other) { + return new ClientIdentifier.Builder(other); + } + + /** + * RecordBuilder for ClientIdentifier instances. + */ + public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase + implements org.apache.avro.data.RecordBuilder { + + private java.lang.CharSequence hostName; + private java.lang.CharSequence ipAddress; + + /** Creates a new Builder */ + private Builder() { + super(SCHEMA$); + } + + /** + * Creates a Builder by copying an existing Builder. + * @param other The existing Builder to copy. + */ + private Builder(ClientIdentifier.Builder other) { + super(other); + if (isValidValue(fields()[0], other.hostName)) { + this.hostName = data().deepCopy(fields()[0].schema(), other.hostName); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.ipAddress)) { + this.ipAddress = data().deepCopy(fields()[1].schema(), other.ipAddress); + fieldSetFlags()[1] = true; + } + } + + /** + * Creates a Builder by copying an existing ClientIdentifier instance + * @param other The existing instance to copy. + */ + private Builder(ClientIdentifier other) { + super(SCHEMA$); + if (isValidValue(fields()[0], other.hostName)) { + this.hostName = data().deepCopy(fields()[0].schema(), other.hostName); + fieldSetFlags()[0] = true; + } + if (isValidValue(fields()[1], other.ipAddress)) { + this.ipAddress = data().deepCopy(fields()[1].schema(), other.ipAddress); + fieldSetFlags()[1] = true; + } + } + + /** + * Gets the value of the 'hostName' field. + * @return The value. + */ + public java.lang.CharSequence getHostName() { + return hostName; + } + + /** + * Sets the value of the 'hostName' field. + * @param value The value of 'hostName'. + * @return This builder. + */ + public ClientIdentifier.Builder setHostName(java.lang.CharSequence value) { + validate(fields()[0], value); + this.hostName = value; + fieldSetFlags()[0] = true; + return this; + } + + /** + * Checks whether the 'hostName' field has been set. + * @return True if the 'hostName' field has been set, false otherwise. + */ + public boolean hasHostName() { + return fieldSetFlags()[0]; + } + + + /** + * Clears the value of the 'hostName' field. + * @return This builder. + */ + public ClientIdentifier.Builder clearHostName() { + hostName = null; + fieldSetFlags()[0] = false; + return this; + } + + /** + * Gets the value of the 'ipAddress' field. + * @return The value. + */ + public java.lang.CharSequence getIpAddress() { + return ipAddress; + } + + /** + * Sets the value of the 'ipAddress' field. + * @param value The value of 'ipAddress'. + * @return This builder. + */ + public ClientIdentifier.Builder setIpAddress(java.lang.CharSequence value) { + validate(fields()[1], value); + this.ipAddress = value; + fieldSetFlags()[1] = true; + return this; + } + + /** + * Checks whether the 'ipAddress' field has been set. + * @return True if the 'ipAddress' field has been set, false otherwise. + */ + public boolean hasIpAddress() { + return fieldSetFlags()[1]; + } + + + /** + * Clears the value of the 'ipAddress' field. + * @return This builder. + */ + public ClientIdentifier.Builder clearIpAddress() { + ipAddress = null; + fieldSetFlags()[1] = false; + return this; + } + + @Override + @SuppressWarnings("unchecked") + public ClientIdentifier build() { + try { + ClientIdentifier record = new ClientIdentifier(); + record.hostName = fieldSetFlags()[0] ? this.hostName : (java.lang.CharSequence) defaultValue(fields()[0]); + record.ipAddress = fieldSetFlags()[1] ? this.ipAddress : (java.lang.CharSequence) defaultValue(fields()[1]); + return record; + } catch (java.lang.Exception e) { + throw new org.apache.avro.AvroRuntimeException(e); + } + } + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumWriter + WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$); + + @Override public void writeExternal(java.io.ObjectOutput out) + throws java.io.IOException { + WRITER$.write(this, SpecificData.getEncoder(out)); + } + + @SuppressWarnings("unchecked") + private static final org.apache.avro.io.DatumReader + READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$); + + @Override public void readExternal(java.io.ObjectInput in) + throws java.io.IOException { + READER$.read(this, SpecificData.getDecoder(in)); + } + +} diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java b/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java new file mode 100644 index 0000000000..7d30c3d1ee --- /dev/null +++ b/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java @@ -0,0 +1,41 @@ +package com.baeldung.avro.util.serealization; + +import com.baeldung.avro.util.model.AvroHttpRequest; +import org.apache.avro.io.DatumReader; +import org.apache.avro.io.Decoder; +import org.apache.avro.io.DecoderFactory; +import org.apache.avro.specific.SpecificDatumReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class AvroDeSerealizer { + + private static Logger logger = LoggerFactory.getLogger(AvroDeSerealizer.class); + + public AvroHttpRequest deSerealizeAvroHttpRequestJSON(byte[] data) { + DatumReader reader = new SpecificDatumReader<>(AvroHttpRequest.class); + Decoder decoder = null; + try { + decoder = DecoderFactory.get() + .jsonDecoder(AvroHttpRequest.getClassSchema(), new String(data)); + return reader.read(null, decoder); + } catch (IOException e) { + logger.error("Deserialization error" + e.getMessage()); + } + return null; + } + + public AvroHttpRequest deSerealizeAvroHttpRequestBinary(byte[] data) { + DatumReader employeeReader = new SpecificDatumReader<>(AvroHttpRequest.class); + Decoder decoder = DecoderFactory.get() + .binaryDecoder(data, null); + try { + return employeeReader.read(null, decoder); + } catch (IOException e) { + logger.error("Deserialization error" + e.getMessage()); + } + return null; + } +} diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java b/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java new file mode 100644 index 0000000000..767b688dea --- /dev/null +++ b/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java @@ -0,0 +1,50 @@ +package com.baeldung.avro.util.serealization; + +import com.baeldung.avro.util.model.AvroHttpRequest; +import org.apache.avro.io.*; +import org.apache.avro.specific.SpecificDatumWriter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class AvroSerealizer { + + private static final Logger logger = LoggerFactory.getLogger(AvroSerealizer.class); + + public byte[] serealizeAvroHttpRequestJSON(AvroHttpRequest request) { + DatumWriter writer = new SpecificDatumWriter<>(AvroHttpRequest.class); + byte[] data = new byte[0]; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + Encoder jsonEncoder = null; + try { + jsonEncoder = EncoderFactory.get() + .jsonEncoder(AvroHttpRequest.getClassSchema(), stream); + writer.write(request, jsonEncoder); + jsonEncoder.flush(); + data = stream.toByteArray(); + } catch (IOException e) { + logger.error("Serialization error " + e.getMessage()); + } + return data; + } + + public byte[] serealizeAvroHttpRequestBinary(AvroHttpRequest request) { + DatumWriter writer = new SpecificDatumWriter<>(AvroHttpRequest.class); + byte[] data = new byte[0]; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + Encoder jsonEncoder = EncoderFactory.get() + .binaryEncoder(stream, null); + try { + writer.write(request, jsonEncoder); + jsonEncoder.flush(); + data = stream.toByteArray(); + } catch (IOException e) { + logger.error("Serialization error " + e.getMessage()); + } + + return data; + } + +} diff --git a/apache-avro/src/main/resources/avroHttpRequest-schema.avsc b/apache-avro/src/main/resources/avroHttpRequest-schema.avsc new file mode 100644 index 0000000000..18179a9cde --- /dev/null +++ b/apache-avro/src/main/resources/avroHttpRequest-schema.avsc @@ -0,0 +1,47 @@ +{ + "type":"record", + "name":"AvroHttpRequest", + "namespace":"com.baeldung.avro.model", + "fields":[ + { + "name":"requestTime", + "type":"long" + }, + { + "name":"clientIdentifier", + "type":{ + "type":"record", + "name":"ClientIdentifier", + "fields":[ + { + "name":"hostName", + "type":"string" + }, + { + "name":"ipAddress", + "type":"string" + } + ] + } + }, + { + "name":"employeeNames", + "type":{ + "type":"array", + "items":"string" + }, + "default":null + }, + { + "name":"active", + "type":{ + "type":"enum", + "name":"Active", + "symbols":[ + "YES", + "NO" + ] + } + } + ] +} \ No newline at end of file diff --git a/apache-avro/src/main/resources/logback.xml b/apache-avro/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-avro/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-avro/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java b/apache-avro/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java new file mode 100644 index 0000000000..992ea806c3 --- /dev/null +++ b/apache-avro/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.avro.util.serealization; + +import com.baeldung.avro.util.model.Active; +import com.baeldung.avro.util.model.AvroHttpRequest; +import com.baeldung.avro.util.model.ClientIdentifier; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static org.junit.Assert.*; + +public class AvroSerealizerDeSerealizerUnitTest { + + AvroSerealizer serealizer; + AvroDeSerealizer deSerealizer; + AvroHttpRequest request; + + @Before + public void setUp() throws Exception { + serealizer = new AvroSerealizer(); + deSerealizer = new AvroDeSerealizer(); + + ClientIdentifier clientIdentifier = ClientIdentifier.newBuilder() + .setHostName("localhost") + .setIpAddress("255.255.255.0") + .build(); + + List employees = new ArrayList(); + employees.add("James"); + employees.add("Alice"); + employees.add("David"); + employees.add("Han"); + + request = AvroHttpRequest.newBuilder() + .setRequestTime(01l) + .setActive(Active.YES) + .setClientIdentifier(clientIdentifier) + .setEmployeeNames(employees) + .build(); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void WhenSerializedUsingJSONEncoder_thenObjectGetsSerialized() { + byte[] data = serealizer.serealizeAvroHttpRequestJSON(request); + assertTrue(Objects.nonNull(data)); + assertTrue(data.length > 0); + } + + @Test + public void WhenSerializedUsingBinaryEncoder_thenObjectGetsSerialized() { + byte[] data = serealizer.serealizeAvroHttpRequestBinary(request); + assertTrue(Objects.nonNull(data)); + assertTrue(data.length > 0); + } + + @Test + public void WhenDeserializeUsingJSONDecoder_thenActualAndExpectedObjectsAreEqual() { + byte[] data = serealizer.serealizeAvroHttpRequestJSON(request); + AvroHttpRequest actualRequest = deSerealizer.deSerealizeAvroHttpRequestJSON(data); + assertEquals(actualRequest, request); + assertTrue(actualRequest.getRequestTime() + .equals(request.getRequestTime())); + } + + @Test + public void WhenDeserializeUsingBinaryecoder_thenActualAndExpectedObjectsAreEqual() { + byte[] data = serealizer.serealizeAvroHttpRequestBinary(request); + AvroHttpRequest actualRequest = deSerealizer.deSerealizeAvroHttpRequestBinary(data); + assertEquals(actualRequest, request); + assertTrue(actualRequest.getRequestTime() + .equals(request.getRequestTime())); + } + +} + diff --git a/apache-bval/pom.xml b/apache-bval/pom.xml index f8a3b8279d..5ddb1ecb59 100644 --- a/apache-bval/pom.xml +++ b/apache-bval/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 apache-bval apache-bval diff --git a/apache-bval/src/main/resources/logback.xml b/apache-bval/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-bval/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-cayenne/pom.xml b/apache-cayenne/pom.xml index fc16db3c81..591809d47f 100644 --- a/apache-cayenne/pom.xml +++ b/apache-cayenne/pom.xml @@ -28,12 +28,6 @@ runtime - - junit - junit - ${junit.version} - test - @@ -47,12 +41,8 @@ - UTF-8 - UTF-8 - 1.8 5.1.44 4.0.M5 - 4.12 diff --git a/apache-cayenne/src/main/resources/logback.xml b/apache-cayenne/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-cayenne/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-curator/pom.xml b/apache-curator/pom.xml index d867d7e74b..ac10811e7a 100644 --- a/apache-curator/pom.xml +++ b/apache-curator/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 apache-curator 0.0.1-SNAPSHOT diff --git a/apache-curator/src/main/resources/logback.xml b/apache-curator/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-curator/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-cxf/README.md b/apache-cxf/README.md index 1e66ce5da8..d03999dce3 100644 --- a/apache-cxf/README.md +++ b/apache-cxf/README.md @@ -3,3 +3,4 @@ - [Apache CXF Support for RESTful Web Services](http://www.baeldung.com/apache-cxf-rest-api) - [A Guide to Apache CXF with Spring](http://www.baeldung.com/apache-cxf-with-spring) - [Introduction to Apache CXF](http://www.baeldung.com/introduction-to-apache-cxf) +- [Server-Sent Events (SSE) In JAX-RS](https://www.baeldung.com/java-ee-jax-rs-sse) diff --git a/apache-cxf/cxf-aegis/pom.xml b/apache-cxf/cxf-aegis/pom.xml index 338860472c..b7e9e426a2 100644 --- a/apache-cxf/cxf-aegis/pom.xml +++ b/apache-cxf/cxf-aegis/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 cxf-aegis @@ -17,8 +17,4 @@ - - 3.1.8 - - diff --git a/apache-cxf/cxf-aegis/src/main/resources/logback.xml b/apache-cxf/cxf-aegis/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-cxf/cxf-aegis/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-cxf/cxf-introduction/pom.xml b/apache-cxf/cxf-introduction/pom.xml index 3c44734733..a9e82c16b3 100644 --- a/apache-cxf/cxf-introduction/pom.xml +++ b/apache-cxf/cxf-introduction/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 cxf-introduction @@ -36,9 +36,4 @@ - - 3.1.8 - 2.19.1 - - diff --git a/apache-cxf/cxf-introduction/src/main/resources/logback.xml b/apache-cxf/cxf-introduction/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-cxf/cxf-introduction/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-cxf/cxf-jaxrs-implementation/pom.xml b/apache-cxf/cxf-jaxrs-implementation/pom.xml index ce35d67948..89acbdf1bd 100644 --- a/apache-cxf/cxf-jaxrs-implementation/pom.xml +++ b/apache-cxf/cxf-jaxrs-implementation/pom.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 cxf-jaxrs-implementation @@ -48,10 +48,7 @@ - UTF-8 - 3.1.8 4.5.2 - 2.19.1 diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/logback.xml b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-cxf/cxf-spring/pom.xml b/apache-cxf/cxf-spring/pom.xml index a06165f4ad..31e75e7cdd 100644 --- a/apache-cxf/cxf-spring/pom.xml +++ b/apache-cxf/cxf-spring/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 cxf-spring war @@ -101,11 +101,7 @@ - 3.1.8 4.3.4.RELEASE - 3.1.0 - 2.6 - 2.19.1 1.6.1 diff --git a/apache-cxf/cxf-spring/src/main/resources/logback.xml b/apache-cxf/cxf-spring/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-cxf/cxf-spring/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-cxf/pom.xml b/apache-cxf/pom.xml index 5a864b18ef..8918fd4450 100644 --- a/apache-cxf/pom.xml +++ b/apache-cxf/pom.xml @@ -17,6 +17,7 @@ cxf-spring cxf-jaxrs-implementation cxf-aegis + sse-jaxrs @@ -33,7 +34,7 @@ - 1.5.0 + 3.1.8 diff --git a/apache-cxf/sse-jaxrs/pom.xml b/apache-cxf/sse-jaxrs/pom.xml new file mode 100644 index 0000000000..d4b6c19d03 --- /dev/null +++ b/apache-cxf/sse-jaxrs/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + sse-jaxrs + pom + + + com.baeldung + apache-cxf + 0.0.1-SNAPSHOT + + + + sse-jaxrs-server + sse-jaxrs-client + + + diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-client/pom.xml b/apache-cxf/sse-jaxrs/sse-jaxrs-client/pom.xml new file mode 100644 index 0000000000..0f5406fbc7 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-client/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + + com.baeldung + sse-jaxrs + 0.0.1-SNAPSHOT + + + sse-jaxrs-client + + + 3.2.0 + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + singleEvent + + java + + + com.baeldung.sse.jaxrs.client.SseClientApp + + + + broadcast + + java + + + com.baeldung.sse.jaxrs.client.SseClientBroadcastApp + + + + + + + + + + org.apache.cxf + cxf-rt-rs-client + ${cxf-version} + + + org.apache.cxf + cxf-rt-rs-sse + ${cxf-version} + + + + diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java b/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java new file mode 100644 index 0000000000..5d42b3a243 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java @@ -0,0 +1,48 @@ +package com.baeldung.sse.jaxrs.client; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.sse.InboundSseEvent; +import javax.ws.rs.sse.SseEventSource; +import java.util.function.Consumer; + +public class SseClientApp { + + private static final String url = "http://127.0.0.1:9080/sse-jaxrs-server/sse/stock/prices"; + + public static void main(String... args) throws Exception { + + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(url); + try (SseEventSource eventSource = SseEventSource.target(target).build()) { + + eventSource.register(onEvent, onError, onComplete); + eventSource.open(); + + //Consuming events for one hour + Thread.sleep(60 * 60 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + client.close(); + System.out.println("End"); + } + + // A new event is received + private static Consumer onEvent = (inboundSseEvent) -> { + String data = inboundSseEvent.readData(); + System.out.println(data); + }; + + //Error + private static Consumer onError = (throwable) -> { + throwable.printStackTrace(); + }; + + //Connection close and there is nothing to receive + private static Runnable onComplete = () -> { + System.out.println("Done!"); + }; + +} diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java b/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java new file mode 100644 index 0000000000..9afc187a6d --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java @@ -0,0 +1,52 @@ +package com.baeldung.sse.jaxrs.client; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.sse.InboundSseEvent; +import javax.ws.rs.sse.SseEventSource; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +public class SseClientBroadcastApp { + + private static final String subscribeUrl = "http://localhost:9080/sse-jaxrs-server/sse/stock/subscribe"; + + + public static void main(String... args) throws Exception { + + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(subscribeUrl); + try (final SseEventSource eventSource = SseEventSource.target(target) + .reconnectingEvery(5, TimeUnit.SECONDS) + .build()) { + eventSource.register(onEvent, onError, onComplete); + eventSource.open(); + System.out.println("Wainting for incoming event ..."); + + //Consuming events for one hour + Thread.sleep(60 * 60 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + client.close(); + System.out.println("End"); + } + + // A new event is received + private static Consumer onEvent = (inboundSseEvent) -> { + String data = inboundSseEvent.readData(); + System.out.println(data); + }; + + //Error + private static Consumer onError = (throwable) -> { + throwable.printStackTrace(); + }; + + //Connection close and there is nothing to receive + private static Runnable onComplete = () -> { + System.out.println("Done!"); + }; + +} diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml b/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/pom.xml b/apache-cxf/sse-jaxrs/sse-jaxrs-server/pom.xml new file mode 100644 index 0000000000..2e82dc3829 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/pom.xml @@ -0,0 +1,85 @@ + + + 4.0.0 + + + com.baeldung + sse-jaxrs + 0.0.1-SNAPSHOT + + + sse-jaxrs-server + war + + + 2.4.2 + false + 18.0.0.2 + + + + ${project.artifactId} + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + ${liberty-maven-plugin.version} + + + io.openliberty + openliberty-webProfile8 + ${openliberty-version} + zip + + project + true + src/main/liberty/config/server.xml + + + + install-server + prepare-package + + install-server + create-server + install-feature + + + + install-apps + package + + install-apps + + + + + + + + + + + javax.ws.rs + javax.ws.rs-api + 2.1 + provided + + + javax.enterprise + cdi-api + 2.0 + provided + + + javax.json.bind + javax.json.bind-api + 1.0 + provided + + + + + diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java new file mode 100644 index 0000000000..058d19f045 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java @@ -0,0 +1,8 @@ +package com.baeldung.sse.jaxrs; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +@ApplicationPath("sse") +public class AppConfig extends Application { +} diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java new file mode 100644 index 0000000000..1f60168a1b --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java @@ -0,0 +1,119 @@ +package com.baeldung.sse.jaxrs; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.sse.OutboundSseEvent; +import javax.ws.rs.sse.Sse; +import javax.ws.rs.sse.SseBroadcaster; +import javax.ws.rs.sse.SseEventSink; + +@ApplicationScoped +@Path("stock") +public class SseResource { + + @Inject + private StockService stockService; + + private Sse sse; + private SseBroadcaster sseBroadcaster; + private OutboundSseEvent.Builder eventBuilder; + + @Context + public void setSse(Sse sse) { + this.sse = sse; + this.eventBuilder = sse.newEventBuilder(); + this.sseBroadcaster = sse.newBroadcaster(); + } + + @GET + @Path("prices") + @Produces("text/event-stream") + public void getStockPrices(@Context SseEventSink sseEventSink, + @HeaderParam(HttpHeaders.LAST_EVENT_ID_HEADER) @DefaultValue("-1") int lastReceivedId) { + + int lastEventId = 1; + if (lastReceivedId != -1) { + lastEventId = ++lastReceivedId; + } + boolean running = true; + while (running) { + Stock stock = stockService.getNextTransaction(lastEventId); + if (stock != null) { + OutboundSseEvent sseEvent = this.eventBuilder + .name("stock") + .id(String.valueOf(lastEventId)) + .mediaType(MediaType.APPLICATION_JSON_TYPE) + .data(Stock.class, stock) + .reconnectDelay(3000) + .comment("price change") + .build(); + sseEventSink.send(sseEvent); + lastEventId++; + } + //Simulate connection close + if (lastEventId % 5 == 0) { + sseEventSink.close(); + break; + } + + try { + //Wait 5 seconds + Thread.sleep(5 * 1000); + } catch (InterruptedException ex) { + // ... + } + //Simulatae a while boucle break + running = lastEventId <= 2000; + } + sseEventSink.close(); + } + + @GET + @Path("subscribe") + @Produces(MediaType.SERVER_SENT_EVENTS) + public void listen(@Context SseEventSink sseEventSink) { + sseEventSink.send(sse.newEvent("Welcome !")); + this.sseBroadcaster.register(sseEventSink); + sseEventSink.send(sse.newEvent("You are registred !")); + } + + @GET + @Path("publish") + public void broadcast() { + Runnable r = new Runnable() { + @Override + public void run() { + int lastEventId = 0; + boolean running = true; + while (running) { + lastEventId++; + Stock stock = stockService.getNextTransaction(lastEventId); + if (stock != null) { + OutboundSseEvent sseEvent = eventBuilder + .name("stock") + .id(String.valueOf(lastEventId)) + .mediaType(MediaType.APPLICATION_JSON_TYPE) + .data(Stock.class, stock) + .reconnectDelay(3000) + .comment("price change") + .build(); + sseBroadcaster.broadcast(sseEvent); + } + try { + //Wait 5 seconds + Thread.currentThread().sleep(5 * 1000); + } catch (InterruptedException ex) { + // ... + } + //Simulatae a while boucle break + running = lastEventId <= 2000; + } + } + }; + new Thread(r).start(); + } +} diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java new file mode 100644 index 0000000000..a186b32771 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java @@ -0,0 +1,50 @@ +package com.baeldung.sse.jaxrs; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +public class Stock { + private Integer id; + private String name; + private BigDecimal price; + LocalDateTime dateTime; + + public Stock(Integer id, String name, BigDecimal price, LocalDateTime dateTime) { + this.id = id; + this.name = name; + this.price = price; + this.dateTime = dateTime; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public LocalDateTime getDateTime() { + return dateTime; + } + + public void setDateTime(LocalDateTime dateTime) { + this.dateTime = dateTime; + } +} diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java new file mode 100644 index 0000000000..15818ead5d --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java @@ -0,0 +1,78 @@ +package com.baeldung.sse.jaxrs; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Initialized; +import javax.enterprise.event.Event; +import javax.enterprise.event.Observes; +import javax.inject.Inject; +import javax.inject.Named; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +@ApplicationScoped +@Named +public class StockService { + + private static final BigDecimal UP = BigDecimal.valueOf(1.05f); + private static final BigDecimal DOWN = BigDecimal.valueOf(0.95f); + + List stockNames = Arrays.asList("GOOG", "IBM", "MS", "GOOG", "YAHO"); + List stocksDB = new ArrayList<>(); + private AtomicInteger counter = new AtomicInteger(0); + + public void init(@Observes @Initialized(ApplicationScoped.class) Object init) { + //Open price + System.out.println("@Start Init ..."); + stockNames.forEach(stockName -> { + stocksDB.add(new Stock(counter.incrementAndGet(), stockName, generateOpenPrice(), LocalDateTime.now())); + }); + + Runnable runnable = new Runnable() { + @Override + public void run() { + //Simulate Change price and put every x seconds + while (true) { + int indx = new Random().nextInt(stockNames.size()); + String stockName = stockNames.get(indx); + BigDecimal price = getLastPrice(stockName); + BigDecimal newprice = changePrice(price); + Stock stock = new Stock(counter.incrementAndGet(), stockName, newprice, LocalDateTime.now()); + stocksDB.add(stock); + + int r = new Random().nextInt(30); + try { + Thread.currentThread().sleep(r*1000); + } catch (InterruptedException ex) { + // ... + } + } + } + }; + new Thread(runnable).start(); + System.out.println("@End Init ..."); + } + + public Stock getNextTransaction(Integer lastEventId) { + return stocksDB.stream().filter(s -> s.getId().equals(lastEventId)).findFirst().orElse(null); + } + + BigDecimal generateOpenPrice() { + float min = 70; + float max = 120; + return BigDecimal.valueOf(min + new Random().nextFloat() * (max - min)).setScale(4,RoundingMode.CEILING); + } + + BigDecimal changePrice(BigDecimal price) { + return Math.random() >= 0.5 ? price.multiply(UP).setScale(4,RoundingMode.CEILING) : price.multiply(DOWN).setScale(4,RoundingMode.CEILING); + } + + private BigDecimal getLastPrice(String stockName) { + return stocksDB.stream().filter(stock -> stock.getName().equals(stockName)).findFirst().get().getPrice(); + } +} diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml new file mode 100644 index 0000000000..9bf66d7795 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml @@ -0,0 +1,7 @@ + + + jaxrs-2.1 + cdi-2.0 + + + diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..4f0b3cdeeb --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..b4b8121fdd --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,11 @@ + + + Hello Servlet + + + index.html + + + diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html new file mode 100644 index 0000000000..9015a7a32c --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html @@ -0,0 +1 @@ +index diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html new file mode 100644 index 0000000000..5a46e2a5d3 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html @@ -0,0 +1,38 @@ + + + + Server-Sent Event Broadcasting + + +

Stock prices :

+
+
    +
+
+ + + \ No newline at end of file diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html new file mode 100644 index 0000000000..8fddae4717 --- /dev/null +++ b/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html @@ -0,0 +1,38 @@ + + + + Server-Sent Event + + +

Stock prices :

+
+
    +
+
+ + + \ No newline at end of file diff --git a/apache-fop/pom.xml b/apache-fop/pom.xml index d0c6984757..879eb4f111 100644 --- a/apache-fop/pom.xml +++ b/apache-fop/pom.xml @@ -1,5 +1,5 @@ + 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 apache-fop diff --git a/apache-fop/src/main/resources/logback.xml b/apache-fop/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/apache-fop/src/main/resources/logback.xml +++ b/apache-fop/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/apache-geode/pom.xml b/apache-geode/pom.xml new file mode 100644 index 0000000000..a3f6604ac4 --- /dev/null +++ b/apache-geode/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + com.baeldung + apache-geode + 1.0-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + 1.6.0 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + + org.apache.geode + geode-core + ${geode.core} + + + junit + junit + RELEASE + + + + \ No newline at end of file diff --git a/apache-geode/src/main/java/com/baeldung/geode/Customer.java b/apache-geode/src/main/java/com/baeldung/geode/Customer.java new file mode 100644 index 0000000000..82ee5ecaeb --- /dev/null +++ b/apache-geode/src/main/java/com/baeldung/geode/Customer.java @@ -0,0 +1,78 @@ +package com.baeldung.geode; + +import java.io.Serializable; +import java.util.Objects; + +public class Customer implements Serializable { + + private static final long serialVersionUID = -7482516011038799900L; + + private CustomerKey key; + private String firstName; + private String lastName; + private Integer age; + + public Customer() { + } + + public Customer(String firstName, String lastName, int age) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + } + + public Customer(CustomerKey key, String firstName, String lastName, int age) { + this(firstName, lastName, age); + this.key = key; + } + + // setters and getters + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + @Override + public String toString() { + return "Customer{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\'' + ", age=" + age + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Customer customer = (Customer) o; + return Objects.equals(firstName, customer.firstName) && Objects.equals(lastName, customer.lastName) && Objects.equals(age, customer.age); + } + + @Override + public int hashCode() { + return Objects.hash(firstName, lastName, age); + } +} diff --git a/apache-geode/src/main/java/com/baeldung/geode/CustomerKey.java b/apache-geode/src/main/java/com/baeldung/geode/CustomerKey.java new file mode 100644 index 0000000000..bfa64870c0 --- /dev/null +++ b/apache-geode/src/main/java/com/baeldung/geode/CustomerKey.java @@ -0,0 +1,57 @@ +package com.baeldung.geode; + +import java.io.Serializable; + +public class CustomerKey implements Serializable { + + private static final long serialVersionUID = -3529253035303792458L; + private long id; + private String country; + + public CustomerKey(long id) { + this.id = id; + this.country = "USA"; + } + + public CustomerKey(long id, String country) { + this.id = id; + this.country = country; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + CustomerKey that = (CustomerKey) o; + + if (id != that.id) + return false; + return country != null ? country.equals(that.country) : that.country == null; + } + + @Override + public int hashCode() { + int result = (int) (id ^ (id >>> 32)); + result = 31 * result + (country != null ? country.hashCode() : 0); + return result; + } +} diff --git a/apache-geode/src/main/java/com/baeldung/geode/functions/UpperCaseNames.java b/apache-geode/src/main/java/com/baeldung/geode/functions/UpperCaseNames.java new file mode 100644 index 0000000000..5ff8e53da8 --- /dev/null +++ b/apache-geode/src/main/java/com/baeldung/geode/functions/UpperCaseNames.java @@ -0,0 +1,34 @@ +package com.baeldung.geode.functions; + +import com.baeldung.geode.Customer; +import com.baeldung.geode.CustomerKey; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.execute.Function; +import org.apache.geode.cache.execute.FunctionContext; +import org.apache.geode.cache.execute.RegionFunctionContext; + +import java.util.Map; + +public class UpperCaseNames implements Function { + private static final long serialVersionUID = -8946294032165677602L; + + @Override + public void execute(FunctionContext context) { + RegionFunctionContext regionContext = (RegionFunctionContext) context; + Region region = regionContext.getDataSet(); + + for (Map.Entry entry : region.entrySet()) { + Customer customer = entry.getValue(); + customer.setFirstName(customer.getFirstName() + .toUpperCase()); + } + + context.getResultSender() + .lastResult(true); + } + + @Override + public String getId() { + return getClass().getName(); + } +} diff --git a/apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesIntegrationTest.java b/apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesIntegrationTest.java new file mode 100644 index 0000000000..b96d2c9b6a --- /dev/null +++ b/apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesIntegrationTest.java @@ -0,0 +1,110 @@ +package com.baeldung.geode; + +import com.baeldung.geode.functions.UpperCaseNames; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.client.ClientRegionShortcut; +import org.apache.geode.cache.execute.Execution; +import org.apache.geode.cache.execute.FunctionService; +import org.apache.geode.cache.query.*; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; + +public class GeodeSamplesIntegrationTest { + + ClientCache cache = null; + Region region = null; + Region queryRegion = null; + Region customerRegion = null; + + @Before + public void connect() { + this.cache = new ClientCacheFactory().addPoolLocator("localhost", 10334) + .create(); + this.region = this.cache. createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY) + .create("baeldung"); + this.customerRegion = this.cache. createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY) + .create("baeldung-customers"); + } + + @After + public void cleanup() { + this.cache.close(); + } + + @Test + public void whenSendMessageToRegion_thenMessageSavedSuccessfully() { + + this.region.put("1", "Hello"); + this.region.put("2", "Baeldung"); + + assertEquals("Hello", region.get("1")); + assertEquals("Baeldung", region.get("2")); + + } + + @Test + public void whenPutMultipleValuesAtOnce_thenValuesSavedSuccessfully() { + + Supplier> keys = () -> Stream.of("A", "B", "C", "D", "E"); + Map values = keys.get() + .collect(Collectors.toMap(Function.identity(), String::toLowerCase)); + + this.region.putAll(values); + + keys.get() + .forEach(k -> assertEquals(k.toLowerCase(), this.region.get(k))); + + } + + @Test + public void whenPutCustomKey_thenValuesSavedSuccessfully() { + CustomerKey key = new CustomerKey(123); + Customer customer = new Customer(key, "William", "Russell", 35); + + Map customerInfo = new HashMap<>(); + customerInfo.put(key, customer); + + this.customerRegion.putAll(customerInfo); + + Customer storedCustomer = this.customerRegion.get(key); + assertEquals("William", storedCustomer.getFirstName()); + assertEquals("Russell", storedCustomer.getLastName()); + + } + + @Test + public void whenFindACustomerUsingOQL_thenCorrectCustomerObject() throws NameResolutionException, TypeMismatchException, QueryInvocationTargetException, FunctionDomainException { + + Map data = new HashMap<>(); + data.put(new CustomerKey(1), new Customer("Gheorge", "Manuc", 36)); + data.put(new CustomerKey(2), new Customer("Allan", "McDowell", 43)); + this.customerRegion.putAll(data); + + QueryService queryService = this.cache.getQueryService(); + String query = "select * from /baeldung-customers c where c.firstName = 'Allan'"; + SelectResults queryResults = (SelectResults) queryService.newQuery(query) + .execute(); + assertEquals(1, queryResults.size()); + + } + + @Test + public void whenExecuteUppercaseNames_thenCustomerNamesAreUppercased() { + Execution execution = FunctionService.onRegion(this.customerRegion); + execution.execute(UpperCaseNames.class.getName()); + Customer customer = this.customerRegion.get(new CustomerKey(1)); + assertEquals("GHEORGE", customer.getFirstName()); + } +} diff --git a/apache-meecrowave/README.md b/apache-meecrowave/README.md new file mode 100644 index 0000000000..42b93a383e --- /dev/null +++ b/apache-meecrowave/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +================================ +- [Building a Microservice with Apache Meecrowave](http://www.baeldung.com/apache-meecrowave) diff --git a/apache-meecrowave/pom.xml b/apache-meecrowave/pom.xml new file mode 100644 index 0000000000..cf13aa1c1b --- /dev/null +++ b/apache-meecrowave/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + com.baeldung + apache-meecrowave + 0.0.1 + apache-meecrowave + A sample REST API application with Meecrowave + + + 1.8 + 1.8 + + + + + org.apache.meecrowave + meecrowave-core + 1.2.1 + + + + org.apache.meecrowave + meecrowave-jpa + 1.2.1 + + + + com.squareup.okhttp3 + okhttp + 3.10.0 + + + org.apache.meecrowave + meecrowave-junit + 1.2.0 + test + + + + junit + junit + 4.10 + test + + + + + + + org.apache.meecrowave + meecrowave-maven-plugin + 1.2.1 + + + + \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java new file mode 100644 index 0000000000..7925e8ff99 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java @@ -0,0 +1,30 @@ +package com.baeldung.meecrowave; + +public class Article { + private String name; + private String author; + + public Article() { + } + + public Article(String name, String author) { + this.author = author; + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } +} \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java new file mode 100644 index 0000000000..6cb7012c64 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java @@ -0,0 +1,32 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +@RequestScoped +@Path("article") +public class ArticleEndpoints { + + @Inject + ArticleService articleService; + + @GET + public Response getArticle() { + return Response.ok() + .entity(new Article("name", "author")) + .build(); + + } + + @POST + public Response createArticle(Article article) { + return Response.status(Status.CREATED) + .entity(articleService.createArticle(article)) + .build(); + } +} \ No newline at end of file diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java new file mode 100644 index 0000000000..7bd6b87345 --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java @@ -0,0 +1,10 @@ +package com.baeldung.meecrowave; + +import javax.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ArticleService { + public Article createArticle(Article article) { + return article; + } +} diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java new file mode 100644 index 0000000000..2aa7d0556f --- /dev/null +++ b/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java @@ -0,0 +1,16 @@ +package com.baeldung.meecrowave; + +import org.apache.meecrowave.Meecrowave; + +public class Server { + public static void main(String[] args) { + final Meecrowave.Builder builder = new Meecrowave.Builder(); + builder.setScanningPackageIncludes("com.baeldung.meecrowave"); + builder.setJaxrsMapping("/api/*"); + builder.setJsonpPrettify(true); + + try (Meecrowave meecrowave = new Meecrowave(builder)) { + meecrowave.bake().await(); + } + } +} diff --git a/apache-meecrowave/src/main/resources/logback.xml b/apache-meecrowave/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-meecrowave/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java b/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java new file mode 100644 index 0000000000..0dc9773490 --- /dev/null +++ b/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsTest.java @@ -0,0 +1,41 @@ +package com.baeldung.meecrowave; + + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.apache.meecrowave.Meecrowave; +import org.apache.meecrowave.junit.MonoMeecrowave; +import org.apache.meecrowave.testing.ConfigurationInject; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +@RunWith(MonoMeecrowave.Runner.class) +public class ArticleEndpointsTest { + + @ConfigurationInject + private Meecrowave.Builder config; + private static OkHttpClient client; + + @BeforeClass + public static void setup() { + client = new OkHttpClient(); + } + + @Test + public void whenRetunedArticle_thenCorrect() throws IOException { + final String base = "http://localhost:"+config.getHttpPort(); + + Request request = new Request.Builder() + .url(base+"/article") + .build(); + Response response = client.newCall(request).execute(); + assertEquals(200, response.code()); + } +} diff --git a/apache-opennlp/pom.xml b/apache-opennlp/pom.xml index 4095207aab..985c9a2df2 100644 --- a/apache-opennlp/pom.xml +++ b/apache-opennlp/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 apache-opennlp 1.0-SNAPSHOT @@ -24,12 +24,6 @@ ${org.assertj.version} test - - junit - junit - ${junit.version} - test - diff --git a/apache-opennlp/src/main/resources/logback.xml b/apache-opennlp/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-opennlp/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-poi/pom.xml b/apache-poi/pom.xml index 4874fe0b3e..a1ec626d43 100644 --- a/apache-poi/pom.xml +++ b/apache-poi/pom.xml @@ -1,5 +1,5 @@ + 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 apache-poi diff --git a/apache-poi/src/main/resources/logback.xml b/apache-poi/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-poi/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-shiro/pom.xml b/apache-shiro/pom.xml index 73fdcab9d2..98d9563284 100644 --- a/apache-shiro/pom.xml +++ b/apache-shiro/pom.xml @@ -3,14 +3,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung apache-shiro 1.0-SNAPSHOT - org.springframework.boot - spring-boot-starter-parent - ${org.springframework.boot.spring-boot-starter-parent.version} + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 @@ -35,13 +35,11 @@ org.slf4j jcl-over-slf4j - ${slf4j-version} runtime org.slf4j slf4j-log4j12 - ${slf4j-version} runtime @@ -52,25 +50,9 @@ - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - 1.8 - 1.8 - - - - - 1.4.0 1.2.17 - 1.7.25 - 1.5.2.RELEASE \ No newline at end of file diff --git a/apache-solrj/pom.xml b/apache-solrj/pom.xml index 31639c4864..9a807c2f26 100644 --- a/apache-solrj/pom.xml +++ b/apache-solrj/pom.xml @@ -1,5 +1,5 @@ + 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 apache-solrj diff --git a/apache-solrj/src/main/resources/logback.xml b/apache-solrj/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-solrj/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java b/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java similarity index 98% rename from apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java rename to apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java index 8b5fe77c6f..eaf0271b55 100644 --- a/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java +++ b/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java @@ -12,7 +12,7 @@ import org.apache.solr.common.SolrDocumentList; import org.junit.Before; import org.junit.Test; -public class SolrJavaIntegrationTest { +public class SolrJavaLiveTest { private SolrJavaIntegration solrJavaIntegration; diff --git a/apache-spark/pom.xml b/apache-spark/pom.xml index 3627f58147..290b63a14d 100644 --- a/apache-spark/pom.xml +++ b/apache-spark/pom.xml @@ -1,5 +1,5 @@ + 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 apache-spark @@ -21,16 +21,9 @@ spark-core_2.10 ${org.apache.spark.spark-core.version} - - junit - junit - ${junit.version} - test - - UTF-8 2.2.0 diff --git a/apache-spark/src/main/resources/logback.xml b/apache-spark/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-spark/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-thrift/pom.xml b/apache-thrift/pom.xml index 272bbb98d7..b22364cb19 100644 --- a/apache-thrift/pom.xml +++ b/apache-thrift/pom.xml @@ -1,5 +1,5 @@ + 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 apache-thrift @@ -39,6 +39,7 @@ org.codehaus.mojo build-helper-maven-plugin + ${build-helper-maven-plugin.version} generate-sources @@ -60,6 +61,7 @@ 0.10.0 0.1.11 1.7.12 + 3.0.0 diff --git a/apache-thrift/src/main/resources/logback.xml b/apache-thrift/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-thrift/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-tika/pom.xml b/apache-tika/pom.xml index 27bb851174..5a76fdeeda 100644 --- a/apache-tika/pom.xml +++ b/apache-tika/pom.xml @@ -1,5 +1,5 @@ + 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 apache-tika diff --git a/apache-tika/src/main/resources/logback.xml b/apache-tika/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-tika/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/apache-velocity/pom.xml b/apache-velocity/pom.xml index efacdff25a..19cf77d945 100644 --- a/apache-velocity/pom.xml +++ b/apache-velocity/pom.xml @@ -60,7 +60,6 @@ 1.2 - 2.6 4.5.2 1.7 2.0 diff --git a/apache-velocity/src/main/resources/logback.xml b/apache-velocity/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/apache-velocity/src/main/resources/logback.xml +++ b/apache-velocity/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/apache-zookeeper/pom.xml b/apache-zookeeper/pom.xml index 7e1960ebb0..0b29186ccc 100644 --- a/apache-zookeeper/pom.xml +++ b/apache-zookeeper/pom.xml @@ -1,5 +1,5 @@ + 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 apache-zookeeper diff --git a/apache-zookeeper/src/main/resources/logback.xml b/apache-zookeeper/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/apache-zookeeper/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/asciidoctor/README.md b/asciidoctor/README.md index aafd0bca17..2124907e87 100644 --- a/asciidoctor/README.md +++ b/asciidoctor/README.md @@ -1,5 +1,4 @@ ### Relevant articles -- [Introduction to Asciidoctor](http://www.baeldung.com/introduction-to-asciidoctor) - [Generating a Book with Asciidoctor](http://www.baeldung.com/asciidoctor-book) - [Introduction to Asciidoctor in Java](http://www.baeldung.com/asciidoctor) diff --git a/asciidoctor/pom.xml b/asciidoctor/pom.xml index 6843b4da42..42ee544eb0 100644 --- a/asciidoctor/pom.xml +++ b/asciidoctor/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 asciidoctor asciidoctor @@ -61,9 +61,10 @@ - 1.5.5 - 1.5.4 - 1.5.0-alpha.11 + 1.5.6 + 1.5.6 + + 1.5.0-alpha.15 1.5.0-alpha.15 diff --git a/asciidoctor/src/main/resources/logback.xml b/asciidoctor/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/asciidoctor/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/asciidoctor/src/test/java/com/baeldung/asciidoctor/AsciidoctorDemoTest.java b/asciidoctor/src/test/java/com/baeldung/asciidoctor/AsciidoctorDemoIntegrationTest.java similarity index 89% rename from asciidoctor/src/test/java/com/baeldung/asciidoctor/AsciidoctorDemoTest.java rename to asciidoctor/src/test/java/com/baeldung/asciidoctor/AsciidoctorDemoIntegrationTest.java index 3e312eb059..c4129e6441 100644 --- a/asciidoctor/src/test/java/com/baeldung/asciidoctor/AsciidoctorDemoTest.java +++ b/asciidoctor/src/test/java/com/baeldung/asciidoctor/AsciidoctorDemoIntegrationTest.java @@ -3,7 +3,7 @@ package com.baeldung.asciidoctor; import org.junit.Assert; import org.junit.Test; -public class AsciidoctorDemoTest { +public class AsciidoctorDemoIntegrationTest { @Test public void givenString_whenConverting_thenResultingHTMLCode() { diff --git a/asm/pom.xml b/asm/pom.xml index 8c3aa379db..5aad2a0e37 100644 --- a/asm/pom.xml +++ b/asm/pom.xml @@ -1,6 +1,6 @@ + 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.examples asm @@ -42,22 +42,12 @@ - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - -javaagent:"C:\asm-1.0.jar" - - - UTF-8 5.2 2.4 - 2.9 \ No newline at end of file diff --git a/asm/src/main/resources/logback.xml b/asm/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/asm/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/atomix/pom.xml b/atomix/pom.xml index e41e60138d..f85d2d7484 100644 --- a/atomix/pom.xml +++ b/atomix/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.atomix.io atomix @@ -17,12 +17,6 @@ atomix-all ${atomix-all.version} - - junit - junit - ${junit.version} - test - log4j log4j @@ -32,7 +26,6 @@ 1.0.0-rc9 - 1.2.17 diff --git a/atomix/src/main/resources/logback.xml b/atomix/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/atomix/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/autovalue/pom.xml b/autovalue/pom.xml index 3aa645002b..3ec2d26b35 100644 --- a/autovalue/pom.xml +++ b/autovalue/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung autovalue diff --git a/autovalue/src/main/resources/logback.xml b/autovalue/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/autovalue/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/aws-lambda/README.md b/aws-lambda/README.md new file mode 100644 index 0000000000..921b699bdd --- /dev/null +++ b/aws-lambda/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Using AWS Lambda with API Gateway](http://www.baeldung.com/aws-lambda-api-gateway) +- [Introduction to AWS Serverless Application Model](http://www.baeldung.com/aws-serverless) diff --git a/aws-lambda/pom.xml b/aws-lambda/pom.xml index 878e4db109..c47c3cd86f 100644 --- a/aws-lambda/pom.xml +++ b/aws-lambda/pom.xml @@ -1,31 +1,30 @@ - - - parent-modules - com.baeldung - 1.0.0-SNAPSHOT - + 4.0.0 - com.baeldung aws-lambda 0.1.0-SNAPSHOT jar aws-lambda + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + com.amazonaws aws-java-sdk-dynamodb - 1.11.241 + ${aws-java-sdk.version} com.amazonaws aws-java-sdk-core - 1.11.241 + ${aws-java-sdk.version} com.amazonaws @@ -65,26 +64,28 @@ ${json-simple.version} + - - - org.apache.maven.plugins - maven-shade-plugin - ${maven-shade-plugin.version} - - false - - - - package - - shade - - - - - + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + false + + + + package + + shade + + + + + + 1.1.1 20180130 @@ -92,8 +93,8 @@ 1.3.0 1.2.0 2.8.2 - 1.11.241 + 1.11.241 3.0.0 - 2.10 + \ No newline at end of file diff --git a/aws-lambda/sam-templates/template-implicit.yaml b/aws-lambda/sam-templates/template-implicit.yaml index 73289b8bb1..3e5b12763e 100644 --- a/aws-lambda/sam-templates/template-implicit.yaml +++ b/aws-lambda/sam-templates/template-implicit.yaml @@ -33,10 +33,10 @@ Resources: Properties: Path: /persons Method: PUT - GetPersonByPathParamFunction: + GetPersonByHTTPParamFunction: Type: AWS::Serverless::Function Properties: - Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByPathParam + Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByParam Runtime: java8 Timeout: 15 MemorySize: 512 @@ -53,21 +53,6 @@ Resources: Properties: Path: /persons/{id} Method: GET - GetPersonByQueryParamFunction: - Type: AWS::Serverless::Function - Properties: - Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByQueryParam - Runtime: java8 - Timeout: 15 - MemorySize: 512 - CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar - Policies: - - DynamoDBReadPolicy: - TableName: !Ref PersonTable - Environment: - Variables: - TABLE_NAME: !Ref PersonTable - Events: GetByQueryApi: Type: Api Properties: diff --git a/aws-lambda/sam-templates/template-inline-swagger.yaml b/aws-lambda/sam-templates/template-inline-swagger.yaml index f704d47c25..8422bcead2 100644 --- a/aws-lambda/sam-templates/template-inline-swagger.yaml +++ b/aws-lambda/sam-templates/template-inline-swagger.yaml @@ -31,10 +31,10 @@ Resources: Method: PUT RestApiId: Ref: MyApi - GetPersonByPathParamFunction: + GetPersonByHTTPParamFunction: Type: AWS::Serverless::Function Properties: - Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByPathParam + Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByParam Runtime: java8 Timeout: 15 MemorySize: 512 @@ -53,21 +53,6 @@ Resources: Method: GET RestApiId: Ref: MyApi - GetPersonByQueryParamFunction: - Type: AWS::Serverless::Function - Properties: - Handler: com.baeldung.lambda.apigateway.APIDemoHandler::handleGetByQueryParam - Runtime: java8 - Timeout: 15 - MemorySize: 512 - CodeUri: ../target/aws-lambda-0.1.0-SNAPSHOT.jar - Policies: - - DynamoDBReadPolicy: - TableName: !Ref PersonTable - Environment: - Variables: - TABLE_NAME: !Ref PersonTable - Events: GetByQueryApi: Type: Api Properties: @@ -96,7 +81,7 @@ Resources: \ headers" x-amazon-apigateway-integration: uri: - Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByQueryParamFunction.Arn}/invocations + Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByHTTPParamFunction.Arn}/invocations responses: {} httpMethod: "POST" type: "aws_proxy" @@ -117,7 +102,7 @@ Resources: responses: {} x-amazon-apigateway-integration: uri: - Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByPathParamFunction.Arn}/invocations + Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetPersonByHTTPParamFunction.Arn}/invocations responses: {} httpMethod: "POST" type: "aws_proxy" diff --git a/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java b/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java index 71889eaf1b..31bcd0b952 100644 --- a/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java +++ b/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/APIDemoHandler.java @@ -16,7 +16,7 @@ import java.io.*; public class APIDemoHandler implements RequestStreamHandler { private JSONParser parser = new JSONParser(); - private static final String DYNAMODB_TABLE_NAME = System.getenv("TABLE_NAME"); + private static final String DYNAMODB_TABLE_NAME = System.getenv("TABLE_NAME"); @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { @@ -35,10 +35,8 @@ public class APIDemoHandler implements RequestStreamHandler { Person person = new Person((String) event.get("body")); dynamoDb.getTable(DYNAMODB_TABLE_NAME) - .putItem(new PutItemSpec().withItem(new Item().withNumber("id", person.getId()) - .withString("firstName", person.getFirstName()) - .withString("lastName", person.getLastName()).withNumber("age", person.getAge()) - .withString("address", person.getAddress()))); + .putItem(new PutItemSpec().withItem(new Item().withNumber("id", person.getId()) + .withString("name", person.getName()))); } JSONObject responseBody = new JSONObject(); @@ -61,8 +59,7 @@ public class APIDemoHandler implements RequestStreamHandler { writer.close(); } - public void handleGetByPathParam(InputStream inputStream, OutputStream outputStream, Context context) - throws IOException { + public void handleGetByParam(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); JSONObject responseJson = new JSONObject(); @@ -81,61 +78,20 @@ public class APIDemoHandler implements RequestStreamHandler { if (pps.get("id") != null) { int id = Integer.parseInt((String) pps.get("id")); - result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id); + result = dynamoDb.getTable(DYNAMODB_TABLE_NAME) + .getItem("id", id); } - } - if (result != null) { - - Person person = new Person(result.toJSON()); - responseBody.put("Person", person); - responseJson.put("statusCode", 200); - } else { - - responseBody.put("message", "No item found"); - responseJson.put("statusCode", 404); - } - - JSONObject headerJson = new JSONObject(); - headerJson.put("x-custom-header", "my custom header value"); - - responseJson.put("headers", headerJson); - responseJson.put("body", responseBody.toString()); - - } catch (ParseException pex) { - responseJson.put("statusCode", 400); - responseJson.put("exception", pex); - } - - OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8"); - writer.write(responseJson.toString()); - writer.close(); - } - - public void handleGetByQueryParam(InputStream inputStream, OutputStream outputStream, Context context) - throws IOException { - - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - JSONObject responseJson = new JSONObject(); - - AmazonDynamoDB client = AmazonDynamoDBClientBuilder.defaultClient(); - DynamoDB dynamoDb = new DynamoDB(client); - - Item result = null; - try { - JSONObject event = (JSONObject) parser.parse(reader); - JSONObject responseBody = new JSONObject(); - - if (event.get("queryStringParameters") != null) { + } else if (event.get("queryStringParameters") != null) { JSONObject qps = (JSONObject) event.get("queryStringParameters"); if (qps.get("id") != null) { int id = Integer.parseInt((String) qps.get("id")); - result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id); + result = dynamoDb.getTable(DYNAMODB_TABLE_NAME) + .getItem("id", id); } } - if (result != null) { Person person = new Person(result.toJSON()); @@ -145,7 +101,7 @@ public class APIDemoHandler implements RequestStreamHandler { responseBody.put("message", "No item found"); responseJson.put("statusCode", 404); - } + } JSONObject headerJson = new JSONObject(); headerJson.put("x-custom-header", "my custom header value"); @@ -162,5 +118,4 @@ public class APIDemoHandler implements RequestStreamHandler { writer.write(responseJson.toString()); writer.close(); } - } diff --git a/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java b/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java index df00994651..9d5a371ab5 100644 --- a/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java +++ b/aws-lambda/src/main/java/com/baeldung/lambda/apigateway/model/Person.java @@ -6,19 +6,13 @@ import com.google.gson.GsonBuilder; public class Person { private int id; - private String firstName; - private String lastName; - private int age; - private String address; + private String name; public Person(String json) { Gson gson = new Gson(); Person request = gson.fromJson(json, Person.class); this.id = request.getId(); - this.firstName = request.getFirstName(); - this.lastName = request.getLastName(); - this.age = request.getAge(); - this.address = request.getAddress(); + this.name = request.getName(); } public String toString() { @@ -34,35 +28,11 @@ public class Person { this.id = id; } - public String getFirstName() { - return firstName; + public String getName() { + return name; } - public void setFirstName(String firstName) { - this.firstName = firstName; + public void setName(String name) { + this.name = name; } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } } diff --git a/aws-lambda/src/main/resources/logback.xml b/aws-lambda/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/aws-lambda/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/aws/.gitignore b/aws/.gitignore index b83d22266a..bf11a4cc38 100644 --- a/aws/.gitignore +++ b/aws/.gitignore @@ -1 +1,2 @@ /target/ +.idea/ \ No newline at end of file diff --git a/aws/README.md b/aws/README.md index d23937a419..2c61928095 100644 --- a/aws/README.md +++ b/aws/README.md @@ -9,4 +9,4 @@ - [Integration Testing with a Local DynamoDB Instance](http://www.baeldung.com/dynamodb-local-integration-tests) - [Using the JetS3t Java Client With Amazon S3](http://www.baeldung.com/jets3t-amazon-s3) - [Managing Amazon SQS Queues in Java](http://www.baeldung.com/aws-queues-java) - +- [Guide to AWS Aurora RDS with Java](https://www.baeldung.com/aws-aurora-rds-java) diff --git a/aws/pom.xml b/aws/pom.xml index 7cd16db802..ab63f6afa1 100644 --- a/aws/pom.xml +++ b/aws/pom.xml @@ -1,5 +1,5 @@ + 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 aws @@ -19,13 +19,7 @@ aws-java-sdk ${aws-java-sdk.version} - - junit - junit - ${junit.version} - test - - + org.mockito mockito-core ${mockito-core.version} @@ -106,26 +100,6 @@ - - - org.apache.maven.plugins - maven-dependency-plugin - ${maven-dependency-plugin.version} - - - copy-dependencies - test-compile - - copy-dependencies - - - test - so,dll,dylib - ${project.basedir}/native-libs - - - - @@ -143,15 +117,13 @@ 1.1.0 2.8.0 1.11.290 - 4.12 - 2.8.9 + 2.21.0 3.8.0 1.11.86 https://s3-us-west-2.amazonaws.com/dynamodb-local/release 1.10.L001 0.9.4.0006L 3.0.0 - 2.10 \ No newline at end of file diff --git a/aws/src/main/java/com/baeldung/rds/AWSRDSService.java b/aws/src/main/java/com/baeldung/rds/AWSRDSService.java new file mode 100644 index 0000000000..d4da92f30f --- /dev/null +++ b/aws/src/main/java/com/baeldung/rds/AWSRDSService.java @@ -0,0 +1,184 @@ +package com.baeldung.rds; + +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.rds.AmazonRDS; +import com.amazonaws.services.rds.AmazonRDSClientBuilder; +import com.amazonaws.services.rds.model.*; + +import java.io.IOException; +import java.io.InputStream; +import java.sql.*; +import java.util.List; +import java.util.Properties; +import java.util.UUID; +import java.util.logging.Logger; + +public class AWSRDSService { + + + final static Logger logger = Logger.getLogger(AWSRDSService.class.getName()); + private AWSCredentialsProvider credentials; + private AmazonRDS amazonRDS; + private String db_username; + private String db_password; + private String db_database; + private String db_hostname; + + /* + * User access key and secret key must be set before execute any operation. + * Follow the link on how to get the user access and secret key + * https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/ + * **/ + public AWSRDSService() throws IOException { + //Init RDS client with credentials and region. + credentials = new + AWSStaticCredentialsProvider(new + BasicAWSCredentials("", + "")); + amazonRDS = AmazonRDSClientBuilder.standard().withCredentials(credentials) + .withRegion(Regions.AP_SOUTHEAST_2).build(); + Properties prop = new Properties(); + InputStream input = AWSRDSService.class.getClassLoader().getResourceAsStream("db.properties"); + prop.load(input); + db_username = prop.getProperty("db_username"); + db_password = prop.getProperty("db_password"); + db_database = prop.getProperty("db_database"); + } + + public AWSRDSService(AmazonRDS amazonRDS){ + this.amazonRDS = amazonRDS; + } + + /** + * create the RDS instance. + * After instance creation, update the db_hostname with endpoint in db.properties. + * */ + + public String launchInstance() { + + String identifier = ""; + CreateDBInstanceRequest request = new CreateDBInstanceRequest(); + // RDS instance name + request.setDBInstanceIdentifier("Sydney"); + request.setEngine("postgres"); + request.setMultiAZ(false); + request.setMasterUsername(db_username); + request.setMasterUserPassword(db_password); + request.setDBName(db_database); + request.setStorageType("gp2"); + request.setAllocatedStorage(10); + + DBInstance instance = amazonRDS.createDBInstance(request); + + // Information about the new RDS instance + identifier = instance.getDBInstanceIdentifier(); + String status = instance.getDBInstanceStatus(); + Endpoint endpoint = instance.getEndpoint(); + String endpoint_url = "Endpoint URL not available yet."; + if (endpoint != null) { + endpoint_url = endpoint.toString(); + } + logger.info(identifier + "\t" + status); + logger.info(endpoint_url); + + return identifier; + + } + + // Describe DB instances + public void listInstances() { + DescribeDBInstancesResult result = amazonRDS.describeDBInstances(); + List instances = result.getDBInstances(); + for (DBInstance instance : instances) { + // Information about each RDS instance + String identifier = instance.getDBInstanceIdentifier(); + String engine = instance.getEngine(); + String status = instance.getDBInstanceStatus(); + Endpoint endpoint = instance.getEndpoint(); + String endpoint_url = "Endpoint URL not available yet."; + if (endpoint != null) { + endpoint_url = endpoint.toString(); + } + logger.info(identifier + "\t" + engine + "\t" + status); + logger.info("\t" + endpoint_url); + } + + } + + //Delete RDS instance + public void terminateInstance(String identifier) { + + DeleteDBInstanceRequest request = new DeleteDBInstanceRequest(); + request.setDBInstanceIdentifier(identifier); + request.setSkipFinalSnapshot(true); + + // Delete the RDS instance + DBInstance instance = amazonRDS.deleteDBInstance(request); + + // Information about the RDS instance being deleted + String status = instance.getDBInstanceStatus(); + Endpoint endpoint = instance.getEndpoint(); + String endpoint_url = "Endpoint URL not available yet."; + if (endpoint != null) { + endpoint_url = endpoint.toString(); + } + + logger.info(identifier + "\t" + status); + logger.info(endpoint_url); + + } + + + public void runJdbcTests() throws SQLException, IOException { + + // Getting database properties from db.properties + Properties prop = new Properties(); + InputStream input = AWSRDSService.class.getClassLoader().getResourceAsStream("db.properties"); + prop.load(input); + db_hostname = prop.getProperty("db_hostname"); + String jdbc_url = "jdbc:postgresql://" + db_hostname + ":5432/" + db_database; + + // Create a connection using the JDBC driver + try (Connection conn = DriverManager.getConnection(jdbc_url, db_username, db_password)) { + + // Create the test table if not exists + Statement statement = conn.createStatement(); + String sql = "CREATE TABLE IF NOT EXISTS jdbc_test (id SERIAL PRIMARY KEY, content VARCHAR(80))"; + statement.executeUpdate(sql); + + // Do some INSERT + PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO jdbc_test (content) VALUES (?)"); + String content = "" + UUID.randomUUID(); + preparedStatement.setString(1, content); + preparedStatement.executeUpdate(); + logger.info("INSERT: " + content); + + // Do some SELECT + sql = "SELECT * FROM jdbc_test"; + ResultSet resultSet = statement.executeQuery(sql); + while (resultSet.next()) { + String count = resultSet.getString("content"); + logger.info("Total Records: " + count); + } + } + + + } + + public static void main(String[] args) throws IOException, SQLException { + AWSRDSService awsrdsService = new AWSRDSService(); + + String instanceName = awsrdsService.launchInstance(); + + //Add some wait for instance creation. + + awsrdsService.listInstances(); + + awsrdsService.runJdbcTests(); + + awsrdsService.terminateInstance(instanceName); + } +} diff --git a/aws/src/main/resources/db.properties b/aws/src/main/resources/db.properties new file mode 100644 index 0000000000..e934611a2b --- /dev/null +++ b/aws/src/main/resources/db.properties @@ -0,0 +1,4 @@ +db_hostname= +db_username=username +db_password=password +db_database=mydb \ No newline at end of file diff --git a/aws/src/main/resources/logback.xml b/aws/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/aws/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/axon/pom.xml b/axon/pom.xml index 8d5636277a..915a04feb5 100644 --- a/axon/pom.xml +++ b/axon/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 axon diff --git a/axon/src/main/resources/logback.xml b/axon/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/axon/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/azure/pom.xml b/azure/pom.xml index c5175a4fec..555efeef70 100644 --- a/azure/pom.xml +++ b/azure/pom.xml @@ -1,8 +1,7 @@ + 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 azure 0.1 @@ -17,11 +16,6 @@ ../parent-boot-2 - - baeldungadr - ${azure.containerRegistry}.azurecr.io - - org.springframework.boot @@ -42,12 +36,13 @@ com.h2database h2 + runtime mysql mysql-connector-java - 5.1.6 + runtime @@ -61,7 +56,7 @@ com.spotify docker-maven-plugin - 1.1.0 + {docker-maven-plugin.version} ${docker.image.prefix}/${project.artifactId} https://${docker.image.prefix} @@ -79,7 +74,7 @@ com.microsoft.azure azure-webapp-maven-plugin - 1.1.0 + ${azure-webapp-maven-plugin.version} azure-auth @@ -87,45 +82,52 @@ baeldung-group baeldung-webapp baeldung-plan - 1.8 - - - - - - - + {java.version} + + + + + + + spring.datasource.url jdbc:h2:file:~/test - + spring.datasource.username sa - + spring.datasource.password - + - - - - - - - - - - + + + + + + + + + + + + baeldungadr + ${azure.containerRegistry}.azurecr.io + 1.1.0 + 1.1.0 + 1.8 + diff --git a/azure/src/main/resources/logback.xml b/azure/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/azure/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/bootique/pom.xml b/bootique/pom.xml index 89ef2b4b5b..880b9a516f 100644 --- a/bootique/pom.xml +++ b/bootique/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung.bootique bootique @@ -52,16 +52,21 @@ + org.apache.maven.plugins maven-shade-plugin + ${maven-shade-plugin.version} + com.baeldung.bootique.App 0.23 + + 2.4.3 \ No newline at end of file diff --git a/bootique/src/main/resources/logback.xml b/bootique/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/bootique/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/cas/cas-secured-app/pom.xml b/cas/cas-secured-app/pom.xml index 332ee912b6..2291da9084 100644 --- a/cas/cas-secured-app/pom.xml +++ b/cas/cas-secured-app/pom.xml @@ -1,19 +1,17 @@ + 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 cas-secured-app - 0.0.1-SNAPSHOT jar cas-secured-app - Demo project for Spring Boot + Demo project for CAS - org.springframework.boot - spring-boot-starter-parent - 1.5.13.RELEASE - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-1 @@ -60,10 +58,4 @@ - - UTF-8 - UTF-8 - 1.8 - - diff --git a/cas/cas-secured-app/src/main/resources/logback.xml b/cas/cas-secured-app/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/cas/cas-secured-app/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/cas/cas-server/pom.xml b/cas/cas-server/pom.xml index 52ddba1a68..9b61aaec3d 100644 --- a/cas/cas-server/pom.xml +++ b/cas/cas-server/pom.xml @@ -1,29 +1,34 @@ - + 4.0.0 - com.baeldung cas-server war 1.0 + + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-1 + - org.apereo.cas - cas-server-support-json-service-registry - ${cas.version} - - - org.apereo.cas - cas-server-support-jdbc - ${cas.version} - - - org.apereo.cas - cas-server-support-jdbc-drivers - ${cas.version} - + org.apereo.cas + cas-server-support-json-service-registry + ${cas.version} + + + org.apereo.cas + cas-server-support-jdbc + ${cas.version} + + + org.apereo.cas + cas-server-support-jdbc-drivers + ${cas.version} + @@ -31,7 +36,7 @@ com.rimerosolutions.maven.plugins wrapper-maven-plugin - 0.0.4 + ${wrapper-maven-plugin.version} true MD5 @@ -40,7 +45,6 @@ org.springframework.boot spring-boot-maven-plugin - ${springboot.version} ${mainClassName} true @@ -58,7 +62,7 @@ org.apache.maven.plugins maven-war-plugin - 2.6 + ${maven-war-plugin.version} cas false @@ -75,57 +79,10 @@ - - org.apache.maven.plugins - maven-compiler-plugin - 3.3 - cas - - 5.3.0-SNAPSHOT - 1.5.13.RELEASE - - -tomcat - - org.springframework.boot.loader.WarLauncher - false - ${project.build.directory}/war/work/org.apereo.cas/cas-server-webapp${app.server}/META-INF/MANIFEST.MF - - 1.8 - 1.8 - UTF-8 - - - - - sonatype-releases - http://oss.sonatype.org/content/repositories/releases/ - - false - - - true - - - - sonatype-snapshots - https://oss.sonatype.org/content/repositories/snapshots/ - - true - - - false - - - - shibboleth-releases - https://build.shibboleth.net/nexus/content/repositories/releases - - - @@ -140,9 +97,7 @@ war runtime - + @@ -161,7 +116,7 @@ com.soebes.maven.plugins echo-maven-plugin - 0.3.0 + ${echo-maven-plugin.version} prepare-package @@ -210,7 +165,7 @@ com.github.s4u.plugins pgpverify-maven-plugin - 1.1.0 + ${pgpverify-maven-plugin.version} @@ -230,4 +185,22 @@ + + + 5.3.3 + + -tomcat + + org.springframework.boot.loader.WarLauncher + false + ${project.build.directory}/war/work/org.apereo.cas/cas-server-webapp${app.server}/META-INF/MANIFEST.MF + + 0.0.4 + 2.6 + 3.3 + + 0.3.0 + 1.1.0 + + diff --git a/cdi-portable-extension/flyway-cdi/pom.xml b/cdi-portable-extension/flyway-cdi/pom.xml new file mode 100644 index 0000000000..9fb781aaab --- /dev/null +++ b/cdi-portable-extension/flyway-cdi/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + flyway-cdi + + + com.baeldung + cdi-portable-extension + 1.0-SNAPSHOT + + + + + javax.enterprise + cdi-api + 2.0.SP1 + + + org.flywaydb + flyway-core + 5.1.4 + + + org.apache.tomcat + tomcat-jdbc + 8.5.33 + + + javax.annotation + javax.annotation-api + 1.3.2 + + + + diff --git a/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java b/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java new file mode 100644 index 0000000000..a5019b82c1 --- /dev/null +++ b/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java @@ -0,0 +1,74 @@ +package com.baeldung.cdi.extension; + +import org.apache.tomcat.jdbc.pool.DataSource; +import org.flywaydb.core.Flyway; + +import javax.annotation.sql.DataSourceDefinition; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Default; +import javax.enterprise.inject.literal.InjectLiteral; +import javax.enterprise.inject.spi.*; +import javax.enterprise.util.AnnotationLiteral; + + +/** + * Flyway is now under CDI container like: + * + * @ApplicationScoped + * @FlywayType public class Flyway{ + * @Inject setDataSource(DataSource dataSource){ + * //... + * } + * } + */ + +public class FlywayExtension implements Extension { + + DataSourceDefinition dataSourceDefinition = null; + + public void registerFlywayType(@Observes BeforeBeanDiscovery bbdEvent) { + bbdEvent.addAnnotatedType(Flyway.class, Flyway.class.getName()); + } + + public void detectDataSourceDefinition(@Observes @WithAnnotations(DataSourceDefinition.class) ProcessAnnotatedType patEvent) { + AnnotatedType at = patEvent.getAnnotatedType(); + dataSourceDefinition = at.getAnnotation(DataSourceDefinition.class); + } + + public void processAnnotatedType(@Observes ProcessAnnotatedType patEvent) { + patEvent.configureAnnotatedType() + //Add Scope + .add(ApplicationScoped.Literal.INSTANCE) + //Add Qualifier + .add(new AnnotationLiteral() { + }) + //Decorate setDataSource(DataSource dataSource){} with @Inject + .filterMethods(annotatedMethod -> { + return annotatedMethod.getParameters().size() == 1 && + annotatedMethod.getParameters().get(0).getBaseType().equals(javax.sql.DataSource.class); + }) + .findFirst().get().add(InjectLiteral.INSTANCE); + } + + void afterBeanDiscovery(@Observes AfterBeanDiscovery abdEvent, BeanManager bm) { + abdEvent.addBean() + .types(javax.sql.DataSource.class, DataSource.class) + .qualifiers(new AnnotationLiteral() {}, new AnnotationLiteral() {}) + .scope(ApplicationScoped.class) + .name(DataSource.class.getName()) + .beanClass(DataSource.class) + .createWith(creationalContext -> { + DataSource instance = new DataSource(); + instance.setUrl(dataSourceDefinition.url()); + instance.setDriverClassName(dataSourceDefinition.className()); + return instance; + }); + } + + void runFlywayMigration(@Observes AfterDeploymentValidation adv, BeanManager manager) { + Flyway flyway = manager.createInstance().select(Flyway.class, new AnnotationLiteral() {}).get(); + flyway.migrate(); + } +} diff --git a/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayType.java b/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayType.java new file mode 100644 index 0000000000..7c3a5affa6 --- /dev/null +++ b/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayType.java @@ -0,0 +1,14 @@ +package com.baeldung.cdi.extension; + +import javax.inject.Qualifier; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({FIELD, METHOD, PARAMETER, TYPE}) +@Qualifier +public @interface FlywayType { +} \ No newline at end of file diff --git a/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/beans.xml b/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..44959bfa99 --- /dev/null +++ b/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 0000000000..a82dc47714 --- /dev/null +++ b/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1,2 @@ +com.baeldung.cdi.extension.FlywayExtension + diff --git a/cdi-portable-extension/main-app/pom.xml b/cdi-portable-extension/main-app/pom.xml new file mode 100644 index 0000000000..fab9b8bf07 --- /dev/null +++ b/cdi-portable-extension/main-app/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + main-app + jar + + + com.baeldung + cdi-portable-extension + 1.0-SNAPSHOT + + + + + + javax.enterprise + cdi-api + 2.0.SP1 + + + org.jboss.weld.se + weld-se-core + 3.0.5.Final + runtime + + + + com.baeldung + flyway-cdi + 1.0-SNAPSHOT + runtime + + + + com.h2database + h2 + 1.4.197 + runtime + + + + javax.annotation + javax.annotation-api + 1.3.2 + + + + + \ No newline at end of file diff --git a/cdi-portable-extension/main-app/src/main/java/com/baeldung/cdi/extension/MainApp.java b/cdi-portable-extension/main-app/src/main/java/com/baeldung/cdi/extension/MainApp.java new file mode 100644 index 0000000000..1f6c5b43ba --- /dev/null +++ b/cdi-portable-extension/main-app/src/main/java/com/baeldung/cdi/extension/MainApp.java @@ -0,0 +1,16 @@ +package com.baeldung.cdi.extension; + +import javax.annotation.sql.DataSourceDefinition; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.se.SeContainer; +import javax.enterprise.inject.se.SeContainerInitializer; + +@ApplicationScoped +@DataSourceDefinition(name = "ds", className = "org.h2.Driver", url = "jdbc:h2:mem:testdb") +public class MainApp { + public static void main(String[] args) { + SeContainerInitializer initializer = SeContainerInitializer.newInstance(); + try (SeContainer container = initializer.initialize()) { + } + } +} \ No newline at end of file diff --git a/cdi-portable-extension/main-app/src/main/resources/META-INF/beans.xml b/cdi-portable-extension/main-app/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..44959bfa99 --- /dev/null +++ b/cdi-portable-extension/main-app/src/main/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/cdi-portable-extension/main-app/src/main/resources/db/migration/V1__Create_person_table.sql b/cdi-portable-extension/main-app/src/main/resources/db/migration/V1__Create_person_table.sql new file mode 100644 index 0000000000..6bddc7689e --- /dev/null +++ b/cdi-portable-extension/main-app/src/main/resources/db/migration/V1__Create_person_table.sql @@ -0,0 +1,4 @@ +create table PERSON ( + ID int not null, + NAME varchar(100) not null +); diff --git a/cdi-portable-extension/main-app/src/main/resources/db/migration/V2__Add_people.sql b/cdi-portable-extension/main-app/src/main/resources/db/migration/V2__Add_people.sql new file mode 100644 index 0000000000..d8f1d62667 --- /dev/null +++ b/cdi-portable-extension/main-app/src/main/resources/db/migration/V2__Add_people.sql @@ -0,0 +1,3 @@ +insert into PERSON (ID, NAME) values (1, 'Axel'); +insert into PERSON (ID, NAME) values (2, 'Mr. Foo'); +insert into PERSON (ID, NAME) values (3, 'Ms. Bar'); diff --git a/cdi-portable-extension/pom.xml b/cdi-portable-extension/pom.xml new file mode 100644 index 0000000000..66913de84d --- /dev/null +++ b/cdi-portable-extension/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + com.baeldung + cdi-portable-extension + 1.0-SNAPSHOT + pom + + + 1.8 + 1.8 + + + + main-app + flyway-cdi + + + + + javax.enterprise + cdi-api + 2.0.SP1 + + + + \ No newline at end of file diff --git a/cdi/README.md b/cdi/README.md index a27c35772a..0477ce85bd 100644 --- a/cdi/README.md +++ b/cdi/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [CDI Interceptor vs Spring AspectJ](http://www.baeldung.com/cdi-interceptor-vs-spring-aspectj) +- [An Introduction to CDI (Contexts and Dependency Injection) in Java](http://www.baeldung.com/java-ee-cdi) diff --git a/cdi/pom.xml b/cdi/pom.xml index 1d14e3c267..2c719c1d7f 100644 --- a/cdi/pom.xml +++ b/cdi/pom.xml @@ -17,19 +17,19 @@ org.hamcrest hamcrest-core - 1.3 + ${hamcrest-core.version} test org.assertj assertj-core - 3.10.0 + ${assertj-core.version} test junit junit - 4.12 + ${junit.version} test @@ -58,6 +58,9 @@ 1.8.9 2.4.1.Final + 1.3 + 3.10.0 + 4.12 diff --git a/cdi/src/main/resources/logback.xml b/cdi/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/cdi/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/cdi/src/test/java/com/baeldung/test/dependencyinjection/ImageProcessorUnitTest.java b/cdi/src/test/java/com/baeldung/test/dependencyinjection/ImageProcessorUnitTest.java index 8b5fa409c9..930e913109 100644 --- a/cdi/src/test/java/com/baeldung/test/dependencyinjection/ImageProcessorUnitTest.java +++ b/cdi/src/test/java/com/baeldung/test/dependencyinjection/ImageProcessorUnitTest.java @@ -1,70 +1,91 @@ package com.baeldung.test.dependencyinjection; -import com.baeldung.dependencyinjection.imagefileeditors.GifFileEditor; -import com.baeldung.dependencyinjection.imagefileeditors.JpgFileEditor; -import com.baeldung.dependencyinjection.imagefileeditors.PngFileEditor; -import com.baeldung.dependencyinjection.imageprocessors.ImageFileProcessor; -import com.baeldung.dependencyinjection.loggers.TimeLogger; -import java.text.SimpleDateFormat; -import java.util.Calendar; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.within; + +import java.text.ParseException; +import java.time.LocalTime; +import java.time.temporal.ChronoUnit; + import org.jboss.weld.environment.se.Weld; import org.jboss.weld.environment.se.WeldContainer; import org.junit.BeforeClass; import org.junit.Test; +import com.baeldung.dependencyinjection.imagefileeditors.PngFileEditor; +import com.baeldung.dependencyinjection.imageprocessors.ImageFileProcessor; +import com.baeldung.dependencyinjection.loggers.TimeLogger; + public class ImageProcessorUnitTest { - + private static ImageFileProcessor imageFileProcessor; - private static SimpleDateFormat dateFormat; - private static Calendar calendar; - - + @BeforeClass public static void setImageProcessorInstance() { Weld weld = new Weld(); WeldContainer container = weld.initialize(); - imageFileProcessor = container.select(ImageFileProcessor.class).get(); + imageFileProcessor = container.select(ImageFileProcessor.class) + .get(); container.shutdown(); } - - @BeforeClass - public static void setSimpleDateFormatInstance() { - dateFormat = new SimpleDateFormat("HH:mm"); - } - - @BeforeClass - public static void setCalendarInstance() { - calendar = Calendar.getInstance(); - } - + @Test public void givenImageProcessorInstance_whenInjectedPngFileEditorandTimeLoggerInstances_thenTwoAssertions() { assertThat(imageFileProcessor.getImageFileditor()).isInstanceOf(PngFileEditor.class); assertThat(imageFileProcessor.getTimeLogger()).isInstanceOf(TimeLogger.class); } - + @Test - public void givenImageProcessorInstance_whenCalledopenFile_thenOneAssertion() { - String currentTime = dateFormat.format(calendar.getTime()); - assertThat(imageFileProcessor.openFile("file1.png")).isEqualTo("Opening PNG file file1.png at: " + currentTime); + public void givenImageProcessorInstance_whenCalledopenFile_thenOneAssertion() throws ParseException { + LocalTime currentTime = LocalTime.now(); + + String openFileLog = imageFileProcessor.openFile("file1.png"); + assertThat(openFileLog).contains("Opening PNG file file1.png at: "); + + LocalTime loggedTime = getLoggedTime(openFileLog); + assertThat(loggedTime).isCloseTo(currentTime, within(2, ChronoUnit.MINUTES)); } - + @Test - public void givenImageProcessorInstance_whenCallededitFile_thenOneAssertion() { - String currentTime = dateFormat.format(calendar.getTime()); - assertThat(imageFileProcessor.editFile("file1.png")).isEqualTo("Editing PNG file file1.png at: " + currentTime); + public void givenImageProcessorInstance_whenCallededitFile_thenOneAssertion() throws ParseException { + LocalTime currentTime = LocalTime.now(); + + String editFileLog = imageFileProcessor.editFile("file1.png"); + assertThat(editFileLog).contains("Editing PNG file file1.png at: "); + + LocalTime loggedTime = getLoggedTime(editFileLog); + assertThat(loggedTime).isCloseTo(currentTime, within(2, ChronoUnit.MINUTES)); } - + @Test - public void givenImageProcessorInstance_whenCalledwriteFile_thenOneAssertion() { - String currentTime = dateFormat.format(calendar.getTime()); - assertThat(imageFileProcessor.writeFile("file1.png")).isEqualTo("Writing PNG file file1.png at: " + currentTime); + public void givenImageProcessorInstance_whenCalledwriteFile_thenOneAssertion() throws ParseException { + LocalTime currentTime = LocalTime.now(); + + String writeFileLog = imageFileProcessor.writeFile("file1.png"); + assertThat(writeFileLog).contains("Writing PNG file file1.png at: "); + + LocalTime loggedTime = getLoggedTime(writeFileLog); + assertThat(loggedTime).isCloseTo(currentTime, within(2, ChronoUnit.MINUTES)); } - + @Test - public void givenImageProcessorInstance_whenCalledsaveFile_thenOneAssertion() { - String currentTime = dateFormat.format(calendar.getTime()); - assertThat(imageFileProcessor.saveFile("file1.png")).isEqualTo("Saving PNG file file1.png at: " + currentTime); + public void givenImageProcessorInstance_whenCalledsaveFile_thenOneAssertion() throws ParseException { + LocalTime currentTime = LocalTime.now(); + + String saveFileLog = imageFileProcessor.saveFile("file1.png"); + assertThat(saveFileLog).contains("Saving PNG file file1.png at: "); + + LocalTime loggedTime = getLoggedTime(saveFileLog); + assertThat(loggedTime).isCloseTo(currentTime, within(2, ChronoUnit.MINUTES)); + } + + private LocalTime getLoggedTime(String log) throws ParseException { + String logTimeString = log.split("at: ")[1]; + + int hour = Integer.valueOf(logTimeString.split(":")[0]); + int minutes = Integer.valueOf(logTimeString.split(":")[1]); + + LocalTime loggedTime = LocalTime.of(hour, minutes); + return loggedTime; } } \ No newline at end of file diff --git a/checker-plugin/pom.xml b/checker-plugin/pom.xml index 01d7a30bfd..45f0939e77 100644 --- a/checker-plugin/pom.xml +++ b/checker-plugin/pom.xml @@ -41,33 +41,12 @@ - - - org.apache.maven.plugins - maven-dependency-plugin - - - - - properties - - - - - maven-compiler-plugin ${maven-compiler-plugin.version} - ${maven.compiler.source} - ${maven.compiler.target} + ${java.version} + ${java.version} @@ -113,8 +92,6 @@ 2.3.1 2.3.1 2.3.1 - 1.8 - 1.8 diff --git a/checker-plugin/src/main/resources/logback.xml b/checker-plugin/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/checker-plugin/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-groovy/pom.xml b/core-groovy/pom.xml index 9076e63642..909250710e 100644 --- a/core-groovy/pom.xml +++ b/core-groovy/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-groovy 1.0-SNAPSHOT @@ -101,24 +101,13 @@ - UTF-8 - 1.1.2 - 1.1.2 - 1.1.2 - 1.1.2 - 0.15 - 1.5.0 - 5.0.0 1.0.0 - 4.12.0 - 4.12 2.4.13 2.4.13 2.4.13 2.4.0 1.1-groovy-2.4 1.6 - 2.19.1 diff --git a/core-groovy/src/main/resources/logback.xml b/core-groovy/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-groovy/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-10/README.md b/core-java-10/README.md index 863448c194..84fa381a26 100644 --- a/core-java-10/README.md +++ b/core-java-10/README.md @@ -3,3 +3,4 @@ - [Java 10 LocalVariable Type-Inference](http://www.baeldung.com/java-10-local-variable-type-inference) - [Guide to Java 10](http://www.baeldung.com/java-10-overview) +- [Copy a List to Another List in Java](http://www.baeldung.com/java-copy-list-to-another) diff --git a/core-java-10/pom.xml b/core-java-10/pom.xml index 8a19893b13..9fcdd9a162 100644 --- a/core-java-10/pom.xml +++ b/core-java-10/pom.xml @@ -1,45 +1,36 @@ - 4.0.0 - com.baeldung - core-java-10 - jar - 0.1.0-SNAPSHOT - core-java-10 - http://maven.apache.org + 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 + core-java-10 + jar + 0.1.0-SNAPSHOT + core-java-10 + http://maven.apache.org - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + - - - junit - junit - ${junit.version} - test - - + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source.version} + ${maven.compiler.target.version} + + + + - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source.version} - ${maven.compiler.target.version} - - - - - - - 10 - 10 - + + 10 + 10 + diff --git a/core-java-10/src/main/resources/logback.xml b/core-java-10/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-java-10/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-10/src/test/java/com/baeldung/java10/list/CopyListServiceUnitTest.java b/core-java-10/src/test/java/com/baeldung/java10/list/CopyListServiceUnitTest.java new file mode 100644 index 0000000000..f529e219a6 --- /dev/null +++ b/core-java-10/src/test/java/com/baeldung/java10/list/CopyListServiceUnitTest.java @@ -0,0 +1,14 @@ +package com.baeldung.java10.list; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +public class CopyListServiceUnitTest { + + @Test(expected = UnsupportedOperationException.class) + public void whenModifyCopyOfList_thenThrowsException() { + List copyList = List.copyOf(Arrays.asList(1, 2, 3, 4)); + } +} diff --git a/core-java-11/pom.xml b/core-java-11/pom.xml index 5cdb5c0640..4dcab49867 100644 --- a/core-java-11/pom.xml +++ b/core-java-11/pom.xml @@ -1,45 +1,36 @@ - 4.0.0 - com.baeldung - core-java-11 - jar - 0.1.0-SNAPSHOT - core-java-11 - http://maven.apache.org + 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 + core-java-11 + jar + 0.1.0-SNAPSHOT + core-java-11 + http://maven.apache.org - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + - - - junit - junit - ${junit.version} - test - - + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source.version} + ${maven.compiler.target.version} + + + + - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source.version} - ${maven.compiler.target.version} - - - - - - - 11 - 11 - + + 11 + 11 + diff --git a/core-java-11/src/main/resources/logback.xml b/core-java-11/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-java-11/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-8/README.md b/core-java-8/README.md index aa6110b7b1..64d423aafe 100644 --- a/core-java-8/README.md +++ b/core-java-8/README.md @@ -9,48 +9,26 @@ - [Java 8 New Features](http://www.baeldung.com/java-8-new-features) - [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips) - [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator) -- [Java 8 Streams Advanced](http://www.baeldung.com/java-8-streams) -- [Introduction to Java 8 Streams](http://www.baeldung.com/java-8-streams-introduction) - [Guide to Java 8 groupingBy Collector](http://www.baeldung.com/java-groupingby-collector) - [Strategy Design Pattern in Java 8](http://www.baeldung.com/java-strategy-pattern) -- [Java 8 and Infinite Streams](http://www.baeldung.com/java-inifinite-streams) -- [String Operations with Java Streams](http://www.baeldung.com/java-stream-operations-on-strings) - [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions) -- [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany) - [Guide to Java 8 Comparator.comparing()](http://www.baeldung.com/java-8-comparator-comparing) -- [How to Get the Last Element of a Stream in Java?](http://www.baeldung.com/java-stream-last-element) -- [Introduction to the Java 8 Date/Time API](http://www.baeldung.com/java-8-date-time-intro) -- [Migrating to the New Java 8 Date Time API](http://www.baeldung.com/migrating-to-java-8-date-time-api) - [Guide To Java 8 Optional](http://www.baeldung.com/java-optional) - [Guide to the Java 8 forEach](http://www.baeldung.com/foreach-java) -- [Get the Current Date, Time and Timestamp in Java 8](http://www.baeldung.com/current-date-time-and-timestamp-in-java-8) -- [TemporalAdjuster in Java](http://www.baeldung.com/java-temporal-adjuster) -- [Finding Max/Min of a List or Collection](http://www.baeldung.com/java-collection-min-max) - [Java Base64 Encoding and Decoding](http://www.baeldung.com/java-base64-encode-and-decode) - [The Difference Between map() and flatMap()](http://www.baeldung.com/java-difference-map-and-flatmap) -- [Merging Streams in Java](http://www.baeldung.com/java-merge-streams) -- [“Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception) -- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones) -- [Copy a File with Java](http://www.baeldung.com/java-copy-file) -- [Generating Prime Numbers in Java](http://www.baeldung.com/java-generate-prime-numbers) - [Static and Default Methods in Interfaces in Java](http://www.baeldung.com/java-static-default-methods) -- [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream) -- [Converting String to Stream of chars](http://www.baeldung.com/java-string-to-stream) -- [How to Iterate Over a Stream With Indices](http://www.baeldung.com/java-stream-indices) - [Efficient Word Frequency Calculator in Java](http://www.baeldung.com/java-word-frequency) -- [Primitive Type Streams in Java 8](http://www.baeldung.com/java-8-primitive-streams) -- [Fail-Safe Iterator vs Fail-Fast Iterator](http://www.baeldung.com/java-fail-safe-vs-fail-fast-iterator) -- [Shuffling Collections In Java](http://www.baeldung.com/java-shuffle-collection) -- [Java 8 StringJoiner](http://www.baeldung.com/java-string-joiner) - [Introduction to Spliterator in Java](http://www.baeldung.com/java-spliterator) - [Java 8 Math New Methods](http://www.baeldung.com/java-8-math) - [Overview of Java Built-in Annotations](http://www.baeldung.com/java-default-annotations) - [Finding Min/Max in an Array with Java](http://www.baeldung.com/java-array-min-max) - [Internationalization and Localization in Java 8](http://www.baeldung.com/java-8-localization) -- [Filtering Kotlin Collections](http://www.baeldung.com/kotlin-filter-collection) -- [How to Find an Element in a List with Java](http://www.baeldung.com/find-list-element-java) -- [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) - [Java 8 Unsigned Arithmetic Support](http://www.baeldung.com/java-unsigned-arithmetic) +- [Generalized Target-Type Inference in Java](http://www.baeldung.com/java-generalized-target-type-inference) +- [Overriding System Time for Testing in Java](http://www.baeldung.com/java-override-system-time) +- [Set the Time Zone of a Date in Java](https://www.baeldung.com/java-set-date-time-zone) +- [An Overview of Regular Expressions Performance in Java](https://www.baeldung.com/java-regex-performance) +- [Java Primitives versus Objects](https://www.baeldung.com/java-primitives-vs-objects) diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml index 20db1e1146..18bdaa15f4 100644 --- a/core-java-8/pom.xml +++ b/core-java-8/pom.xml @@ -1,5 +1,5 @@ + 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 core-java-8 @@ -10,8 +10,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java @@ -90,9 +90,19 @@ ${vavr.version} - one.util - streamex - ${streamex.version} + joda-time + joda-time + ${joda.version} + + + org.aspectj + aspectjrt + ${asspectj.version} + + + org.aspectj + aspectjweaver + ${asspectj.version} @@ -108,106 +118,18 @@ org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - - - - org.apache.maven.plugins - maven-jar-plugin + maven-compiler-plugin + 3.1 - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - + 1.8 + 1.8 + -parameters - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - - 1.8 - 1.8 - -parameters - - org.springframework.boot spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} @@ -225,22 +147,21 @@ - 21.0 3.5 3.6.1 - 2.5 4.1 4.01 1.10 1.16.12 0.9.0 1.13 - 0.6.5 + 2.10 3.6.1 + 1.8.9 1.7.0 1.19 1.19 + 2.0.4.RELEASE - - \ No newline at end of file + diff --git a/core-java-8/src/main/java/com/baeldung/aspect/ChangeCallsToCurrentTimeInMillisMethod.aj b/core-java-8/src/main/java/com/baeldung/aspect/ChangeCallsToCurrentTimeInMillisMethod.aj new file mode 100644 index 0000000000..b28bebfdaf --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/aspect/ChangeCallsToCurrentTimeInMillisMethod.aj @@ -0,0 +1,9 @@ +package com.baeldung.aspect; + +public aspect ChangeCallsToCurrentTimeInMillisMethod { + long around(): + call(public static native long java.lang.System.currentTimeMillis()) + && within(user.code.base.pckg.*) { + return 0; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/list/Flower.java b/core-java-8/src/main/java/com/baeldung/list/Flower.java new file mode 100644 index 0000000000..29c6a78326 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/list/Flower.java @@ -0,0 +1,28 @@ +package com.baeldung.list; + +public class Flower { + + private String name; + private int petals; + + public Flower(String name, int petals) { + this.name = name; + this.petals = petals; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getPetals() { + return petals; + } + + public void setPetals(int petals) { + this.petals = petals; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java b/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java new file mode 100644 index 0000000000..7587cc6834 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java @@ -0,0 +1,19 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.stream.Stream; +import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; + +public class NullSafeCollectionStreamsUsingCommonsEmptyIfNull { + + /** + * This method shows how to make a null safe stream from a collection through the use of + * emptyIfNull() method from Apache Commons CollectionUtils library + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return emptyIfNull(collection).stream(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java b/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java new file mode 100644 index 0000000000..ae8e399d53 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java @@ -0,0 +1,21 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Stream; + +public class NullSafeCollectionStreamsUsingJava8OptionalContainer { + + /** + * This method shows how to make a null safe stream from a collection through the use of + * Java SE 8’s Optional Container + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return Optional.ofNullable(collection) + .map(Collection::stream) + .orElseGet(Stream::empty); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java b/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java new file mode 100644 index 0000000000..63b6d34f11 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java @@ -0,0 +1,20 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.stream.Stream; + +public class NullSafeCollectionStreamsUsingNullDereferenceCheck { + + /** + * This method shows how to make a null safe stream from a collection through the use of a check + * to prevent null dereferences + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return collection == null ? Stream.empty() : collection.stream(); + } + + +} diff --git a/core-java-8/src/main/java/com/baeldung/optional/PersonRepository.java b/core-java-8/src/main/java/com/baeldung/optional/PersonRepository.java new file mode 100644 index 0000000000..46018faf80 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/optional/PersonRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.optional; + +public class PersonRepository { + + public String findNameById(String id) { + return id == null ? null : "Name"; + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/BenchmarkRunner.java b/core-java-8/src/main/java/com/baeldung/primitive/BenchmarkRunner.java new file mode 100644 index 0000000000..2513ec0d03 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/BenchmarkRunner.java @@ -0,0 +1,23 @@ +package com.baeldung.primitive; + +public class BenchmarkRunner { + + public static void main(String[] args) throws Exception { + new IntPrimitiveLookup().run(); + new IntegerWrapperLookup().run(); + new FloatPrimitiveLookup().run(); + new FloatWrapperLookup().run(); + new DoublePrimitiveLookup().run(); + new DoubleWrapperLookup().run(); + new ShortPrimitiveLookup().run(); + new ShortWrapperLookup().run(); + new BooleanPrimitiveLookup().run(); + new BooleanWrapperLookup().run(); + new CharPrimitiveLookup().run(); + new CharacterWrapperLookup().run(); + new BytePrimitiveLookup().run(); + new ByteWrapperLookup().run(); + new LongPrimitiveLookup().run(); + new LongWrapperLookup().run(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/BooleanPrimitiveLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/BooleanPrimitiveLookup.java new file mode 100644 index 0000000000..2ad698eba4 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/BooleanPrimitiveLookup.java @@ -0,0 +1,45 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class BooleanPrimitiveLookup extends Lookup { + + private boolean[] elements; + private final boolean pivot = false; + + @Setup + @Override + public void prepare() { + elements = new boolean[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = true; + } + elements[s - 1] = pivot; + } + + @TearDown + @Override + public void clean() { + elements = null; + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + while (pivot != elements[index]) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return BooleanPrimitiveLookup.class.getSimpleName(); + } + + + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/BooleanWrapperLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/BooleanWrapperLookup.java new file mode 100644 index 0000000000..8d996739a8 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/BooleanWrapperLookup.java @@ -0,0 +1,45 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class BooleanWrapperLookup extends Lookup { + private Boolean[] elements; + private final boolean pivot = false; + + @Override + @Setup + public void prepare() { + elements = new Boolean[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = true; + } + elements[s - 1] = pivot; + } + + @Override + @TearDown + public void clean() { + elements = null; + } + + @Override + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + Boolean pivotWrapper = pivot; + while (!pivotWrapper.equals(elements[index])) { + index++; + } + return index; + + } + + @Override + public String getSimpleClassName() { + return BooleanWrapperLookup.class.getSimpleName(); + } + + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/BytePrimitiveLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/BytePrimitiveLookup.java new file mode 100644 index 0000000000..73eda5cf5b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/BytePrimitiveLookup.java @@ -0,0 +1,46 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class BytePrimitiveLookup extends Lookup { + + private byte[] elements; + private final byte pivot = 2; + + @Setup + @Override + public void prepare() { + byte common = 1; + elements = new byte[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @TearDown + @Override + public void clean() { + elements = null; + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + while (pivot != elements[index]) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return BytePrimitiveLookup.class.getSimpleName(); + } + + + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/ByteWrapperLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/ByteWrapperLookup.java new file mode 100644 index 0000000000..23e02315a6 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/ByteWrapperLookup.java @@ -0,0 +1,46 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class ByteWrapperLookup extends Lookup { + private Byte[] elements; + private final byte pivot = 2; + + @Override + @Setup + public void prepare() { + byte common = 1; + elements = new Byte[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @Override + @TearDown + public void clean() { + elements = null; + } + + @Override + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + Byte pivotWrapper = pivot; + while (!pivotWrapper.equals(elements[index])) { + index++; + } + return index; + + } + + @Override + public String getSimpleClassName() { + return ByteWrapperLookup.class.getSimpleName(); + } + + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/CharPrimitiveLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/CharPrimitiveLookup.java new file mode 100644 index 0000000000..a6d4be6206 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/CharPrimitiveLookup.java @@ -0,0 +1,46 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class CharPrimitiveLookup extends Lookup { + + private char[] elements; + private final char pivot = 'b'; + + @Setup + @Override + public void prepare() { + char common = 'a'; + elements = new char[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @TearDown + @Override + public void clean() { + elements = null; + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + while (pivot != elements[index]) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return CharPrimitiveLookup.class.getSimpleName(); + } + + + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/CharacterWrapperLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/CharacterWrapperLookup.java new file mode 100644 index 0000000000..9509b4a156 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/CharacterWrapperLookup.java @@ -0,0 +1,46 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class CharacterWrapperLookup extends Lookup { + private Character[] elements; + private final char pivot = 'b'; + + @Override + @Setup + public void prepare() { + char common = 'a'; + elements = new Character[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @Override + @TearDown + public void clean() { + elements = null; + } + + @Override + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + Character pivotWrapper = pivot; + while (!pivotWrapper.equals(elements[index])) { + index++; + } + return index; + + } + + @Override + public String getSimpleClassName() { + return CharacterWrapperLookup.class.getSimpleName(); + } + + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/DoublePrimitiveLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/DoublePrimitiveLookup.java new file mode 100644 index 0000000000..f95515a02d --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/DoublePrimitiveLookup.java @@ -0,0 +1,42 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class DoublePrimitiveLookup extends Lookup { + private double[] elements; + private final double pivot = 2; + + @Setup + @Override + public void prepare() { + double common = 1; + elements = new double[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @TearDown + @Override + public void clean() { + elements = null; + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + while (pivot != elements[index]) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return DoublePrimitiveLookup.class.getSimpleName(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/DoubleWrapperLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/DoubleWrapperLookup.java new file mode 100644 index 0000000000..671c2ccc29 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/DoubleWrapperLookup.java @@ -0,0 +1,45 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class DoubleWrapperLookup extends Lookup { + private Double[] elements; + private final double pivot = 2d; + + @Override + @Setup + public void prepare() { + double common = 1; + elements = new Double[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @Override + @TearDown + public void clean() { + elements = null; + } + + @Override + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + Double pivotWrapper = pivot; + while (!pivotWrapper.equals(elements[index])) { + index++; + } + return index; + + } + + @Override + public String getSimpleClassName() { + return DoubleWrapperLookup.class.getSimpleName(); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/FloatPrimitiveLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/FloatPrimitiveLookup.java new file mode 100644 index 0000000000..26b58f0053 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/FloatPrimitiveLookup.java @@ -0,0 +1,42 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class FloatPrimitiveLookup extends Lookup { + private float[] elements; + private final float pivot = 2; + + @Setup + @Override + public void prepare() { + int common = 1; + elements = new float[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @TearDown + @Override + public void clean() { + elements = null; + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + while (pivot != elements[index]) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return FloatPrimitiveLookup.class.getSimpleName(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/FloatWrapperLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/FloatWrapperLookup.java new file mode 100644 index 0000000000..8e75eae3e3 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/FloatWrapperLookup.java @@ -0,0 +1,43 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class FloatWrapperLookup extends Lookup { + private Float[] elements; + private final float pivot = 2; + + @Override + @Setup + public void prepare() { + float common = 1; + elements = new Float[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @Override + @TearDown + public void clean() { + elements = null; + } + + @Override + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + Float pivotWrapper = pivot; + while (!pivotWrapper.equals(elements[index])) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return FloatWrapperLookup.class.getSimpleName(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/IntPrimitiveLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/IntPrimitiveLookup.java new file mode 100644 index 0000000000..551163dba2 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/IntPrimitiveLookup.java @@ -0,0 +1,45 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class IntPrimitiveLookup extends Lookup { + + private int[] elements; + private final int pivot = 2; + + @Setup + @Override + public void prepare() { + int common = 1; + elements = new int[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @TearDown + @Override + public void clean() { + elements = null; + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + while (pivot != elements[index]) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return IntPrimitiveLookup.class.getSimpleName(); + } + + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/IntegerWrapperLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/IntegerWrapperLookup.java new file mode 100644 index 0000000000..f39fb80a0b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/IntegerWrapperLookup.java @@ -0,0 +1,45 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class IntegerWrapperLookup extends Lookup { + private Integer[] elements; + private final int pivot = 2; + + @Override + @Setup + public void prepare() { + int common = 1; + elements = new Integer[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @Override + @TearDown + public void clean() { + elements = null; + } + + @Override + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + Integer pivotWrapper = pivot; + while (!pivotWrapper.equals(elements[index])) { + index++; + } + return index; + + } + + @Override + public String getSimpleClassName() { + return IntegerWrapperLookup.class.getSimpleName(); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/LongPrimitiveLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/LongPrimitiveLookup.java new file mode 100644 index 0000000000..2f414577da --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/LongPrimitiveLookup.java @@ -0,0 +1,42 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class LongPrimitiveLookup extends Lookup { + private long[] elements; + private final long pivot = 2; + + @Setup + @Override + public void prepare() { + long common = 1; + elements = new long[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @TearDown + @Override + public void clean() { + elements = null; + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + while (pivot != elements[index]) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return LongPrimitiveLookup.class.getSimpleName(); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/LongWrapperLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/LongWrapperLookup.java new file mode 100644 index 0000000000..692a9fd15c --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/LongWrapperLookup.java @@ -0,0 +1,45 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class LongWrapperLookup extends Lookup{ + private Long[] elements; + private final long pivot = 2; + + @Override + @Setup + public void prepare() { + long common = 1; + elements = new Long[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @Override + @TearDown + public void clean() { + elements = null; + } + + @Override + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + Long pivotWrapper = pivot; + while (!pivotWrapper.equals(elements[index])) { + index++; + } + return index; + + } + + @Override + public String getSimpleClassName() { + return LongWrapperLookup.class.getSimpleName(); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/Lookup.java b/core-java-8/src/main/java/com/baeldung/primitive/Lookup.java new file mode 100644 index 0000000000..3dc7b7655e --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/Lookup.java @@ -0,0 +1,56 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.results.RunResult; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.Collection; + +/** + * An abstract class that is to be extended by the classes that + * perform lookup in the arrays either of Java primitive types or their wrappers. + */ +public abstract class Lookup { + /** + * the array size + */ + final protected int s = 50000000; + + /** + * Initialize the array: fill in the array with the same + * elements except for the last one. + */ + abstract public void prepare(); + + /** + * Free the array's reference. + */ + abstract public void clean(); + + /** + * Find the position of the element that is different from the others. + * By construction, it is the last array element. + * + * @return array's last element index + */ + abstract public int findPosition(); + + /** + * Get the name of the class that extends this one. It is needed in order + * to set up the benchmark. + * + * @return + */ + abstract public String getSimpleClassName(); + + Collection run() throws RunnerException { + Options opt = new OptionsBuilder() + .include(getSimpleClassName()) + .forks(1) + .build(); + return new Runner(opt).run(); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/ShortPrimitiveLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/ShortPrimitiveLookup.java new file mode 100644 index 0000000000..2d2ffbd67b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/ShortPrimitiveLookup.java @@ -0,0 +1,45 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class ShortPrimitiveLookup extends Lookup { + + private short[] elements; + private final short pivot = 2; + + @Setup + @Override + public void prepare() { + short common = 1; + elements = new short[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @TearDown + @Override + public void clean() { + elements = null; + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + while (pivot != elements[index]) { + index++; + } + return index; + } + + @Override + public String getSimpleClassName() { + return ShortPrimitiveLookup.class.getSimpleName(); + } + + +} diff --git a/core-java-8/src/main/java/com/baeldung/primitive/ShortWrapperLookup.java b/core-java-8/src/main/java/com/baeldung/primitive/ShortWrapperLookup.java new file mode 100644 index 0000000000..1c1cd4a345 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/primitive/ShortWrapperLookup.java @@ -0,0 +1,46 @@ +package com.baeldung.primitive; + +import org.openjdk.jmh.annotations.*; + +@State(Scope.Thread) +public class ShortWrapperLookup extends Lookup { + private Short[] elements; + private final short pivot = 2; + + @Override + @Setup + public void prepare() { + short common = 1; + elements = new Short[s]; + for (int i = 0; i < s - 1; i++) { + elements[i] = common; + } + elements[s - 1] = pivot; + } + + @Override + @TearDown + public void clean() { + elements = null; + } + + @Override + @Benchmark + @BenchmarkMode(Mode.AverageTime) + public int findPosition() { + int index = 0; + Short pivotWrapper = pivot; + while (!pivotWrapper.equals(elements[index])) { + index++; + } + return index; + + } + + @Override + public String getSimpleClassName() { + return ShortWrapperLookup.class.getSimpleName(); + } + + +} diff --git a/core-java-8/src/main/resources/logback.xml b/core-java-8/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-java-8/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/internationalization/DateTimeFormatterUnitTest.java b/core-java-8/src/test/java/com/baeldung/internationalization/DateTimeFormatterUnitTest.java deleted file mode 100644 index 4d95bc82e1..0000000000 --- a/core-java-8/src/test/java/com/baeldung/internationalization/DateTimeFormatterUnitTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.baeldung.internationalization; - -import org.junit.Assert; -import org.junit.Test; - -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.FormatStyle; -import java.util.Locale; -import java.util.TimeZone; - -public class DateTimeFormatterUnitTest { - - @Test - public void givenDefaultUsLocaleAndDateTimeAndPattern_whenFormatWithDifferentLocales_thenGettingLocalizedDateTimes() { - Locale.setDefault(Locale.US); - LocalDateTime localDateTime = LocalDateTime.of(2018, 1, 1, 10, 15, 50, 500); - String pattern = "dd-MMMM-yyyy HH:mm:ss.SSS"; - - DateTimeFormatter defaultTimeFormatter = DateTimeFormatter.ofPattern(pattern); - DateTimeFormatter plTimeFormatter = DateTimeFormatter.ofPattern(pattern, new Locale("pl", "PL")); - DateTimeFormatter deTimeFormatter = DateTimeFormatter.ofPattern(pattern).withLocale(Locale.GERMANY); - - Assert.assertEquals("01-January-2018 10:15:50.000", defaultTimeFormatter.format(localDateTime)); - Assert.assertEquals("01-stycznia-2018 10:15:50.000", plTimeFormatter.format(localDateTime)); - Assert.assertEquals("01-Januar-2018 10:15:50.000", deTimeFormatter.format(localDateTime)); - } - - @Test - public void givenDateTimeAndTimeZone_whenFormatWithDifferentLocales_thenGettingLocalizedZonedDateTimes() { - Locale.setDefault(Locale.US); - LocalDateTime localDateTime = LocalDateTime.of(2018, 1, 1, 10, 15, 50, 500); - ZoneId losAngelesTimeZone = TimeZone.getTimeZone("America/Los_Angeles").toZoneId(); - - DateTimeFormatter localizedFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL); - DateTimeFormatter frLocalizedFormatter = - DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(Locale.FRANCE); - String formattedDateTime = localizedFormatter.format(ZonedDateTime.of(localDateTime, losAngelesTimeZone)); - String frFormattedDateTime = frLocalizedFormatter.format(ZonedDateTime.of(localDateTime, losAngelesTimeZone)); - - Assert.assertEquals("Monday, January 1, 2018 10:15:50 AM PST", formattedDateTime); - Assert.assertEquals("lundi 1 janvier 2018 10 h 15 PST", frFormattedDateTime); - } -} diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java index f371c0d7da..71ec5b147f 100644 --- a/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java +++ b/core-java-8/src/test/java/com/baeldung/java8/Java8SortUnitTest.java @@ -1,16 +1,18 @@ package com.baeldung.java8; -import com.baeldung.java8.entity.Human; -import com.google.common.collect.Lists; -import com.google.common.primitives.Ints; -import org.junit.Assert; -import org.junit.Test; +import static org.hamcrest.Matchers.equalTo; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; -import static org.hamcrest.Matchers.equalTo; +import org.junit.Assert; +import org.junit.Test; + +import com.baeldung.java8.entity.Human; +import com.google.common.collect.Lists; +import com.google.common.primitives.Ints; public class Java8SortUnitTest { @@ -111,5 +113,22 @@ public class Java8SortUnitTest { humans.sort(Comparator.comparing(Human::getName)); Assert.assertThat(humans.get(0), equalTo(new Human("Jack", 12))); } + + @Test + public final void givenStreamNaturalOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { + final List letters = Lists.newArrayList("B", "A", "C"); + + final List sortedLetters = letters.stream().sorted().collect(Collectors.toList()); + Assert.assertThat(sortedLetters.get(0), equalTo("A")); + } + @Test + public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() { + + final List humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12)); + final Comparator nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName()); + + final List sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList()); + Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12))); + } } diff --git a/core-java-8/src/test/java/com/baeldung/list/AddElementsUnitTest.java b/core-java-8/src/test/java/com/baeldung/list/AddElementsUnitTest.java new file mode 100644 index 0000000000..93c28812bd --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/list/AddElementsUnitTest.java @@ -0,0 +1,87 @@ +package com.baeldung.list; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.*; + +import static org.junit.Assert.*; + +public class AddElementsUnitTest { + + List flowers; + + @Before + public void init() { + this.flowers = new ArrayList<>(Arrays.asList( + new Flower("Poppy", 12), + new Flower("Anemone", 8), + new Flower("Catmint", 12))); + } + + @Test + public void givenAList_whenTargetListIsEmpty_thenReturnTargetListWithNewItems() { + List anotherList = new ArrayList<>(); + anotherList.addAll(flowers); + + assertEquals(anotherList.size(), flowers.size()); + Assert.assertTrue(anotherList.containsAll(flowers)); + } + + @Test + public void givenAList_whenTargetListIsEmpty_thenReturnTargetListWithOneModifiedElementByConstructor() { + List anotherList = new ArrayList<>(); + anotherList.addAll(flowers); + + Flower flower = anotherList.get(0); + flower.setPetals(flowers.get(0).getPetals() * 3); + + assertEquals(anotherList.size(), flowers.size()); + Assert.assertTrue(anotherList.containsAll(flowers)); + } + + @Test + public void givenAListAndElements_whenUseCollectionsAddAll_thenAddElementsToTargetList() { + List target = new ArrayList<>(); + + Collections.addAll(target, flowers.get(0), flowers.get(1), flowers.get(2), flowers.get(0)); + + assertEquals(target.size(), 4); + } + + @Test + public void givenTwoList_whenSourceListDoesNotHaveNullElements_thenAddElementsToTargetListSkipFirstElementByStreamProcess() { + List flowerVase = new ArrayList<>(); + + flowers.stream() + .skip(1) + .forEachOrdered(flowerVase::add); + + assertEquals(flowerVase.size() + 1, flowers.size()); + assertFalse(flowerVase.containsAll(flowers)); + } + + @Test + public void givenTwoList_whenSourceListDoesNotHaveNullElements_thenAddElementsToTargetListFilteringElementsByStreamProcess() { + List flowerVase = new ArrayList<>(); + + flowers.stream() + .filter(f -> f.getPetals() > 10) + .forEachOrdered(flowerVase::add); + + assertEquals(flowerVase.size() + 1, flowers.size()); + assertFalse(flowerVase.containsAll(flowers)); + } + + @Test + public void givenAList_whenListIsNotNull_thenAddElementsToListByStreamProcessWihtOptional() { + List target = new ArrayList<>(); + + Optional.ofNullable(flowers) + .ifPresent(target::addAll); + + assertNotNull(target); + assertEquals(target.size(), 3); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java b/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java new file mode 100644 index 0000000000..f68df2c821 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; +import org.junit.Test; +import static org.junit.Assert.*; + + +public class NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest { + + private final NullSafeCollectionStreamsUsingCommonsEmptyIfNull instance = + new NullSafeCollectionStreamsUsingCommonsEmptyIfNull(); + + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java b/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java new file mode 100644 index 0000000000..df6c72d346 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java @@ -0,0 +1,50 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.baeldung.nullsafecollectionstreams; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; + +import org.junit.Test; + +/** + * + * @author Kwaje Anthony + */ +public class NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest { + + private final NullSafeCollectionStreamsUsingJava8OptionalContainer instance = new NullSafeCollectionStreamsUsingJava8OptionalContainer(); + + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java b/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java new file mode 100644 index 0000000000..ddb4dcdc12 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java @@ -0,0 +1,45 @@ + +package com.baeldung.nullsafecollectionstreams; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Kwaje Anthony + */ +public class NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest { + + private final NullSafeCollectionStreamsUsingNullDereferenceCheck instance = + new NullSafeCollectionStreamsUsingNullDereferenceCheck(); + + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/optional/PersonRepositoryUnitTest.java b/core-java-8/src/test/java/com/baeldung/optional/PersonRepositoryUnitTest.java new file mode 100644 index 0000000000..4efa625ccd --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/optional/PersonRepositoryUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.optional; + +import org.junit.Test; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class PersonRepositoryUnitTest { + + PersonRepository personRepository = new PersonRepository(); + + @Test + public void whenIdIsNull_thenExceptionIsThrown() { + assertThrows(IllegalArgumentException.class, + () -> + Optional + .ofNullable(personRepository.findNameById(null)) + .orElseThrow(IllegalArgumentException::new)); + } + + @Test + public void whenIdIsNonNull_thenNoExceptionIsThrown() { + assertAll( + () -> + Optional + .ofNullable(personRepository.findNameById("id")) + .orElseThrow(RuntimeException::new)); + } + + @Test + public void whenIdNonNull_thenReturnsNameUpperCase() { + String name = Optional + .ofNullable(personRepository.findNameById("id")) + .map(String::toUpperCase) + .orElseThrow(RuntimeException::new); + + assertEquals("NAME", name); + } + +} \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/stream/conditional/StreamForEachIfElseUnitTest.java b/core-java-8/src/test/java/com/baeldung/stream/conditional/StreamForEachIfElseUnitTest.java new file mode 100644 index 0000000000..b5d26eb6a8 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/stream/conditional/StreamForEachIfElseUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.stream.conditional; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Test; + +public class StreamForEachIfElseUnitTest { + + @Test + public final void givenIntegerStream_whenCheckingIntegerParityWithIfElse_thenEnsureCorrectParity() { + List ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + ints.stream() + .forEach(i -> { + if (i.intValue() % 2 == 0) { + Assert.assertTrue(i.intValue() + " is not even", i.intValue() % 2 == 0); + } else { + Assert.assertTrue(i.intValue() + " is not odd", i.intValue() % 2 != 0); + } + }); + + } + + @Test + public final void givenIntegerStream_whenCheckingIntegerParityWithStreamFilter_thenEnsureCorrectParity() { + List ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + + Stream evenIntegers = ints.stream() + .filter(i -> i.intValue() % 2 == 0); + Stream oddIntegers = ints.stream() + .filter(i -> i.intValue() % 2 != 0); + + evenIntegers.forEach(i -> Assert.assertTrue(i.intValue() + " is not even", i.intValue() % 2 == 0)); + oddIntegers.forEach(i -> Assert.assertTrue(i.intValue() + " is not odd", i.intValue() % 2 != 0)); + + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeUnitTest.java b/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeUnitTest.java index 3ad3deb548..ec20b7794b 100644 --- a/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeUnitTest.java +++ b/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeUnitTest.java @@ -39,5 +39,4 @@ public class CurrentDateTimeUnitTest { assertEquals(clock.instant().getEpochSecond(), now.getEpochSecond()); } - } diff --git a/core-java-9/README.md b/core-java-9/README.md index a76dcefc69..38816471aa 100644 --- a/core-java-9/README.md +++ b/core-java-9/README.md @@ -15,10 +15,7 @@ - [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity) - [Java 9 Optional API Additions](http://www.baeldung.com/java-9-optional) - [Java 9 Reactive Streams](http://www.baeldung.com/java-9-reactive-streams) -- [How to Get All Dates Between Two Dates?](http://www.baeldung.com/java-between-dates) - [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new) -- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string) -- [Convert Date to LocalDate or LocalDateTime and Back](http://www.baeldung.com/java-date-to-localdate-and-localdatetime) - [Java 9 Variable Handles Demistyfied](http://www.baeldung.com/java-variable-handles) - [Exploring the New HTTP Client in Java 9](http://www.baeldung.com/java-9-http-client) - [Method Handles in Java](http://www.baeldung.com/java-method-handles) @@ -26,3 +23,7 @@ - [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) +- [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range) +- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) +- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api) +- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api) diff --git a/core-java-9/logging.sh b/core-java-9/logging.sh new file mode 100755 index 0000000000..c9b502f300 --- /dev/null +++ b/core-java-9/logging.sh @@ -0,0 +1,15 @@ +# compile logging module +# javac --module-path mods -d mods/com.baeldung.logging src/modules/com.baeldung.logging/module-info.java src/modules/com.baeldung.logging/com/baeldung/logging/*.java + +# compile logging slf4j module +javac --module-path mods -d mods/com.baeldung.logging.slf4j src/modules/com.baeldung.logging.slf4j/module-info.java src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/*.java + + +# compile logging main app module +javac --module-path mods -d mods/com.baeldung.logging.app src/modules/com.baeldung.logging.app/module-info.java src/modules/com.baeldung.logging.app/com/baeldung/logging/app/*.java + +# run logging main app +# java --module-path mods -m com.baeldung.logging.app/com.baeldung.logging.app.MainApp + +# run looging main app using logback +java --module-path mods -Dlogback.configurationFile=mods/logback.xml -m com.baeldung.logging.app/com.baeldung.logging.app.MainApp diff --git a/core-java-9/mods/logback.xml b/core-java-9/mods/logback.xml new file mode 100644 index 0000000000..c22c7a7130 --- /dev/null +++ b/core-java-9/mods/logback.xml @@ -0,0 +1,16 @@ + + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} -- %msg%n + + + + + + + + + \ No newline at end of file diff --git a/core-java-9/pom.xml b/core-java-9/pom.xml index 0662e1e9a2..f22d0a3ed9 100644 --- a/core-java-9/pom.xml +++ b/core-java-9/pom.xml @@ -1,5 +1,5 @@ + 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 core-java-9 @@ -13,45 +13,29 @@ - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${ch.qos.logback.version} - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - junit - junit - ${junit.version} - test - - - org.mockito - mockito-core - ${mockito.version} - test - com.jayway.awaitility awaitility ${awaitility.version} test + + org.assertj + assertj-core + ${assertj.version} + test + com.google.guava guava ${guava.version} + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + @@ -77,20 +61,9 @@ - - UTF-8 - - - 1.7.21 - 1.2.1 - - 3.7.0 - 2.19.1 - - 1.3 - 4.12 - 1.10.19 + 3.10.0 + 1.2.0 1.7.0 1.9 1.9 diff --git a/core-java-9/src/main/java/com/baeldung/java9/language/stream/StreamsGroupingCollectionFilter.java b/core-java-9/src/main/java/com/baeldung/java9/language/stream/StreamsGroupingCollectionFilter.java new file mode 100644 index 0000000000..84d2e63c6c --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/language/stream/StreamsGroupingCollectionFilter.java @@ -0,0 +1,27 @@ +package com.baeldung.java9.language.stream; + +import static java.util.stream.Collectors.filtering; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +public class StreamsGroupingCollectionFilter { + + static public Map> findEvenNumbersAfterGroupingByQuantityOfDigits(Collection baseCollection) { + Function getQuantityOfDigits = item -> (int) Math.log10(item) + 1; + + return baseCollection.stream() + .collect(groupingBy(getQuantityOfDigits, filtering(item -> item % 2 == 0, toList()))); + } + + static public Map> findEvenNumbersBeforeGroupingByQuantityOfDigits(Collection baseCollection) { + + return baseCollection.stream() + .filter(item -> item % 2 == 0) + .collect(groupingBy(item -> (int) Math.log10(item) + 1, toList())); + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/maps/initialize/MapsInitializer.java b/core-java-9/src/main/java/com/baeldung/java9/maps/initialize/MapsInitializer.java new file mode 100644 index 0000000000..2a8ce588bb --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/maps/initialize/MapsInitializer.java @@ -0,0 +1,33 @@ +package com.baeldung.java9.maps.initialize; + +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.Map; + +public class MapsInitializer { + + @SuppressWarnings("unused") + public void createMapWithMapOf() { + Map emptyMap = Map.of(); + Map singletonMap = Map.of("key1", "value"); + Map map = Map.of("key1","value1", "key2", "value2"); + } + + public void createMapWithMapEntries() { + Map map = Map.ofEntries( + new AbstractMap.SimpleEntry("name", "John"), + new AbstractMap.SimpleEntry("city", "budapest"), + new AbstractMap.SimpleEntry("zip", "000000"), + new AbstractMap.SimpleEntry("home", "1231231231") + ); + } + + @SuppressWarnings("unused") + public void createMutableMaps() { + Map map = new HashMap (Map.of("key1","value1", "key2", "value2")); + Map map2 = new HashMap ( Map.ofEntries( + new AbstractMap.SimpleEntry("name", "John"), + new AbstractMap.SimpleEntry("city", "budapest"))); + + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/process/ChildProcess.java b/core-java-9/src/main/java/com/baeldung/java9/process/ChildProcess.java new file mode 100644 index 0000000000..46c2e688ce --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/process/ChildProcess.java @@ -0,0 +1,15 @@ +package com.baeldung.java9.process; + +import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ChildProcess { + + public static void main(String[] args) { + @SuppressWarnings("resource") + Scanner input = new Scanner(System.in); + Logger log = Logger.getLogger(ChildProcess.class.getName()); + log.log(Level.INFO, input.nextLine()); + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/process/OutputStreamExample.java b/core-java-9/src/main/java/com/baeldung/java9/process/OutputStreamExample.java new file mode 100644 index 0000000000..443847916a --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/process/OutputStreamExample.java @@ -0,0 +1,16 @@ +package com.baeldung.java9.process; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class OutputStreamExample { + + public static void main(String[] args) { + Logger log = Logger.getLogger(OutputStreamExample.class.getName()); + log.log(Level.INFO, Integer.toString(sum(1,2))); + } + + public static int sum(int a, int b) { + return a + b; + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/process/ProcessCompilationError.java b/core-java-9/src/main/java/com/baeldung/java9/process/ProcessCompilationError.java new file mode 100644 index 0000000000..8b6ae0b441 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/process/ProcessCompilationError.java @@ -0,0 +1,7 @@ +package com.baeldung.java9.process; + +public class ProcessCompilationError { + //This method has been written to generate error to display + //how process errorStream() can consume error + public static void(); +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUnderstanding.java b/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUnderstanding.java new file mode 100644 index 0000000000..74101ba3da --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUnderstanding.java @@ -0,0 +1,110 @@ +package com.baeldung.java9.process; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ProcessUnderstanding { + + public static int compileAndRunJavaProgram() throws IOException { + Process process = Runtime.getRuntime() + .exec("javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\OutputStreamExample.java"); + process = Runtime.getRuntime() + .exec("java -cp src/main/java com.baeldung.java9.process.OutputStreamExample"); + BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream())); + int value = Integer.parseInt(output.readLine()); + return value; + } + + public static String getErrorStreamExample() throws IOException { + Process process = Runtime.getRuntime() + .exec("javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\ProcessCompilationError.java"); + BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String errorString = error.readLine(); + return errorString; + } + + public static void creatingNewProcess() throws IOException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + } + + public static int filterProcessWithStreamsInSpecificRangeReturnCount() { + return (int) ProcessHandle.allProcesses() + .filter(ph -> (ph.pid() > 10000 && ph.pid() < 50000)) + .count(); + } + + public static void destroyingProcessCreatedBySameProcess() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + Thread.sleep(10000); + process.destroy(); + } + + public static void destroyingProcessCreatedByDifferentProcess() { + // find out the process id of current running task by checking + // task manager in windows and enter the integer value + Optional optionalProcessHandle = ProcessHandle.of(5232); + ProcessHandle processHandle = optionalProcessHandle.get(); + processHandle.destroy(); + } + + public static int waitForExample() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + return process.waitFor(); + } + + public static int exitValueExample() throws IOException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + process.destroy(); + return process.exitValue(); + } + + public static void destroyExample() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + Thread.sleep(10000); + process.destroy(); + } + + public static void destroyForciblyExample() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + Thread.sleep(10000); + process.destroy(); + if (process.isAlive()) { + process.destroyForcibly(); + } + } + + public static void outputStreamDemo() throws IOException, InterruptedException { + Logger log = Logger.getLogger(ProcessUnderstanding.class.getName()); + Process pr = Runtime.getRuntime() + .exec("javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\ChildProcess.java"); + final Process process = Runtime.getRuntime() + .exec("java -cp src/main/java com.baeldung.java9.process.ChildProcess"); + try (Writer w = new OutputStreamWriter(process.getOutputStream(), "UTF-8")) { + w.write("send to child\n"); + } + new Thread(() -> { + try { + int c; + while ((c = process.getInputStream() + .read()) != -1) + System.out.write((byte) c); + } catch (Exception e) { + e.printStackTrace(); + } + }).start(); + // send to child + log.log(Level.INFO, "rc=" + process.waitFor()); + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/rangedates/DatesCollectionIteration.java b/core-java-9/src/main/java/com/baeldung/java9/rangedates/DatesCollectionIteration.java new file mode 100644 index 0000000000..f5ec5d29dc --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/rangedates/DatesCollectionIteration.java @@ -0,0 +1,24 @@ +package com.baeldung.java9.rangedates; + +import java.util.Collection; +import java.util.Date; + +public class DatesCollectionIteration { + + public void iteratingRangeOfDatesJava7(Collection dates) { + + for (Date date : dates) { + processDate(date); + } + } + + public void iteratingRangeOfDatesJava8(Collection dates) { + dates.stream() + .forEach(this::processDate); + } + + private void processDate(Date date) { + System.out.println(date); + } + +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/rangedates/RangeDatesIteration.java b/core-java-9/src/main/java/com/baeldung/java9/rangedates/RangeDatesIteration.java new file mode 100644 index 0000000000..4972036c91 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/rangedates/RangeDatesIteration.java @@ -0,0 +1,43 @@ +package com.baeldung.java9.rangedates; + +import java.time.LocalDate; +import java.util.Calendar; +import java.util.Date; + +public class RangeDatesIteration { + + public void iterateBetweenDatesJava9(LocalDate startDate, LocalDate endDate) { + + startDate.datesUntil(endDate) + .forEach(this::processDate); + } + + public void iterateBetweenDatesJava8(LocalDate start, LocalDate end) { + for (LocalDate date = start; date.isBefore(end); date = date.plusDays(1)) { + processDate(date); + } + } + + public void iterateBetweenDatesJava7(Date start, Date end) { + Date current = start; + + while (current.before(end)) { + processDate(current); + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(current); + + calendar.add(Calendar.DATE, 1); + + current = calendar.getTime(); + } + } + + private void processDate(LocalDate date) { + System.out.println(date); + } + + private void processDate(Date date) { + System.out.println(date); + } +} diff --git a/core-java-9/src/main/resources/logback.xml b/core-java-9/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/core-java-9/src/main/resources/logback.xml +++ b/core-java-9/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/core-java-9/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java b/core-java-9/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java new file mode 100644 index 0000000000..01f53d59e9 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java @@ -0,0 +1,13 @@ +package com.baeldung.logging.app; + +import static java.lang.System.Logger.*; + +public class MainApp { + + private static System.Logger LOGGER = System.getLogger("MainApp"); + + public static void main(String[] args) { + LOGGER.log(Level.ERROR, "error test"); + LOGGER.log(Level.INFO, "info test"); + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging.app/module-info.java b/core-java-9/src/modules/com.baeldung.logging.app/module-info.java new file mode 100644 index 0000000000..037c72b755 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.app/module-info.java @@ -0,0 +1,2 @@ +module com.baeldung.logging.app { +} \ No newline at end of file diff --git a/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java b/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java new file mode 100644 index 0000000000..df41e071fd --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java @@ -0,0 +1,99 @@ +package com.baeldung.logging.slf4j; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ResourceBundle; + +public class Slf4jLogger implements System.Logger { + + private final String name; + private final Logger logger; + + public Slf4jLogger(String name) { + this.name = name; + logger = LoggerFactory.getLogger(name); + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean isLoggable(Level level) { + switch (level) { + case OFF: + return false; + case TRACE: + return logger.isTraceEnabled(); + case DEBUG: + return logger.isDebugEnabled(); + case INFO: + return logger.isInfoEnabled(); + case WARNING: + return logger.isWarnEnabled(); + case ERROR: + return logger.isErrorEnabled(); + case ALL: + default: + return true; + } + } + + @Override + public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) { + if (!isLoggable(level)) { + return; + } + + switch (level) { + case TRACE: + logger.trace(msg, thrown); + break; + case DEBUG: + logger.debug(msg, thrown); + break; + case INFO: + logger.info(msg, thrown); + break; + case WARNING: + logger.warn(msg, thrown); + break; + case ERROR: + logger.error(msg, thrown); + break; + case ALL: + default: + logger.info(msg, thrown); + } + } + + @Override + public void log(Level level, ResourceBundle bundle, String format, Object... params) { + if (!isLoggable(level)) { + return; + } + + switch (level) { + case TRACE: + logger.trace(format, params); + break; + case DEBUG: + logger.debug(format, params); + break; + case INFO: + logger.info(format, params); + break; + case WARNING: + logger.warn(format, params); + break; + case ERROR: + logger.error(format, params); + break; + case ALL: + default: + logger.info(format, params); + } + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java b/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java new file mode 100644 index 0000000000..97f7cccb92 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java @@ -0,0 +1,8 @@ +package com.baeldung.logging.slf4j; + +public class Slf4jLoggerFinder extends System.LoggerFinder { + @Override + public System.Logger getLogger(String name, Module module) { + return new Slf4jLogger(name); + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging.slf4j/module-info.java b/core-java-9/src/modules/com.baeldung.logging.slf4j/module-info.java new file mode 100644 index 0000000000..311ca22f5b --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.slf4j/module-info.java @@ -0,0 +1,6 @@ +module com.baeldung.logging.slf4j { + requires org.slf4j; + provides java.lang.System.LoggerFinder + with com.baeldung.logging.slf4j.Slf4jLoggerFinder; + exports com.baeldung.logging.slf4j; +} \ No newline at end of file diff --git a/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java b/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java new file mode 100644 index 0000000000..a495e6979d --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java @@ -0,0 +1,27 @@ +package com.baeldung.logging; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +public class ConsoleLogger implements System.Logger { + + @Override + public String getName() { + return "ConsoleLogger"; + } + + @Override + public boolean isLoggable(Level level) { + return true; + } + + @Override + public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) { + System.out.printf("ConsoleLogger [%s]: %s - %s%n", level, msg, thrown); + } + + @Override + public void log(Level level, ResourceBundle bundle, String format, Object... params) { + System.out.printf("ConsoleLogger [%s]: %s%n", level, MessageFormat.format(format, params)); + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java b/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java new file mode 100644 index 0000000000..b38955f199 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java @@ -0,0 +1,9 @@ +package com.baeldung.logging; + +public class CustomLoggerFinder extends System.LoggerFinder { + + @Override + public System.Logger getLogger(String name, Module module) { + return new ConsoleLogger(); + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging/module-info.java b/core-java-9/src/modules/com.baeldung.logging/module-info.java new file mode 100644 index 0000000000..4ca0af0225 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging/module-info.java @@ -0,0 +1,5 @@ +module com.baeldung.logging { + provides java.lang.System.LoggerFinder + with com.baeldung.logging.CustomLoggerFinder; + exports com.baeldung.logging; +} \ No newline at end of file diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectionFilterUnitTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectionFilterUnitTest.java new file mode 100644 index 0000000000..1b9315678a --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/language/stream/CollectionFilterUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.java9.language.stream; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +@RunWith(JUnitPlatform.class) +public class CollectionFilterUnitTest { + + private static final Collection BASE_INTEGER_COLLECTION = Arrays.asList(9, 12, 55, 56, 101, 115, 8002, 223, 2668, 19, 8); + private static final Map> EXPECTED_EVEN_FILTERED_AFTER_GROUPING_MAP = createExpectedFilterAfterGroupingMap(); + private static Map> createExpectedFilterAfterGroupingMap() { + Map> map = new HashMap<>(); + map.put(1, Arrays.asList(8)); + map.put(2, Arrays.asList(12, 56)); + map.put(3, Collections.emptyList()); + map.put(4, Arrays.asList(8002, 2668)); + return map; + + } + + private static final Map> EXPECTED_EVEN_FILTERED_BEFORE_GROUPING_MAP = createExpectedFilterBeforeGroupingMap(); + private static Map> createExpectedFilterBeforeGroupingMap() { + Map> map = new HashMap<>(); + map.put(1, Arrays.asList(8)); + map.put(2, Arrays.asList(12, 56)); + map.put(4, Arrays.asList(8002, 2668)); + return map; + + } + + @Test + public void givenAStringCollection_whenFilteringFourLetterWords_thenObtainTheFilteredCollection() { + Map> filteredAfterGroupingMap = StreamsGroupingCollectionFilter.findEvenNumbersAfterGroupingByQuantityOfDigits(BASE_INTEGER_COLLECTION); + Map> filteredBeforeGroupingMap = StreamsGroupingCollectionFilter.findEvenNumbersBeforeGroupingByQuantityOfDigits(BASE_INTEGER_COLLECTION); + + assertThat(filteredAfterGroupingMap).containsAllEntriesOf(EXPECTED_EVEN_FILTERED_AFTER_GROUPING_MAP); + assertThat(filteredBeforeGroupingMap).doesNotContainKey(3) + .containsAllEntriesOf(EXPECTED_EVEN_FILTERED_BEFORE_GROUPING_MAP); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/process/ProcessUnderstandingTest.java b/core-java-9/src/test/java/com/baeldung/java9/process/ProcessUnderstandingTest.java new file mode 100644 index 0000000000..2c5525b9ed --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/process/ProcessUnderstandingTest.java @@ -0,0 +1,121 @@ +package com.baeldung.java9.process; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.String; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.lang.Integer; + +import org.junit.jupiter.api.Test; + +class ProcessUnderstandingTest { + + @Test + public void givenSourceProgram_whenExecutedFromAnotherProgram_thenSourceProgramOutput3() throws IOException { + Process process = Runtime.getRuntime() + .exec("javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\OutputStreamExample.java"); + process = Runtime.getRuntime() + .exec("java -cp src/main/java com.baeldung.java9.process.OutputStreamExample"); + BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream())); + int value = Integer.parseInt(output.readLine()); + assertEquals(3, value); + } + + @Test + public void givenSourceProgram_whenReadingInputStream_thenFirstLineEquals3() throws IOException { + Process process = Runtime.getRuntime() + .exec("javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\OutputStreamExample.java"); + process = Runtime.getRuntime() + .exec("java -cp src/main/java com.baeldung.java9.process.OutputStreamExample"); + BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream())); + int value = Integer.parseInt(output.readLine()); + assertEquals(3, value); + } + + @Test + public void givenSubProcess_whenEncounteringError_thenErrorStreamNotNull() throws IOException { + Process process = Runtime.getRuntime() + .exec("javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\ProcessCompilationError.java"); + BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String errorString = error.readLine(); + assertNotNull(errorString); + } + + //@Test - windows specific + public void givenSubProcess_whenStarted_thenStartSuccessIsAlive() throws IOException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + assertTrue(builder.start().isAlive()); + } + + //@Test - windows specific + public void givenSubProcess_whenDestroying_thenProcessNotAlive() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + Thread.sleep(10000); + process.destroy(); + assertFalse(process.isAlive()); + } + + //@Test - windows specific + public void givenSubProcess_whenAlive_thenDestroyForcibly() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + Thread.sleep(10000); + process.destroy(); + if (process.isAlive()) { + process.destroyForcibly(); + } + assertFalse(process.isAlive()); + } + + //@Test - windows specific + public void givenSubProcess_whenDestroyed_thenCheckIfAlive() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + Thread.sleep(10000); + process.destroy(); + assertFalse(process.isAlive()); + } + + @Test + public void givenProcessNotCreated_fromWithinJavaApplicationDestroying_thenProcessNotAlive() { + Optional optionalProcessHandle = ProcessHandle.of(5232); + ProcessHandle processHandle = optionalProcessHandle.get(); + processHandle.destroy(); + assertFalse(processHandle.isAlive()); + } + + //@Test - windows specific + public void givenSubProcess_whenCurrentThreadWaitsIndefinitelyuntilSubProcessEnds_thenProcessWaitForReturnsGrt0() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + assertThat(process.waitFor() >= 0); + } + + //@Test - windows specific + public void givenSubProcess_whenCurrentThreadWaitsAndSubProcessNotTerminated_thenProcessWaitForReturnsFalse() throws IOException, InterruptedException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + assertFalse(process.waitFor(1, TimeUnit.SECONDS)); + } + + //@Test - windows specific + public void givenSubProcess_whenCurrentThreadWillNotWaitIndefinitelyforSubProcessToEnd_thenProcessExitValueReturnsGrt0() throws IOException { + ProcessBuilder builder = new ProcessBuilder("notepad.exe"); + Process process = builder.start(); + assertThat(process.exitValue() >= 0); + } + + @Test + public void givenRunningProcesses_whenFilterOnProcessIdRange_thenGetSelectedProcessPid() { + assertThat(((int) ProcessHandle.allProcesses() + .filter(ph -> (ph.pid() > 10000 && ph.pid() < 50000)) + .count()) > 0); + } +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/rangedates/DatesCollectionIterationUnitTest.java b/core-java-9/src/test/java/com/baeldung/java9/rangedates/DatesCollectionIterationUnitTest.java new file mode 100644 index 0000000000..522b00065e --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/rangedates/DatesCollectionIterationUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.java9.rangedates; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Test; + +public class DatesCollectionIterationUnitTest { + + private Collection localDates = LocalDate.now() + .datesUntil(LocalDate.now() + .plus(10L, ChronoUnit.DAYS)) + .collect(Collectors.toList()); + + private Collection dates = localDates.stream() + .map(localDate -> Date.from(localDate.atStartOfDay(ZoneId.systemDefault()) + .toInstant())) + .collect(Collectors.toList()); + + @Test + public void givenIteratingListOfDatesJava7_WhenStartTodayAndEnding10DaysAhead() { + DatesCollectionIteration iterateInColleciton = new DatesCollectionIteration(); + Calendar today = Calendar.getInstance(); + Calendar next10Ahead = (Calendar) today.clone(); + next10Ahead.add(Calendar.DATE, 10); + + iterateInColleciton.iteratingRangeOfDatesJava7(createRangeDates(today.getTime(), next10Ahead.getTime())); + } + + @Test + public void givenIteratingListOfDatesJava8_WhenStartTodayAndEnd10DaysAhead() { + DatesCollectionIteration iterateInColleciton = new DatesCollectionIteration(); + + iterateInColleciton.iteratingRangeOfDatesJava8(dates); + } + + private List createRangeDates(Date start, Date end) { + + List dates = new ArrayList<>(); + Date current = start; + + while (current.before(end)) { + dates.add(current); + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(current); + calendar.add(Calendar.DATE, 1); + + current = calendar.getTime(); + } + + return dates; + } +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/rangedates/RangeDatesIterationUnitTest.java b/core-java-9/src/test/java/com/baeldung/java9/rangedates/RangeDatesIterationUnitTest.java new file mode 100644 index 0000000000..4f5cd17d98 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/rangedates/RangeDatesIterationUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.java9.rangedates; + +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +public class RangeDatesIterationUnitTest { + + @Test + public void givenIterateBetweenDatesJava9_WhenStartDateAsTodayAndEndDateAs10DaysAhead() { + LocalDate start = LocalDate.now(); + LocalDate end = start.plus(10L, ChronoUnit.DAYS); + + RangeDatesIteration iteration = new RangeDatesIteration(); + + iteration.iterateBetweenDatesJava9(start, end); + } + + @Test + public void givenIterateBetweenDatesJava8_WhenStartDateAsTodayAndEndDateAs10DaysAhead() { + LocalDate start = LocalDate.now(); + LocalDate end = start.plus(10L, ChronoUnit.DAYS); + + RangeDatesIteration iteration = new RangeDatesIteration(); + + iteration.iterateBetweenDatesJava8(start, end); + } + + @Test + public void givenIterateBetweenDatesJava7_WhenStartDateAsTodayAndEndDateAs10DaysAhead() { + Calendar today = Calendar.getInstance(); + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(today.get(Calendar.YEAR), today.get(Calendar.MONTH), today.get(Calendar.DATE)); + Date start = calendar.getTime(); + + calendar.add(Calendar.DATE, 10); + Date end = calendar.getTime(); + + RangeDatesIteration iteration = new RangeDatesIteration(); + + iteration.iterateBetweenDatesJava7(start, end); + } + +} diff --git a/core-java-collections/README.md b/core-java-collections/README.md index 510eac9dbc..aef640634e 100644 --- a/core-java-collections/README.md +++ b/core-java-collections/README.md @@ -30,3 +30,28 @@ - [How to TDD a List Implementation in Java](http://www.baeldung.com/java-test-driven-list) - [How to Store Duplicate Keys in a Map in Java?](http://www.baeldung.com/java-map-duplicate-keys) - [Getting the Size of an Iterable in Java](http://www.baeldung.com/java-iterable-size) +- [Iterating Backward Through a List](http://www.baeldung.com/java-list-iterate-backwards) +- [How to Filter a Collection in Java](http://www.baeldung.com/java-collection-filtering) +- [Add Multiple Items to an Java ArrayList](http://www.baeldung.com/java-add-items-array-list) +- [Remove the First Element from a List](http://www.baeldung.com/java-remove-first-element-from-list) +- [How to Convert List to Map in Java](http://www.baeldung.com/java-list-to-map) +- [Initializing HashSet at the Time of Construction](http://www.baeldung.com/java-initialize-hashset) +- [Removing the First Element of an Array](https://www.baeldung.com/java-array-remove-first-element) +- [Fail-Safe Iterator vs Fail-Fast Iterator](http://www.baeldung.com/java-fail-safe-vs-fail-fast-iterator) +- [Shuffling Collections In Java](http://www.baeldung.com/java-shuffle-collection) +- [How to Find an Element in a List with Java](http://www.baeldung.com/find-list-element-java) +- [An Introduction to Java.util.Hashtable Class](http://www.baeldung.com/java-hash-table) +- [Copy a List to Another List in Java](http://www.baeldung.com/java-copy-list-to-another) +- [Finding Max/Min of a List or Collection](http://www.baeldung.com/java-collection-min-max) +- [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections) +- [Remove All Occurrences of a Specific Value from a List](https://www.baeldung.com/java-remove-value-from-list) +- [Thread Safe LIFO Data Structure Implementations](https://www.baeldung.com/java-lifo-thread-safe) +- [Collections.emptyList() vs. New List Instance](https://www.baeldung.com/java-collections-emptylist-new-list) +- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) +- [Differences Between Collection.clear() and Collection.removeAll()](https://www.baeldung.com/java-collection-clear-vs-removeall) +- [Performance of contains() in a HashSet vs ArrayList](https://www.baeldung.com/java-hashset-arraylist-contains-performance) +- [Get the Key for a Value from a Java Map](https://www.baeldung.com/java-map-key-from-value) +- [Time Complexity of Java Collections](https://www.baeldung.com/java-collections-complexity) +- [Sort a HashMap in Java](https://www.baeldung.com/java-hashmap-sort) +- [Finding the Highest Value in a Java Map](https://www.baeldung.com/java-find-map-max) +- [Operating on and Removing an Item from Stream](https://www.baeldung.com/java-use-remove-item-stream) diff --git a/core-java-collections/pom.xml b/core-java-collections/pom.xml index c5d3396642..b4a6e26d13 100644 --- a/core-java-collections/pom.xml +++ b/core-java-collections/pom.xml @@ -1,60 +1,88 @@ - - 4.0.0 - com.baeldung - core-java-collections - 0.1.0-SNAPSHOT - jar - core-java-collections - - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - - - - - junit - junit - ${junit.version} - test - - - net.sourceforge.collections - collections-generic - ${collections-generic.version} - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - com.jayway.awaitility - awaitility - ${avaitility.version} - test - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - org.assertj - assertj-core - ${assertj.version} - test - - - - - 3.5 - 4.1 - 4.01 - 1.7.0 - 3.6.1 - - + + 4.0.0 + core-java-collections + 0.1.0-SNAPSHOT + jar + core-java-collections + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + net.sourceforge.collections + collections-generic + ${collections-generic.version} + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.eclipse.collections + eclipse-collections + ${eclipse.collections.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.openjdk.jmh + jmh-core + ${openjdk.jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${openjdk.jmh.version} + + + org.apache.commons + commons-exec + 1.3 + + + + one.util + streamex + 0.6.5 + + + + + 1.19 + 1.2.0 + 3.5 + 4.1 + 4.01 + 1.7.0 + 3.6.1 + 7.1.0 + + diff --git a/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningArrays.java b/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningArrays.java new file mode 100644 index 0000000000..2ad48033c0 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningArrays.java @@ -0,0 +1,39 @@ +package com.baeldung.combiningcollections; + +import java.util.Arrays; +import java.util.stream.Stream; + +import org.apache.commons.lang3.ArrayUtils; + +import com.google.common.collect.ObjectArrays; + +public class CombiningArrays { + + public static Object[] usingNativeJava(Object[] first, Object[] second) { + Object[] combined = new Object[first.length + second.length]; + System.arraycopy(first, 0, combined, 0, first.length); + System.arraycopy(second, 0, combined, first.length, second.length); + return combined; + } + + public static Object[] usingJava8ObjectStream(Object[] first, Object[] second) { + Object[] combined = Stream.concat(Arrays.stream(first), Arrays.stream(second)).toArray(); + return combined; + } + + public static Object[] usingJava8FlatMaps(Object[] first, Object[] second) { + Object[] combined = Stream.of(first, second).flatMap(Stream::of).toArray(String[]::new); + return combined; + } + + public static Object[] usingApacheCommons(Object[] first, Object[] second) { + Object[] combined = ArrayUtils.addAll(first, second); + return combined; + } + + public static Object[] usingGuava(Object[] first, Object[] second) { + Object [] combined = ObjectArrays.concat(first, second, Object.class); + return combined; + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningLists.java b/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningLists.java new file mode 100644 index 0000000000..3fdf672758 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningLists.java @@ -0,0 +1,46 @@ +package com.baeldung.combiningcollections; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.collections4.ListUtils; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +public class CombiningLists { + + public static List usingNativeJava(List first, List second) { + List combined = new ArrayList<>(); + combined.addAll(first); + combined.addAll(second); + return combined; + } + + public static List usingJava8ObjectStream(List first, List second) { + List combined = Stream.concat(first.stream(), second.stream()).collect(Collectors.toList()); + return combined; + } + + public static List usingJava8FlatMaps(List first, List second) { + List combined = Stream.of(first, second).flatMap(Collection::stream).collect(Collectors.toList()); + return combined; + } + + public static List usingApacheCommons(List first, List second) { + List combined = ListUtils.union(first, second); + return combined; + } + + public static List usingGuava(List first, List second) { + Iterable combinedIterables = Iterables.unmodifiableIterable( + Iterables.concat(first, second)); + + List combined = Lists.newArrayList(combinedIterables); + return combined; + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningMaps.java b/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningMaps.java new file mode 100644 index 0000000000..d8bbd01ed3 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningMaps.java @@ -0,0 +1,47 @@ +package com.baeldung.combiningcollections; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.exec.util.MapUtils; + +import com.google.common.collect.ImmutableMap; + +public class CombiningMaps { + + public static Map usingPlainJava(Map first, Map second) { + Map combined = new HashMap<>(); + combined.putAll(first); + combined.putAll(second); + return combined; + } + + public static Map usingJava8ForEach(Map first, Map second) { + second.forEach((key, value) -> first.merge(key, value, String::concat)); + return first; + } + + public static Map usingJava8FlatMaps(Map first, Map second) { + Map combined = Stream.of(first, second).map(Map::entrySet).flatMap(Collection::stream) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, String::concat)); + return combined; + + } + + public static Map usingApacheCommons(Map first, Map second) { + Map combined = MapUtils.merge(first, second); + return combined; + } + + public static Map usingGuava(Map first, Map second) { + Map combined = ImmutableMap.builder() + .putAll(first) + .putAll(second) + .build(); + return combined; + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningSets.java b/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningSets.java new file mode 100644 index 0000000000..5f531c1d43 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/combiningcollections/CombiningSets.java @@ -0,0 +1,42 @@ +package com.baeldung.combiningcollections; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.collections4.SetUtils; + +import com.google.common.collect.Sets; + +public class CombiningSets { + + public static Set usingNativeJava(Set first, Set second) { + Set combined = new HashSet<>(); + combined.addAll(first); + combined.addAll(second); + return combined; + } + + public static Set usingJava8ObjectStream(Set first, Set second) { + Set combined = Stream.concat(first.stream(), second.stream()).collect(Collectors.toSet()); + return combined; + } + + public static Set usingJava8FlatMaps(Set first, Set second) { + Set combined = Stream.of(first, second).flatMap(Collection::stream).collect(Collectors.toSet()); + return combined; + } + + public static Set usingApacheCommons(Set first, Set second) { + Set combined = SetUtils.union(first, second); + return combined; + } + + public static Set usingGuava(Set first, Set second) { + Set combined = Sets.union(first, second); + return combined; + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java b/core-java-collections/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java new file mode 100644 index 0000000000..5c9464182e --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/convertcollectiontoarraylist/Foo.java @@ -0,0 +1,52 @@ +package com.baeldung.convertcollectiontoarraylist; + +/** + * This POJO is the element type of our collection. It has a deepCopy() method. + * + * @author chris + */ +public class Foo { + + private int id; + private String name; + private Foo parent; + + public Foo() { + } + + public Foo(int id, String name, Foo parent) { + this.id = id; + this.name = name; + this.parent = parent; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Foo getParent() { + return parent; + } + + public void setParent(Foo parent) { + this.parent = parent; + } + + public Foo deepCopy() { + return new Foo( + this.id, this.name, this.parent != null ? this.parent.deepCopy() : null); + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/convertlisttomap/Animal.java b/core-java-collections/src/main/java/com/baeldung/convertlisttomap/Animal.java new file mode 100644 index 0000000000..b8eddf71a5 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/convertlisttomap/Animal.java @@ -0,0 +1,27 @@ +package com.baeldung.convertlisttomap; + +public class Animal { + private int id; + private String name; + + public Animal(int id, String name) { + this.id = id; + this.setName(name); + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/convertlisttomap/ConvertListToMapService.java b/core-java-collections/src/main/java/com/baeldung/convertlisttomap/ConvertListToMapService.java new file mode 100644 index 0000000000..6527d35742 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/convertlisttomap/ConvertListToMapService.java @@ -0,0 +1,42 @@ +package com.baeldung.convertlisttomap; + +import com.google.common.collect.Maps; +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class ConvertListToMapService { + + public Map convertListBeforeJava8(List list) { + + Map map = new HashMap<>(); + + for (Animal animal : list) { + map.put(animal.getId(), animal); + } + return map; + } + + public Map convertListAfterJava8(List list) { + Map map = list.stream().collect(Collectors.toMap(Animal::getId, animal -> animal)); + return map; + } + + public Map convertListWithGuava(List list) { + + Map map = Maps.uniqueIndex(list, Animal::getId); + return map; + } + + public Map convertListWithApacheCommons(List list) { + + Map map = new HashMap<>(); + + MapUtils.populateMap(map, list, Animal::getId); + + return map; + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/enumset/EnumSets.java b/core-java-collections/src/main/java/com/baeldung/enumset/EnumSets.java new file mode 100644 index 0000000000..7b93ed8737 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/enumset/EnumSets.java @@ -0,0 +1,45 @@ +package com.baeldung.enumset; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +public class EnumSets { + + public enum Color { + RED, YELLOW, GREEN, BLUE, BLACK, WHITE + } + + public static void main(String[] args) { + EnumSet allColors = EnumSet.allOf(Color.class); + System.out.println(allColors); + + EnumSet noColors = EnumSet.noneOf(Color.class); + System.out.println(noColors); + + EnumSet blackAndWhite = EnumSet.of(Color.BLACK, Color.WHITE); + System.out.println(blackAndWhite); + + EnumSet noBlackOrWhite = EnumSet.complementOf(blackAndWhite); + System.out.println(noBlackOrWhite); + + EnumSet range = EnumSet.range(Color.YELLOW, Color.BLUE); + System.out.println(range); + + EnumSet blackAndWhiteCopy = EnumSet.copyOf(EnumSet.of(Color.BLACK, Color.WHITE)); + System.out.println(blackAndWhiteCopy); + + List colorsList = new ArrayList<>(); + colorsList.add(Color.RED); + EnumSet listCopy = EnumSet.copyOf(colorsList); + System.out.println(listCopy); + + EnumSet set = EnumSet.noneOf(Color.class); + set.add(Color.RED); + set.add(Color.YELLOW); + set.contains(Color.RED); + set.forEach(System.out::println); + set.remove(Color.RED); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/findanelement/Customer.java b/core-java-collections/src/main/java/com/baeldung/findanelement/Customer.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/findanelement/Customer.java rename to core-java-collections/src/main/java/com/baeldung/findanelement/Customer.java diff --git a/core-java-8/src/main/java/com/baeldung/findanelement/FindACustomerInGivenList.java b/core-java-collections/src/main/java/com/baeldung/findanelement/FindACustomerInGivenList.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/findanelement/FindACustomerInGivenList.java rename to core-java-collections/src/main/java/com/baeldung/findanelement/FindACustomerInGivenList.java diff --git a/core-java-8/src/main/java/com/baeldung/hashtable/Word.java b/core-java-collections/src/main/java/com/baeldung/hashtable/Word.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/hashtable/Word.java rename to core-java-collections/src/main/java/com/baeldung/hashtable/Word.java diff --git a/core-java-8/src/main/java/com/baeldung/iterators/Iterators.java b/core-java-collections/src/main/java/com/baeldung/iterators/Iterators.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/iterators/Iterators.java rename to core-java-collections/src/main/java/com/baeldung/iterators/Iterators.java diff --git a/core-java-collections/src/main/java/com/baeldung/java/filtering/CollectionUtilsCollectionFilter.java b/core-java-collections/src/main/java/com/baeldung/java/filtering/CollectionUtilsCollectionFilter.java new file mode 100644 index 0000000000..58f9f6af54 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/filtering/CollectionUtilsCollectionFilter.java @@ -0,0 +1,16 @@ +package com.baeldung.java.filtering; + +import java.util.Collection; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.Predicate; + +public class CollectionUtilsCollectionFilter { + + static public Collection findEvenNumbers(Collection baseCollection) { + Predicate apacheEventNumberPredicate = item -> item % 2 == 0; + + CollectionUtils.filter(baseCollection, apacheEventNumberPredicate); + return baseCollection; + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/java/filtering/EclipseCollectionsCollectionFilter.java b/core-java-collections/src/main/java/com/baeldung/java/filtering/EclipseCollectionsCollectionFilter.java new file mode 100644 index 0000000000..981d6ca241 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/filtering/EclipseCollectionsCollectionFilter.java @@ -0,0 +1,32 @@ +package com.baeldung.java.filtering; + +import java.util.Collection; + +import org.eclipse.collections.api.block.predicate.Predicate; +import org.eclipse.collections.impl.factory.Lists; +import org.eclipse.collections.impl.utility.Iterate; + +public class EclipseCollectionsCollectionFilter { + + static public Collection findEvenNumbers(Collection baseCollection) { + Predicate eclipsePredicate = item -> item % 2 == 0; + Collection filteredList = Lists.mutable.ofAll(baseCollection) + .select(eclipsePredicate); + + return filteredList; + } + + static public Collection findEvenNumbersUsingIterate(Collection baseCollection) { + Predicate eclipsePredicate = new Predicate() { + private static final long serialVersionUID = 1L; + + @Override + public boolean accept(Integer arg0) { + return arg0 % 2 == 0; + } + }; + Collection filteredList = Iterate.select(baseCollection, eclipsePredicate); + + return filteredList; + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/java/filtering/GuavaCollectionFilter.java b/core-java-collections/src/main/java/com/baeldung/java/filtering/GuavaCollectionFilter.java new file mode 100644 index 0000000000..88338fd6d4 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/filtering/GuavaCollectionFilter.java @@ -0,0 +1,17 @@ +package com.baeldung.java.filtering; + +import java.util.Collection; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; + +public class GuavaCollectionFilter { + + static public Collection findEvenNumbers(Collection baseCollection) { + Predicate guavaPredicate = item -> item % 2 == 0; + + Collection filteredCollection = Collections2.filter(baseCollection, guavaPredicate); + return filteredCollection; + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/java/filtering/StreamsCollectionFilter.java b/core-java-collections/src/main/java/com/baeldung/java/filtering/StreamsCollectionFilter.java new file mode 100644 index 0000000000..f074f74199 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/filtering/StreamsCollectionFilter.java @@ -0,0 +1,26 @@ +package com.baeldung.java.filtering; + +import java.util.Collection; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class StreamsCollectionFilter { + + public static Collection filterCollectionHelperMethod(Collection baseCollection, Predicate predicate) { + return baseCollection.stream() + .filter(predicate) + .collect(Collectors.toList()); + } + + static public Collection findEvenNumbersUsingHelperMethod(Collection baseCollection) { + return filterCollectionHelperMethod(baseCollection, item -> item % 2 == 0); + } + + static public Collection findEvenNumbers(Collection baseCollection) { + Predicate streamsPredicate = item -> item % 2 == 0; + + return baseCollection.stream() + .filter(streamsPredicate) + .collect(Collectors.toList()); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/java/list/CopyListService.java b/core-java-collections/src/main/java/com/baeldung/java/list/CopyListService.java new file mode 100644 index 0000000000..5c92d856aa --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/list/CopyListService.java @@ -0,0 +1,73 @@ +package com.baeldung.java.list; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CopyListService { + + public List copyListByConstructor(List source) { + return new ArrayList(source); + } + + public List copyListByConstructorAndEditOneFlowerInTheNewList(List source) { + List flowers = new ArrayList<>(source); + if(flowers.size() > 0) { + flowers.get(0).setPetals(flowers.get(0).getPetals() * 3); + } + + return flowers; + } + + public List copyListByAddAllMethod(List source) { + List flowers = new ArrayList<>(); + flowers.addAll(source); + return flowers; + } + + public List copyListByAddAllMethodAndEditOneFlowerInTheNewList(List source) { + List flowers = new ArrayList<>(); + flowers.addAll(source); + + if(flowers.size() > 0) { + flowers.get(0).setPetals(flowers.get(0).getPetals() * 3); + } + + return flowers; + } + + public List copyListByCopyMethod(List source, List dest) { + Collections.copy(dest, source); + return dest; + } + + public List copyListByStream(List source) { + return source.stream().collect(Collectors.toList()); + } + + public List copyListByStreamAndSkipFirstElement(List source) { + return source.stream().skip(1).collect(Collectors.toList()); + } + + public List copyListByStreamWithFilter(List source, Integer moreThanPetals) { + return source.stream().filter(f -> f.getPetals() > moreThanPetals).collect(Collectors.toList()); + } + + public List copyListByStreamWithOptional(List source) { + return Optional.ofNullable(source) + .map(List::stream) + .orElseGet(Stream::empty) + .collect(Collectors.toList()); + } + + public List copyListByStreamWithOptionalAndSkip(List source) { + return Optional.ofNullable(source) + .map(List::stream) + .orElseGet(Stream::empty) + .skip(1) + .collect(Collectors.toList()); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/java/list/Flower.java b/core-java-collections/src/main/java/com/baeldung/java/list/Flower.java new file mode 100644 index 0000000000..eb897ea72f --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/list/Flower.java @@ -0,0 +1,28 @@ +package com.baeldung.java.list; + +public class Flower { + + private String name; + private int petals; + + public Flower(String name, int petals) { + this.name = name; + this.petals = petals; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getPetals() { + return petals; + } + + public void setPetals(int petals) { + this.petals = petals; + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/java/map/MapUtil.java b/core-java-collections/src/main/java/com/baeldung/java/map/MapUtil.java new file mode 100644 index 0000000000..688c7592f3 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/map/MapUtil.java @@ -0,0 +1,44 @@ +/** + * + */ +package com.baeldung.java.map; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.stream.Stream; + +/** + * @author swpraman + * + */ +public class MapUtil { + + public static Stream keys(Map map, V value) { + return map.entrySet() + .stream() + .filter(entry -> value.equals(entry.getValue())) + .map(Map.Entry::getKey); + } + + public static Set getKeys(Map map, V value) { + Set keys = new HashSet<>(); + for (Entry entry : map.entrySet()) { + if (entry.getValue().equals(value)) { + keys.add(entry.getKey()); + } + } + return keys; + } + + public static K getKey(Map map, V value) { + for (Entry entry : map.entrySet()) { + if (entry.getValue().equals(value)) { + return entry.getKey(); + } + } + return null; + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/java/map/initialize/MapInitializer.java b/core-java-collections/src/main/java/com/baeldung/java/map/initialize/MapInitializer.java new file mode 100644 index 0000000000..4dbaceac62 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/map/initialize/MapInitializer.java @@ -0,0 +1,80 @@ +package com.baeldung.java.map.initialize; + +import java.util.AbstractMap; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class MapInitializer { + + public static Map articleMapOne; + static { + articleMapOne = new HashMap<>(); + articleMapOne.put("ar01", "Intro to Map"); + articleMapOne.put("ar02", "Some article"); + } + + public static Map createSingletonMap() { + Map passwordMap = Collections.singletonMap("username1", "password1"); + return passwordMap; + + } + + public Map createEmptyMap() { + Map emptyMap = Collections.emptyMap(); + return emptyMap; + } + + public Map createUsingDoubleBrace() { + Map doubleBraceMap = new HashMap() { + + /** + * + */ + private static final long serialVersionUID = 1L; + + { + put("key1", "value1"); + put("key2", "value2"); + } + }; + return doubleBraceMap; + } + + public Map createMapUsingStreamStringArray() { + Map map = Stream.of(new String[][] { { "Hello", "World" }, { "John", "Doe" }, }) + .collect(Collectors.toMap(data -> data[0], data -> data[1])); + + return map; + } + + public Map createMapUsingStreamObjectArray() { + Map map = Stream.of(new Object[][] { { "data1", 1 }, { "data2", 2 }, }) + .collect(Collectors.toMap(data -> (String) data[0], data -> (Integer) data[1])); + + return map; + } + + public Map createMapUsingStreamSimpleEntry() { + Map map = Stream.of(new AbstractMap.SimpleEntry<>("idea", 1), new AbstractMap.SimpleEntry<>("mobile", 2)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + return map; + } + + public Map createMapUsingStreamSimpleImmutableEntry() { + Map map = Stream.of(new AbstractMap.SimpleImmutableEntry<>("idea", 1), new AbstractMap.SimpleImmutableEntry<>("mobile", 2)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + return map; + } + + public Map createImmutableMapWithStreams() { + Map map = Stream.of(new String[][] { { "Hello", "World" }, { "John", "Doe" }, }) + .collect(Collectors.collectingAndThen(Collectors.toMap(data -> data[0], data -> data[1]), Collections:: unmodifiableMap)); + return map; + + } +} diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/Car.java b/core-java-collections/src/main/java/com/baeldung/java_8_features/Car.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/Car.java rename to core-java-collections/src/main/java/com/baeldung/java_8_features/Car.java diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/Person.java b/core-java-collections/src/main/java/com/baeldung/java_8_features/Person.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/Person.java rename to core-java-collections/src/main/java/com/baeldung/java_8_features/Person.java diff --git a/core-java-collections/src/main/java/com/baeldung/list/list/listoflist/Pen.java b/core-java-collections/src/main/java/com/baeldung/list/listoflist/Pen.java similarity index 100% rename from core-java-collections/src/main/java/com/baeldung/list/list/listoflist/Pen.java rename to core-java-collections/src/main/java/com/baeldung/list/listoflist/Pen.java diff --git a/core-java-collections/src/main/java/com/baeldung/list/list/listoflist/Pencil.java b/core-java-collections/src/main/java/com/baeldung/list/listoflist/Pencil.java similarity index 100% rename from core-java-collections/src/main/java/com/baeldung/list/list/listoflist/Pencil.java rename to core-java-collections/src/main/java/com/baeldung/list/listoflist/Pencil.java diff --git a/core-java-collections/src/main/java/com/baeldung/list/list/listoflist/Rubber.java b/core-java-collections/src/main/java/com/baeldung/list/listoflist/Rubber.java similarity index 100% rename from core-java-collections/src/main/java/com/baeldung/list/list/listoflist/Rubber.java rename to core-java-collections/src/main/java/com/baeldung/list/listoflist/Rubber.java diff --git a/core-java-collections/src/main/java/com/baeldung/list/list/listoflist/Stationery.java b/core-java-collections/src/main/java/com/baeldung/list/listoflist/Stationery.java similarity index 100% rename from core-java-collections/src/main/java/com/baeldung/list/list/listoflist/Stationery.java rename to core-java-collections/src/main/java/com/baeldung/list/listoflist/Stationery.java diff --git a/core-java-collections/src/main/java/com/baeldung/list/removeall/RemoveAll.java b/core-java-collections/src/main/java/com/baeldung/list/removeall/RemoveAll.java new file mode 100644 index 0000000000..d5f9cf4b4e --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/list/removeall/RemoveAll.java @@ -0,0 +1,111 @@ +package com.baeldung.list.removeall; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class RemoveAll { + + static void removeWithWhileLoopPrimitiveElement(List list, int element) { + while (list.contains(element)) { + list.remove(element); + } + } + + static void removeWithWhileLoopNonPrimitiveElement(List list, Integer element) { + while (list.contains(element)) { + list.remove(element); + } + } + + static void removeWithWhileLoopStoringFirstOccurrenceIndex(List list, Integer element) { + int index; + while ((index = list.indexOf(element)) >= 0) { + list.remove(index); + } + } + + static void removeWithCallingRemoveUntilModifies(List list, Integer element) { + while (list.remove(element)) + ; + } + + static void removeWithStandardForLoopUsingIndex(List list, int element) { + for (int i = 0; i < list.size(); i++) { + if (Objects.equals(element, list.get(i))) { + list.remove(i); + } + } + } + + static void removeWithForLoopDecrementOnRemove(List list, int element) { + for (int i = 0; i < list.size(); i++) { + if (Objects.equals(element, list.get(i))) { + list.remove(i); + i--; + } + } + } + + static void removeWithForLoopIncrementIfRemains(List list, int element) { + for (int i = 0; i < list.size();) { + if (Objects.equals(element, list.get(i))) { + list.remove(i); + } else { + i++; + } + } + } + + static void removeWithForEachLoop(List list, int element) { + for (Integer number : list) { + if (Objects.equals(number, element)) { + list.remove(number); + } + } + } + + static void removeWithIterator(List list, int element) { + for (Iterator i = list.iterator(); i.hasNext();) { + Integer number = i.next(); + if (Objects.equals(number, element)) { + i.remove(); + } + } + } + + static List removeWithCollectingAndReturningRemainingElements(List list, int element) { + List remainingElements = new ArrayList<>(); + for (Integer number : list) { + if (!Objects.equals(number, element)) { + remainingElements.add(number); + } + } + return remainingElements; + } + + static void removeWithCollectingRemainingElementsAndAddingToOriginalList(List list, int element) { + List remainingElements = new ArrayList<>(); + for (Integer number : list) { + if (!Objects.equals(number, element)) { + remainingElements.add(number); + } + } + + list.clear(); + list.addAll(remainingElements); + } + + static List removeWithStreamFilter(List list, Integer element) { + return list.stream() + .filter(e -> !Objects.equals(e, element)) + .collect(Collectors.toList()); + } + + static void removeWithRemoveIf(List list, Integer element) { + list.removeIf(n -> Objects.equals(n, element)); + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java new file mode 100644 index 0000000000..052cfb8bad --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/map/java_8/MergeMaps.java @@ -0,0 +1,105 @@ +package com.baeldung.map.java_8; + +import com.baeldung.sort.Employee; +import one.util.streamex.EntryStream; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class MergeMaps { + + private static Map map1 = new HashMap<>(); + private static Map map2 = new HashMap<>(); + + public static void main(String[] args) { + + initialize(); + + mergeFunction(); + + streamConcat(); + + streamOf(); + + streamEx(); + + streamMerge(); + } + + private static void streamMerge() { + + Map map3 = map2.entrySet() + .stream() + .collect( + Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (v1, v2) -> new Employee(v1.getId(), v2.getName()), + () -> new HashMap<>(map1) + ) + ); + + System.out.println(map3); + } + + private static void streamEx() { + Map map3 = EntryStream.of(map1) + .append(EntryStream.of(map2)) + .toMap((e1, e2) -> e1); + + System.out.println(map3); + + } + + private static void streamOf() { + Map map3 = Stream.of(map1, map2) + .flatMap(map -> map.entrySet().stream()) + .collect( + Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (v1, v2) -> new Employee(v1.getId(), v2.getName()) + ) + ); + + map3.entrySet().forEach(System.out::println); + } + + private static void streamConcat() { + Map result = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (value1, value2) -> new Employee(value2.getId(), value1.getName()) + )); + + result.entrySet().forEach(System.out::println); + } + + private static void mergeFunction() { + Map map3 = new HashMap<>(map1); + + map2.forEach( + (key, value) -> map3.merge(key, value, (v1, v2) -> + new Employee(v1.getId(), v2.getName())) + ); + + map3.entrySet().forEach(System.out::println); + } + + + private static void initialize() { + Employee employee1 = new Employee(1L, "Henry"); + map1.put(employee1.getName(), employee1); + Employee employee2 = new Employee(22L, "Annie"); + map1.put(employee2.getName(), employee2); + Employee employee3 = new Employee(8L, "John"); + map1.put(employee3.getName(), employee3); + + Employee employee4 = new Employee(2L, "George"); + map2.put(employee4.getName(), employee4); + Employee employee5 = new Employee(3L, "Henry"); + map2.put(employee5.getName(), employee5); + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/map/util/MapMax.java b/core-java-collections/src/main/java/com/baeldung/map/util/MapMax.java new file mode 100644 index 0000000000..93a98ba6fd --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/map/util/MapMax.java @@ -0,0 +1,96 @@ +package com.baeldung.map.util; + +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; + +public class MapMax { + + public > V maxUsingIteration(Map map) { + + Map.Entry maxEntry = null; + + for (Map.Entry entry : map.entrySet()) { + + if (maxEntry == null || entry.getValue() + .compareTo(maxEntry.getValue()) > 0) { + maxEntry = entry; + } + } + + return maxEntry.getValue(); + } + + public > V maxUsingCollectionsMax(Map map) { + + Entry maxEntry = Collections.max(map.entrySet(), new Comparator>() { + public int compare(Entry e1, Entry e2) { + return e1.getValue() + .compareTo(e2.getValue()); + } + }); + + return maxEntry.getValue(); + } + + public > V maxUsingCollectionsMaxAndLambda(Map map) { + + Entry maxEntry = Collections.max(map.entrySet(), (Entry e1, Entry e2) -> e1.getValue() + .compareTo(e2.getValue())); + + return maxEntry.getValue(); + } + + public > V maxUsingCollectionsMaxAndMethodReference(Map map) { + + Entry maxEntry = Collections.max(map.entrySet(), Comparator.comparing(Map.Entry::getValue)); + + return maxEntry.getValue(); + } + + public > V maxUsingStreamAndLambda(Map map) { + + Optional> maxEntry = map.entrySet() + .stream() + .max((Entry e1, Entry e2) -> e1.getValue() + .compareTo(e2.getValue())); + + return maxEntry.get() + .getValue(); + } + + public > V maxUsingStreamAndMethodReference(Map map) { + + Optional> maxEntry = map.entrySet() + .stream() + .max(Comparator.comparing(Map.Entry::getValue)); + + return maxEntry.get() + .getValue(); + } + + public static void main(String[] args) { + + Map map = new HashMap(); + + map.put(1, 3); + map.put(2, 4); + map.put(3, 5); + map.put(4, 6); + map.put(5, 7); + + MapMax mapMax = new MapMax(); + + System.out.println(mapMax.maxUsingIteration(map)); + System.out.println(mapMax.maxUsingCollectionsMax(map)); + System.out.println(mapMax.maxUsingCollectionsMaxAndLambda(map)); + System.out.println(mapMax.maxUsingCollectionsMaxAndMethodReference(map)); + System.out.println(mapMax.maxUsingStreamAndLambda(map)); + System.out.println(mapMax.maxUsingStreamAndMethodReference(map)); + + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java b/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java new file mode 100644 index 0000000000..2405c26aac --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNull.java @@ -0,0 +1,19 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.stream.Stream; +import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; + +public class NullSafeCollectionStreamsUsingCommonsEmptyIfNull { + + /** + * This method shows how to make a null safe stream from a collection through the use of + * emptyIfNull() method from Apache Commons CollectionUtils library + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return emptyIfNull(collection).stream(); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java b/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java new file mode 100644 index 0000000000..da767d4563 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainer.java @@ -0,0 +1,21 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Stream; + +public class NullSafeCollectionStreamsUsingJava8OptionalContainer { + + /** + * This method shows how to make a null safe stream from a collection through the use of + * Java SE 8’s Optional Container + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return Optional.ofNullable(collection) + .map(Collection::stream) + .orElseGet(Stream::empty); + } +} \ No newline at end of file diff --git a/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java b/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java new file mode 100644 index 0000000000..0c10f1cebc --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheck.java @@ -0,0 +1,19 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Collection; +import java.util.stream.Stream; + +public class NullSafeCollectionStreamsUsingNullDereferenceCheck { + + /** + * This method shows how to make a null safe stream from a collection through the use of a check + * to prevent null dereferences + * + * @param collection The collection that is to be converted into a stream + * @return The stream that has been created from the collection or an empty stream if the collection is null + */ + public Stream collectionAsStream(Collection collection) { + return collection == null ? Stream.empty() : collection.stream(); + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/performance/ArrayListBenchmark.java b/core-java-collections/src/main/java/com/baeldung/performance/ArrayListBenchmark.java new file mode 100644 index 0000000000..dddd85007d --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/performance/ArrayListBenchmark.java @@ -0,0 +1,77 @@ +package com.baeldung.performance; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 10) +public class ArrayListBenchmark { + + @State(Scope.Thread) + public static class MyState { + + List employeeList = new ArrayList<>(); + //LinkedList employeeList = new LinkedList<>(); + + long iterations = 100000; + + Employee employee = new Employee(100L, "Harry"); + + int employeeIndex = -1; + + @Setup(Level.Trial) + public void setUp() { + for (long i = 0; i < iterations; i++) { + employeeList.add(new Employee(i, "John")); + } + + employeeList.add(employee); + employeeIndex = employeeList.indexOf(employee); + } + } + + @Benchmark + public void testAddAt(ArrayListBenchmark.MyState state) { + state.employeeList.add((int) (state.iterations), new Employee(state.iterations, "John")); + } + + @Benchmark + public boolean testContains(ArrayListBenchmark.MyState state) { + return state.employeeList.contains(state.employee); + } + + @Benchmark + public int testIndexOf(ArrayListBenchmark.MyState state) { + return state.employeeList.indexOf(state.employee); + } + + @Benchmark + public Employee testGet(ArrayListBenchmark.MyState state) { + return state.employeeList.get(state.employeeIndex); + } + + @Benchmark + public boolean testRemove(ArrayListBenchmark.MyState state) { + return state.employeeList.remove(state.employee); + } + +// @Benchmark +// public void testAdd(ArrayListBenchmark.MyState state) { +// state.employeeList.add(new Employee(state.iterations + 1, "John")); +// } + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(ArrayListBenchmark.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/performance/CollectionsBenchmark.java b/core-java-collections/src/main/java/com/baeldung/performance/CollectionsBenchmark.java new file mode 100644 index 0000000000..921e1608ea --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/performance/CollectionsBenchmark.java @@ -0,0 +1,59 @@ +package com.baeldung.performance; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 5) +public class CollectionsBenchmark { + + @State(Scope.Thread) + public static class MyState { + private Set employeeSet = new HashSet<>(); + private List employeeList = new ArrayList<>(); + + private long iterations = 10000; + + private Employee employee = new Employee(100L, "Harry"); + + @Setup(Level.Trial) + public void setUp() { + + for (long i = 0; i < iterations; i++) { + employeeSet.add(new Employee(i, "John")); + employeeList.add(new Employee(i, "John")); + } + + employeeList.add(employee); + employeeSet.add(employee); + } + } + + @Benchmark + public boolean testArrayList(MyState state) { + return state.employeeList.contains(state.employee); + } + + @Benchmark + public boolean testHashSet(MyState state) { + return state.employeeSet.contains(state.employee); + } + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(CollectionsBenchmark.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/performance/CopyOnWriteBenchmark.java b/core-java-collections/src/main/java/com/baeldung/performance/CopyOnWriteBenchmark.java new file mode 100644 index 0000000000..30c50291dd --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/performance/CopyOnWriteBenchmark.java @@ -0,0 +1,78 @@ +package com.baeldung.performance; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 10) +public class CopyOnWriteBenchmark { + + @State(Scope.Thread) + public static class MyState { + + CopyOnWriteArrayList employeeList = new CopyOnWriteArrayList<>(); + + long iterations = 100000; + + Employee employee = new Employee(100L, "Harry"); + + int employeeIndex = -1; + + @Setup(Level.Trial) + public void setUp() { + for (long i = 0; i < iterations; i++) { + employeeList.add(new Employee(i, "John")); + } + + employeeList.add(employee); + + employeeIndex = employeeList.indexOf(employee); + } + } + + @Benchmark + public void testAdd(CopyOnWriteBenchmark.MyState state) { + state.employeeList.add(new Employee(state.iterations + 1, "John")); + } + + @Benchmark + public void testAddAt(CopyOnWriteBenchmark.MyState state) { + state.employeeList.add((int) (state.iterations), new Employee(state.iterations, "John")); + } + + @Benchmark + public boolean testContains(CopyOnWriteBenchmark.MyState state) { + return state.employeeList.contains(state.employee); + } + + @Benchmark + public int testIndexOf(CopyOnWriteBenchmark.MyState state) { + return state.employeeList.indexOf(state.employee); + } + + @Benchmark + public Employee testGet(CopyOnWriteBenchmark.MyState state) { + return state.employeeList.get(state.employeeIndex); + } + + @Benchmark + public boolean testRemove(CopyOnWriteBenchmark.MyState state) { + return state.employeeList.remove(state.employee); + } + + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(CopyOnWriteBenchmark.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/performance/Employee.java b/core-java-collections/src/main/java/com/baeldung/performance/Employee.java new file mode 100644 index 0000000000..1ed4410371 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/performance/Employee.java @@ -0,0 +1,55 @@ +package com.baeldung.performance; + +public class Employee { + + private Long id; + private String name; + + public Employee(Long id, String name) { + this.name = name; + this.id = id; + } + + 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; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Employee employee = (Employee) o; + + if (!id.equals(employee.id)) return false; + return name.equals(employee.name); + + } + + @Override + public int hashCode() { + int result = id.hashCode(); + result = 31 * result + name.hashCode(); + return result; + } + + @Override + public String toString() { + return "Employee{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/performance/HashMapBenchmark.java b/core-java-collections/src/main/java/com/baeldung/performance/HashMapBenchmark.java new file mode 100644 index 0000000000..085daaceb7 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/performance/HashMapBenchmark.java @@ -0,0 +1,73 @@ +package com.baeldung.performance; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 10) +public class HashMapBenchmark { + + @State(Scope.Thread) + public static class MyState { + + Map employeeMap = new HashMap<>(); + //LinkedHashMap employeeMap = new LinkedHashMap<>(); + //IdentityHashMap employeeMap = new IdentityHashMap<>(); + //WeakHashMap employeeMap = new WeakHashMap<>(); + //ConcurrentHashMap employeeMap = new ConcurrentHashMap<>(); + //ConcurrentSkipListMap employeeMap = new ConcurrentSkipListMap <>(); + + // TreeMap + + long iterations = 100000; + + Employee employee = new Employee(100L, "Harry"); + + int employeeIndex = -1; + + @Setup(Level.Trial) + public void setUp() { + for (long i = 0; i < iterations; i++) { + employeeMap.put(i, new Employee(i, "John")); + } + + //employeeMap.put(iterations, employee); + } + } + + @Benchmark + public Employee testGet(HashMapBenchmark.MyState state) { + return state.employeeMap.get(state.iterations); + } + + @Benchmark + public Employee testRemove(HashMapBenchmark.MyState state) { + return state.employeeMap.remove(state.iterations); + } + + @Benchmark + public Employee testPut(HashMapBenchmark.MyState state) { + return state.employeeMap.put(state.employee.getId(), state.employee); + } + + @Benchmark + public Boolean testContainsKey(HashMapBenchmark.MyState state) { + return state.employeeMap.containsKey(state.employee.getId()); + } + + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(HashMapBenchmark.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/performance/SetBenchMark.java b/core-java-collections/src/main/java/com/baeldung/performance/SetBenchMark.java new file mode 100644 index 0000000000..f70bab4fcf --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/performance/SetBenchMark.java @@ -0,0 +1,66 @@ +package com.baeldung.performance; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@Warmup(iterations = 10) +public class SetBenchMark { + + @State(Scope.Thread) + public static class MyState { + + //Set employeeSet = new HashSet<>(); + LinkedHashSet employeeSet = new LinkedHashSet<>(); + //ConcurrentSkipListSet employeeSet = new ConcurrentSkipListSet <>(); + + // TreeSet  + + long iterations = 1000; + Employee employee = new Employee(100L, "Harry"); + + @Setup(Level.Trial) + public void setUp() { + for (long i = 0; i < iterations; i++) { + employeeSet.add(new Employee(i, "John")); + } + + //employeeSet.add(employee); + } + } + + @Benchmark + public boolean testAdd(SetBenchMark.MyState state) { + return state.employeeSet.add(state.employee); + } + + @Benchmark + public Boolean testContains(SetBenchMark.MyState state) { + return state.employeeSet.contains(state.employee); + } + + @Benchmark + public boolean testRemove(SetBenchMark.MyState state) { + return state.employeeSet.remove(state.employee); + } + + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(SetBenchMark.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/sort/Employee.java b/core-java-collections/src/main/java/com/baeldung/sort/Employee.java new file mode 100644 index 0000000000..b5e56f6141 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/sort/Employee.java @@ -0,0 +1,60 @@ +package com.baeldung.sort; + +public class Employee implements Comparable { + + private Long id; + private String name; + + public Employee(Long id, String name) { + this.name = name; + this.id = id; + } + + 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; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Employee employee = (Employee) o; + + if (!id.equals(employee.id)) return false; + return name.equals(employee.name); + + } + + @Override + public int hashCode() { + int result = id.hashCode(); + result = 31 * result + name.hashCode(); + return result; + } + + @Override + public String toString() { + return "Employee{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + + @Override + public int compareTo(Employee employee) { + return (int)(this.id - employee.getId()); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/sort/SortHashMap.java b/core-java-collections/src/main/java/com/baeldung/sort/SortHashMap.java new file mode 100644 index 0000000000..b8a2b32060 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/sort/SortHashMap.java @@ -0,0 +1,104 @@ +package com.baeldung.sort; + +import com.google.common.base.Functions; +import com.google.common.collect.ImmutableSortedMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; + +import java.util.*; +import java.util.stream.Collectors; + +public class SortHashMap { + + private static Map map = new HashMap<>(); + + public static void main(String[] args) { + + initialize(); + + treeMapSortByKey(); + + arrayListSortByValue(); + arrayListSortByKey(); + + sortStream(); + + sortGuava(); + + addDuplicates(); + + treeSetByKey(); + treeSetByValue(); + + } + + private static void sortGuava() { + final Ordering naturalOrdering = + Ordering.natural().onResultOf(Functions.forMap(map, null)); + + System.out.println(ImmutableSortedMap.copyOf(map, naturalOrdering)); + } + + private static void sortStream() { + map.entrySet().stream() + .sorted(Map.Entry.comparingByKey().reversed()) + .forEach(System.out::println); + + Map result = map.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, + (oldValue, newValue) -> oldValue, LinkedHashMap::new)); + + result.entrySet().forEach(System.out::println); + } + + private static void treeSetByValue() { + SortedSet values = new TreeSet<>(map.values()); + System.out.println(values); + } + + private static void treeSetByKey() { + SortedSet keysSet = new TreeSet<>(map.keySet()); + System.out.println(keysSet); + } + + private static void treeMapSortByKey() { + TreeMap sorted = new TreeMap<>(map); + sorted.putAll(map); + + sorted.entrySet().forEach(System.out::println); + + } + + private static void arrayListSortByValue() { + List employeeById = new ArrayList<>(map.values()); + + Collections.sort(employeeById); + + System.out.println(employeeById); + } + + private static void arrayListSortByKey() { + List employeeByKey = new ArrayList<>(map.keySet()); + Collections.sort(employeeByKey); + System.out.println(employeeByKey); + } + + private static void initialize() { + Employee employee1 = new Employee(1L, "Mher"); + map.put(employee1.getName(), employee1); + Employee employee2 = new Employee(22L, "Annie"); + map.put(employee2.getName(), employee2); + Employee employee3 = new Employee(8L, "John"); + map.put(employee3.getName(), employee3); + Employee employee4 = new Employee(2L, "George"); + map.put(employee4.getName(), employee4); + } + + private static void addDuplicates() { + Employee employee5 = new Employee(1L, "Mher"); + map.put(employee5.getName(), employee5); + Employee employee6 = new Employee(22L, "Annie"); + map.put(employee6.getName(), employee6); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/synchronizedcollections/application/Application.java b/core-java-collections/src/main/java/com/baeldung/synchronizedcollections/application/Application.java new file mode 100644 index 0000000000..1840c125d0 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/synchronizedcollections/application/Application.java @@ -0,0 +1,18 @@ +package com.baeldung.synchronizedcollections.application; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.logging.Logger; + +public class Application { + + private static final Logger LOGGER = Logger.getLogger(Application.class.getName()); + + public static void main(String[] args) throws InterruptedException { + List syncCollection = Collections.synchronizedList(Arrays.asList(1, 2, 3, 4, 5, 6)); + synchronized (syncCollection) { + syncCollection.forEach((e) -> {LOGGER.info(e.toString());}); + } + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/thread_safe_lifo/DequeBasedSynchronizedStack.java b/core-java-collections/src/main/java/com/baeldung/thread_safe_lifo/DequeBasedSynchronizedStack.java new file mode 100644 index 0000000000..ea1618b0f2 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/thread_safe_lifo/DequeBasedSynchronizedStack.java @@ -0,0 +1,36 @@ +package com.baeldung.thread_safe_lifo; + +import java.util.ArrayDeque; + +/** + * Deque Based Stack implementation. + */ +public class DequeBasedSynchronizedStack { + + // Internal Deque which gets decorated for synchronization. + private ArrayDeque dequeStore = new ArrayDeque<>(); + + public DequeBasedSynchronizedStack(int initialCapacity) { + this.dequeStore = new ArrayDeque<>(initialCapacity); + } + + public DequeBasedSynchronizedStack() { + + } + + public synchronized T pop() { + return this.dequeStore.pop(); + } + + public synchronized void push(T element) { + this.dequeStore.push(element); + } + + public synchronized T peek() { + return this.dequeStore.peek(); + } + + public synchronized int size() { + return this.dequeStore.size(); + } +} diff --git a/core-java-collections/src/main/resources/logback.xml b/core-java-collections/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-java-collections/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-collections/src/test/java/com/baeldung/collection/ClearVsRemoveAllUnitTest.java b/core-java-collections/src/test/java/com/baeldung/collection/ClearVsRemoveAllUnitTest.java new file mode 100644 index 0000000000..8b0a7ef0db --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/collection/ClearVsRemoveAllUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.collection; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Unit tests demonstrating differences between ArrayList#clear() and ArrayList#removeAll() + */ +class ClearVsRemoveAllUnitTest { + + /* + * Tests + */ + @Test + void givenArrayListWithElements_whenClear_thenListBecomesEmpty() { + Collection collection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); + + collection.clear(); + + assertTrue(collection.isEmpty()); + } + + @Test + void givenTwoArrayListsWithCommonElements_whenRemoveAll_thenFirstListMissElementsFromSecondList() { + Collection firstCollection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); + Collection secondCollection = new ArrayList<>(Arrays.asList(3, 4, 5, 6, 7)); + + firstCollection.removeAll(secondCollection); + + assertEquals(Arrays.asList(1, 2), firstCollection); + assertEquals(Arrays.asList(3, 4, 5, 6, 7), secondCollection); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/collection/CollectionsEmpty.java b/core-java-collections/src/test/java/com/baeldung/collection/CollectionsEmpty.java new file mode 100644 index 0000000000..86a262107d --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/collection/CollectionsEmpty.java @@ -0,0 +1,26 @@ +package com.baeldung.collection; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; +import org.junit.Assert; +import org.junit.Test; + +public class CollectionsEmpty { + + @Test + public void givenArrayList_whenAddingElement_addsNewElement() { + ArrayList mutableList = new ArrayList<>(); + mutableList.add("test"); + + Assert.assertEquals(mutableList.size(), 1); + Assert.assertEquals(mutableList.get(0), "test"); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenCollectionsEmptyList_whenAddingElement_throwsUnsupportedOperationException() { + List immutableList = Collections.emptyList(); + immutableList.add("test"); + } + +} \ No newline at end of file diff --git a/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningArraysUnitTest.java b/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningArraysUnitTest.java new file mode 100644 index 0000000000..3b80d773ad --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningArraysUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.combiningcollections; + +import static org.junit.Assert.*; +import org.junit.Test; + +public class CombiningArraysUnitTest { + private static final String first[] = { + "One", + "Two", + "Three" + }; + + private static final String second[] = { + "Four", + "Five", + "Six" + }; + + private static final String expected[] = { + "One", + "Two", + "Three", + "Four", + "Five", + "Six" + }; + + @Test + public void givenTwoArrays_whenUsingNativeJava_thenArraysCombined() { + assertArrayEquals(expected, CombiningArrays.usingNativeJava(first, second)); + } + + @Test + public void givenTwoArrays_whenUsingObjectStreams_thenArraysCombined() { + assertArrayEquals(expected, CombiningArrays.usingJava8ObjectStream(first, second)); + } + + @Test + public void givenTwoArrays_whenUsingFlatMaps_thenArraysCombined() { + assertArrayEquals(expected, CombiningArrays.usingJava8FlatMaps(first, second)); + } + + @Test + public void givenTwoArrays_whenUsingApacheCommons_thenArraysCombined() { + assertArrayEquals(expected, CombiningArrays.usingApacheCommons(first, second)); + } + + @Test + public void givenTwoArrays_whenUsingGuava_thenArraysCombined() { + assertArrayEquals(expected, CombiningArrays.usingGuava(first, second)); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningListsUnitTest.java b/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningListsUnitTest.java new file mode 100644 index 0000000000..c5851d7daf --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningListsUnitTest.java @@ -0,0 +1,57 @@ +package com.baeldung.combiningcollections; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class CombiningListsUnitTest { + private static final List first = Arrays.asList(new Object[]{ + "One", + "Two", + "Three" + }); + + private static final List second = Arrays.asList(new Object[]{ + "Four", + "Five", + "Six" + }); + + private static final List expected = Arrays.asList(new Object[]{ + "One", + "Two", + "Three", + "Four", + "Five", + "Six" + }); + + @Test + public void givenTwoLists_whenUsingNativeJava_thenArraysCombined() { + assertThat(CombiningLists.usingNativeJava(first, second), is(expected)); + } + + @Test + public void givenTwoLists_whenUsingObjectStreams_thenArraysCombined() { + assertThat(CombiningLists.usingJava8ObjectStream(first, second), is(expected)); + } + + @Test + public void givenTwoLists_whenUsingFlatMaps_thenArraysCombined() { + assertThat(CombiningLists.usingJava8FlatMaps(first, second), is(expected)); + } + + @Test + public void givenTwoLists_whenUsingApacheCommons_thenArraysCombined() { + assertThat(CombiningLists.usingApacheCommons(first, second), is(expected)); + } + + @Test + public void givenTwoLists_whenUsingGuava_thenArraysCombined() { + assertThat(CombiningLists.usingGuava(first, second), is(expected)); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningMapsUnitTest.java b/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningMapsUnitTest.java new file mode 100644 index 0000000000..3fa9cc7dc4 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningMapsUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.combiningcollections; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; + +public class CombiningMapsUnitTest { + private static final Map first = new HashMap<>(); + private static final Map second = new HashMap<>(); + private static Map expected = new HashMap<>(); + + static { + first.put("one", "first String"); + first.put("two", "second String"); + + second.put("three", "third String"); + second.put("four", "fourth String"); + + expected.put("one", "first String"); + expected.put("two", "second String"); + expected.put("three", "third String"); + expected.put("four", "fourth String"); + } + + @Test + public void givenTwoMaps_whenUsingNativeJava_thenMapsCombined() { + assertThat(CombiningMaps.usingPlainJava(first, second), is(expected)); + } + + + @Test + public void givenTwoMaps_whenUsingForEach_thenMapsCombined() { + assertThat(CombiningMaps.usingJava8ForEach(first, second), is(expected)); + } + + @Test + public void givenTwoMaps_whenUsingFlatMaps_thenMapsCombined() { + assertThat(CombiningMaps.usingJava8FlatMaps(first, second), is(expected)); + } + + @Test + public void givenTwoMaps_whenUsingApacheCommons_thenMapsCombined() { + assertThat(CombiningMaps.usingApacheCommons(first, second), is(expected)); + } + + @Test + public void givenTwoMaps_whenUsingGuava_thenMapsCombined() { + assertThat(CombiningMaps.usingGuava(first, second), is(expected)); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningSetsUnitTest.java b/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningSetsUnitTest.java new file mode 100644 index 0000000000..330827bdc2 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/combiningcollections/CombiningSetsUnitTest.java @@ -0,0 +1,45 @@ + +package com.baeldung.combiningcollections; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +public class CombiningSetsUnitTest { + private static final Set first = new HashSet(Arrays.asList(new Object[] { "One", "Two", "Three" })); + + private static final Set second = new HashSet(Arrays.asList(new Object[] { "Four", "Five", "Six" })); + + private static final Set expected = new HashSet(Arrays + .asList(new Object[] { "One", "Two", "Three", "Four", "Five", "Six" })); + + @Test + public void givenTwoSets_whenUsingNativeJava_thenArraysCombined() { + assertThat(CombiningSets.usingNativeJava(first, second), is(expected)); + } + + @Test + public void givenTwoSets_whenUsingObjectStreams_thenArraysCombined() { + assertThat(CombiningSets.usingJava8ObjectStream(first, second), is(expected)); + } + + @Test + public void givenTwoSets_whenUsingFlatMaps_thenArraysCombined() { + assertThat(CombiningSets.usingJava8FlatMaps(first, second), is(expected)); + } + + @Test + public void givenTwoSets_whenUsingApacheCommons_thenArraysCombined() { + assertThat(CombiningSets.usingApacheCommons(first, second), is(expected)); + } + + @Test + public void givenTwoSets_whenUsingGuava_thenArraysCombined() { + assertThat(CombiningSets.usingGuava(first, second), is(expected)); + } +} \ No newline at end of file diff --git a/core-java-collections/src/test/java/com/baeldung/convertcollectiontoarraylist/FooUnitTest.java b/core-java-collections/src/test/java/com/baeldung/convertcollectiontoarraylist/FooUnitTest.java new file mode 100644 index 0000000000..5be4121bc7 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/convertcollectiontoarraylist/FooUnitTest.java @@ -0,0 +1,148 @@ +package com.baeldung.convertcollectiontoarraylist; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import static java.util.stream.Collectors.toCollection; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author chris + */ +public class FooUnitTest { + private static Collection srcCollection = new HashSet<>(); + + public FooUnitTest() { + } + + @BeforeClass + public static void setUpClass() { + int i = 0; + Foo john = new Foo(i++, "John", null); + Foo mary = new Foo(i++, "Mary", null); + Foo sam = new Foo(i++, "Sam", john); + Foo alice = new Foo(i++, "Alice", john); + Foo buffy = new Foo(i++, "Buffy", sam); + srcCollection.add(john); + srcCollection.add(mary); + srcCollection.add(sam); + srcCollection.add(alice); + srcCollection.add(buffy); + + // make sure the collection isn't sorted accidentally + assertFalse("Oops: source collection is already sorted!", isSorted(srcCollection)); + } + + /** + * Section 3. Using the ArrayList Constructor + */ + @Test + public void whenUsingConstructor_thenVerifyShallowCopy() { + ArrayList newList = new ArrayList<>(srcCollection); + verifyShallowCopy(srcCollection, newList); + } + + /** + * Section 4. Using the Streams API + */ + @Test + public void whenUsingStream_thenVerifyShallowCopy() { + ArrayList newList = srcCollection.stream().collect(toCollection(ArrayList::new)); + + verifyShallowCopy(srcCollection, newList); + } + + /** + * Section 5. Deep Copy + */ + @Test + public void whenUsingDeepCopy_thenVerifyDeepCopy() { + ArrayList newList = srcCollection.stream() + .map(foo -> foo.deepCopy()) + .collect(toCollection(ArrayList::new)); + + verifyDeepCopy(srcCollection, newList); + } + + /** + * Section 6. Controlling the List Order + */ + @Test + public void whenUsingSortedStream_thenVerifySortOrder() { + ArrayList newList = srcCollection.stream() + .sorted(Comparator.comparing(Foo::getName)) + .collect(toCollection(ArrayList::new)); + + assertTrue("ArrayList is not sorted by name", isSorted(newList)); + } + + /** + * Verify that the contents of the two collections are the same + * @param a + * @param b + */ + private void verifyShallowCopy(Collection a, Collection b) { + assertEquals("Collections have different lengths", a.size(), b.size()); + Iterator iterA = a.iterator(); + Iterator iterB = b.iterator(); + while (iterA.hasNext()) { + // use '==' to test instance identity + assertTrue("Foo instances differ!", iterA.next() == iterB.next()); + } + } + + /** + * Verify that the contents of the two collections are the same + * @param a + * @param b + */ + private void verifyDeepCopy(Collection a, Collection b) { + assertEquals("Collections have different lengths", a.size(), b.size()); + Iterator iterA = a.iterator(); + Iterator iterB = b.iterator(); + while (iterA.hasNext()) { + Foo nextA = iterA.next(); + Foo nextB = iterB.next(); + // should not be same instance + assertFalse("Foo instances are the same!", nextA == nextB); + // but should have same content + assertFalse("Foo instances have different content!", fooDiff(nextA, nextB)); + } + } + + /** + * Return true if the contents of a and b differ. Test parent recursively + * @param a + * @param b + * @return False if the two items are the same + */ + private boolean fooDiff(Foo a, Foo b) { + if (a != null && b != null) { + return a.getId() != b.getId() + || !a.getName().equals(b.getName()) + || fooDiff(a.getParent(), b.getParent()); + } + return !(a == null && b == null); + } + + /** + * @param c collection of Foo + * @return true if the collection is sorted by name + */ + private static boolean isSorted(Collection c) { + String prevName = null; + for (Foo foo : c) { + if (prevName == null || foo.getName().compareTo(prevName) > 0) { + prevName = foo.getName(); + } else { + return false; + } + } + return true; + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/convertlisttomap/ConvertListToMapServiceUnitTest.java b/core-java-collections/src/test/java/com/baeldung/convertlisttomap/ConvertListToMapServiceUnitTest.java new file mode 100644 index 0000000000..4d783f4525 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/convertlisttomap/ConvertListToMapServiceUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.convertlisttomap; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; + +public class ConvertListToMapServiceUnitTest { + List list; + + private ConvertListToMapService convertListService; + + @Before + public void init() { + this.convertListService = new ConvertListToMapService(); + this.list = new ArrayList<>(); + + Animal cat = new Animal(1, "Cat"); + list.add(cat); + Animal dog = new Animal(2, "Dog"); + list.add(dog); + Animal pig = new Animal(3, "Pig"); + list.add(pig); + Animal cow = new Animal(4, "Cow"); + list.add(cow); + Animal goat = new Animal(5, "Goat"); + list.add(goat); + + } + + @Test + public void givenAList_whenConvertBeforeJava8_thenReturnMapWithTheSameElements() { + + Map map = convertListService.convertListBeforeJava8(list); + + assertThat(map.values(), containsInAnyOrder(list.toArray())); + } + + @Test + public void givenAList_whenConvertAfterJava8_thenReturnMapWithTheSameElements() { + + Map map = convertListService.convertListAfterJava8(list); + + assertThat(map.values(), containsInAnyOrder(list.toArray())); + } + + @Test + public void givenAList_whenConvertWithGuava_thenReturnMapWithTheSameElements() { + + Map map = convertListService.convertListWithGuava(list); + + assertThat(map.values(), containsInAnyOrder(list.toArray())); + } + + @Test + public void givenAList_whenConvertWithApacheCommons_thenReturnMapWithTheSameElements() { + + Map map = convertListService.convertListWithApacheCommons(list); + + assertThat(map.values(), containsInAnyOrder(list.toArray())); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/convertlisttomap/ConvertListWithDiplicatedIdToMapServiceUnitTest.java b/core-java-collections/src/test/java/com/baeldung/convertlisttomap/ConvertListWithDiplicatedIdToMapServiceUnitTest.java new file mode 100644 index 0000000000..6e766433d1 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/convertlisttomap/ConvertListWithDiplicatedIdToMapServiceUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.convertlisttomap; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasSize; + +public class ConvertListWithDiplicatedIdToMapServiceUnitTest { + List duplicatedIdList; + + private ConvertListToMapService convertListService = new ConvertListToMapService(); + + @Before + public void init() { + + this.duplicatedIdList = new ArrayList<>(); + + Animal cat = new Animal(1, "Cat"); + duplicatedIdList.add(cat); + Animal dog = new Animal(2, "Dog"); + duplicatedIdList.add(dog); + Animal pig = new Animal(3, "Pig"); + duplicatedIdList.add(pig); + Animal cow = new Animal(4, "Cow"); + duplicatedIdList.add(cow); + Animal goat = new Animal(4, "Goat"); + duplicatedIdList.add(goat); + + } + + @Test + public void givenADupIdList_whenConvertBeforeJava8_thenReturnMapWithRewrittenElement() { + + Map map = convertListService.convertListBeforeJava8(duplicatedIdList); + + assertThat(map.values(), hasSize(4)); + assertThat(map.values(), hasItem(duplicatedIdList.get(4))); + } + + @Test + public void givenADupIdList_whenConvertWithApacheCommons_thenReturnMapWithRewrittenElement() { + + Map map = convertListService.convertListWithApacheCommons(duplicatedIdList); + + assertThat(map.values(), hasSize(4)); + assertThat(map.values(), hasItem(duplicatedIdList.get(4))); + } + + @Test(expected = IllegalStateException.class) + public void givenADupIdList_whenConvertAfterJava8_thenException() { + + convertListService.convertListAfterJava8(duplicatedIdList); + } + + @Test(expected = IllegalArgumentException.class) + public void givenADupIdList_whenConvertWithGuava_thenException() { + + convertListService.convertListWithGuava(duplicatedIdList); + + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/findItems/FindItemsBasedOnOtherStreamUnitTest.java b/core-java-collections/src/test/java/com/baeldung/findItems/FindItemsBasedOnOtherStreamUnitTest.java new file mode 100644 index 0000000000..326ea9fbe4 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/findItems/FindItemsBasedOnOtherStreamUnitTest.java @@ -0,0 +1,89 @@ +package com.baeldung.findItems; + +import static org.junit.Assert.assertEquals; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Test; + +public class FindItemsBasedOnOtherStreamUnitTest { + + private List employeeList = new ArrayList(); + + private List departmentList = new ArrayList(); + + @Test + public void givenDepartmentList_thenEmployeeListIsFilteredCorrectly() { + Integer expectedId = 1002; + + populate(employeeList, departmentList); + + List filteredList = employeeList.stream() + .filter(empl -> departmentList.stream() + .anyMatch(dept -> dept.getDepartment() + .equals("sales") && empl.getEmployeeId() + .equals(dept.getEmployeeId()))) + .collect(Collectors.toList()); + + assertEquals(expectedId, filteredList.get(0) + .getEmployeeId()); + } + + private void populate(List EmplList, List deptList) { + Employee employee1 = new Employee(1001, "empl1"); + Employee employee2 = new Employee(1002, "empl2"); + Employee employee3 = new Employee(1003, "empl3"); + + Collections.addAll(EmplList, employee1, employee2, employee3); + + Department department1 = new Department(1002, "sales"); + Department department2 = new Department(1003, "marketing"); + Department department3 = new Department(1004, "sales"); + + Collections.addAll(deptList, department1, department2, department3); + } +} + +class Employee { + private Integer employeeId; + private String employeeName; + + Employee(Integer employeeId, String employeeName) { + super(); + this.employeeId = employeeId; + this.employeeName = employeeName; + } + + Integer getEmployeeId() { + return employeeId; + } + + public String getEmployeeName() { + return employeeName; + } + +} + +class Department { + private Integer employeeId; + private String department; + + Department(Integer employeeId, String department) { + super(); + this.employeeId = employeeId; + this.department = department; + } + + Integer getEmployeeId() { + return employeeId; + } + + String getDepartment() { + return department; + } + +} \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/findanelement/FindACustomerInGivenListUnitTest.java b/core-java-collections/src/test/java/com/baeldung/findanelement/FindACustomerInGivenListUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/findanelement/FindACustomerInGivenListUnitTest.java rename to core-java-collections/src/test/java/com/baeldung/findanelement/FindACustomerInGivenListUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/hashtable/HashtableUnitTest.java b/core-java-collections/src/test/java/com/baeldung/hashtable/HashtableUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/hashtable/HashtableUnitTest.java rename to core-java-collections/src/test/java/com/baeldung/hashtable/HashtableUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/iterators/IteratorsUnitTest.java b/core-java-collections/src/test/java/com/baeldung/iterators/IteratorsUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/iterators/IteratorsUnitTest.java rename to core-java-collections/src/test/java/com/baeldung/iterators/IteratorsUnitTest.java diff --git a/core-java-collections/src/test/java/com/baeldung/java/filtering/CollectionFiltersUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java/filtering/CollectionFiltersUnitTest.java new file mode 100644 index 0000000000..b30805d471 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/filtering/CollectionFiltersUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.java.filtering; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +@RunWith(JUnitPlatform.class) +public class CollectionFiltersUnitTest { + + private static final Collection BASE_INTEGER_COLLECTION = Arrays.asList(9, 14, 2, 7, 1, 5, 8); + private static final Collection EXPECTED_EVEN_FILTERED_COLLECTION = Arrays.asList(14, 2, 8); + + @Test + public void givenAStringCollection_whenFilteringFourLetterWords_thenObtainTheFilteredCollection() { + final Collection baseStrings = Arrays.asList("java", "baeldung", "type", "example", "other"); + + Collection filtered = StreamsCollectionFilter.filterCollectionHelperMethod(baseStrings, item -> item.length() == 4); + + assertThat(filtered).containsExactlyInAnyOrder("java", "type"); + } + + @Test + public void givenAnIntegerCollection_whenFilteringEvenValues_thenObtainTheFilteredCollectionForAllCases() { + Collection filteredWithStreams1 = StreamsCollectionFilter.findEvenNumbers(BASE_INTEGER_COLLECTION); + Collection filteredWithCollectionUtils = CollectionUtilsCollectionFilter.findEvenNumbers(new ArrayList<>(BASE_INTEGER_COLLECTION)); + Collection filteredWithEclipseCollections = EclipseCollectionsCollectionFilter.findEvenNumbers(BASE_INTEGER_COLLECTION); + Collection filteredWithEclipseCollectionsUsingIterate = EclipseCollectionsCollectionFilter.findEvenNumbersUsingIterate(BASE_INTEGER_COLLECTION); + Collection filteredWithGuava = GuavaCollectionFilter.findEvenNumbers(BASE_INTEGER_COLLECTION); + + assertThat(filteredWithStreams1).hasSameElementsAs(filteredWithCollectionUtils) + .hasSameElementsAs(filteredWithEclipseCollections) + .hasSameElementsAs(filteredWithEclipseCollectionsUsingIterate) + .hasSameElementsAs(filteredWithEclipseCollectionsUsingIterate) + .hasSameElementsAs(filteredWithGuava) + .hasSameElementsAs(EXPECTED_EVEN_FILTERED_COLLECTION); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/java/list/CopyListServiceUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java/list/CopyListServiceUnitTest.java new file mode 100644 index 0000000000..bc1611038c --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/list/CopyListServiceUnitTest.java @@ -0,0 +1,133 @@ +package com.baeldung.java.list; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class CopyListServiceUnitTest { + + List flowers; + + private CopyListService copyListService; + + @Before + public void init() { + this.copyListService = new CopyListService(); + this.flowers = new ArrayList<>(); + + Flower poppy = new Flower("Poppy", 12); + flowers.add(poppy); + Flower anemone = new Flower("Anemone", 8); + flowers.add(anemone); + Flower catmint = new Flower("Catmint", 12); + flowers.add(catmint); + Flower diascia = new Flower("Diascia", 5); + flowers.add(diascia); + Flower iris = new Flower("Iris", 3); + flowers.add(iris); + Flower pansy = new Flower("Pansy", 5); + flowers.add(pansy); + } + + @Test + public void givenAList_whenListDoesNotHaveNullElements_thenReturnAnotherListWithTheSameElementsByConstructor() { + List copy = copyListService.copyListByConstructor(flowers); + assertEquals(copy.size(), flowers.size()); + assertTrue(copy.containsAll(flowers)); + } + + @Test + public void givenAList_whenListDoesNotHaveNullElements_thenReturnAnotherListWithOneModifiedElementByConstructor() { + List copy = copyListService.copyListByConstructorAndEditOneFlowerInTheNewList(flowers); + assertEquals(copy.size(), flowers.size()); + assertTrue(copy.containsAll(flowers)); + } + + @Test + public void givenAList_whenListDoesNotHaveNullElements_thenReturnAnotherListWithTheSameElementsByAddAllmethod() { + List copy = copyListService.copyListByAddAllMethod(flowers); + assertEquals(copy.size(), flowers.size()); + assertTrue(copy.containsAll(flowers)); + } + + @Test + public void givenAList_whenListDoesNotHaveNullElements_thenReturnAnotherListWithOneModifiedElementByAddAllmethod() { + List copy = copyListService.copyListByAddAllMethodAndEditOneFlowerInTheNewList(flowers); + assertEquals(copy.size(), flowers.size()); + assertTrue(copy.containsAll(flowers)); + } + + @Test + public void givenAList_whenListsHaveSameSize_thenReturnAnotherListWithTheSameElementsByCopyMethod() { + List source = Arrays.asList(1,2,3); + List dest = Arrays.asList(4,5,6); + + dest = copyListService.copyListByCopyMethod(source, dest); + assertEquals(dest.size(), source.size()); + assertTrue(dest.containsAll(source)); + } + + @Test + public void givenAList_whenListsHaveDifferentSize_thenReturnAnotherListWithTheSameElementsByCopyMethod() { + List source = Arrays.asList(1,2,3); + List dest = Arrays.asList(5,6,7,8,9,10); + + dest = copyListService.copyListByCopyMethod(source, dest); + assertNotEquals(dest.size(), source.size()); + assertTrue(dest.containsAll(source)); + } + + @Test + public void givenAList_whenListDoesNotHaveNullElements_thenReturnAnotherListWithTheSameElementsByStreamProcess() { + List copy = copyListService.copyListByStream(flowers); + assertEquals(copy.size(), flowers.size()); + assertTrue(copy.containsAll(flowers)); + } + + @Test + public void givenAList_whenListDoesNotHaveNullElements_thenReturnAnotherListWithOneElementLessByStreamProcess() { + List copy = copyListService.copyListByStreamAndSkipFirstElement(flowers); + assertNotEquals(copy.size(), flowers.size()); + assertEquals(copy.size() + 1, flowers.size()); + assertFalse(copy.containsAll(flowers)); + } + + @Test + public void givenAList_whenListDoesNotHaveNullElements_thenReturnAnotherListWithFilterElementsByStreamProcess() { + List copy = copyListService.copyListByStreamWithFilter(flowers, 5); + assertNotEquals(copy.size(), flowers.size()); + assertEquals(copy.size() + 3, flowers.size()); + assertFalse(copy.containsAll(flowers)); + } + + @Test + public void givenAList_whenListIsNull_thenReturnEmptyListByStreamProcess() { + List copy = copyListService.copyListByStreamWithOptional(null); + assertNotNull(copy); + assertEquals(copy.size(), 0); + } + + @Test + public void givenAList_whenListIsNotNull_thenReturnAnotherListWithTheElementsByStreamProcess() { + List copy = copyListService.copyListByStreamWithOptional(flowers); + assertEquals(copy.size(), flowers.size()); + assertTrue(copy.containsAll(flowers)); + } + + @Test + public void givenAList_whenListIsNotNull_thenReturnAnotherListWithOneElementLessByStreamProcess() { + List copy = copyListService.copyListByStreamWithOptionalAndSkip(flowers); + assertNotEquals(copy.size(), flowers.size()); + assertEquals(copy.size() + 1, flowers.size()); + assertFalse(copy.containsAll(flowers)); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/java/map/KeyCheckUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java/map/KeyCheckUnitTest.java new file mode 100644 index 0000000000..2c97a97690 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/map/KeyCheckUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.java.map; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.Map; + +import org.junit.Test; + +public class KeyCheckUnitTest { + + @Test + public void whenKeyIsPresent_thenContainsKeyReturnsTrue() { + Map map = Collections.singletonMap("key", "value"); + + assertTrue(map.containsKey("key")); + assertFalse(map.containsKey("missing")); + } + + @Test + public void whenKeyHasNullValue_thenGetStillWorks() { + Map map = Collections.singletonMap("nothing", null); + + assertTrue(map.containsKey("nothing")); + assertNull(map.get("nothing")); + } +} \ No newline at end of file diff --git a/core-java-collections/src/test/java/com/baeldung/java/map/MapUtilUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java/map/MapUtilUnitTest.java new file mode 100644 index 0000000000..e31385e972 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/map/MapUtilUnitTest.java @@ -0,0 +1,104 @@ +/** + * + */ +package com.baeldung.java.map; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.bidimap.DualHashBidiMap; +import org.junit.Test; + +import com.google.common.collect.HashBiMap; + +/** + * @author swpraman + * + */ +public class MapUtilUnitTest { + + + @Test + public void whenUsingImperativeWayForSingleKey_shouldReturnSingleKey() { + Map capitalCountryMap = new HashMap<>(); + capitalCountryMap.put("Tokyo", "Japan"); + capitalCountryMap.put("New Delhi", "India"); + assertEquals("New Delhi", MapUtil.getKey(capitalCountryMap, "India")); + } + + @Test + public void whenUsingImperativeWayForAllKeys_shouldReturnAllKeys() { + Map capitalCountryMap = new HashMap<>(); + capitalCountryMap.put("Tokyo", "Japan"); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + capitalCountryMap.put("Pretoria", "South Africa"); + capitalCountryMap.put("Bloemfontein", "South Africa"); + + assertEquals(new HashSet(Arrays.asList( + new String[] {"Cape Town", "Pretoria", "Bloemfontein"})), + MapUtil.getKeys(capitalCountryMap, "South Africa")); + } + + @Test + public void whenUsingFunctionalWayForSingleKey_shouldReturnSingleKey() { + Map capitalCountryMap = new HashMap<>(); + capitalCountryMap.put("Tokyo", "Japan"); + capitalCountryMap.put("Berlin", "Germany"); + assertEquals("Berlin", MapUtil.keys(capitalCountryMap, "Germany").findFirst().get()); + } + + @Test + public void whenUsingFunctionalWayForAllKeys_shouldReturnAllKeys() { + Map capitalCountryMap = new HashMap<>(); + capitalCountryMap.put("Tokyo", "Japan"); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + capitalCountryMap.put("Pretoria", "South Africa"); + capitalCountryMap.put("Bloemfontein", "South Africa"); + assertEquals(new HashSet(Arrays.asList( + new String[] {"Cape Town", "Pretoria", "Bloemfontein"})), + MapUtil.keys(capitalCountryMap, "South Africa").collect(Collectors.toSet())); + } + + @Test + public void whenUsingBidiMap_shouldReturnKey() { + BidiMap capitalCountryMap = new DualHashBidiMap(); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + assertEquals("Berlin", capitalCountryMap.getKey("Germany")); + } + + @Test + public void whenUsingBidiMapAddDuplicateValue_shouldRemoveOldEntry() { + BidiMap capitalCountryMap = new DualHashBidiMap(); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + capitalCountryMap.put("Pretoria", "South Africa"); + assertEquals("Pretoria", capitalCountryMap.getKey("South Africa")); + } + + @Test + public void whenUsingBiMap_shouldReturnKey() { + HashBiMap capitalCountryMap = HashBiMap.create(); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + assertEquals("Berlin", capitalCountryMap.inverse().get("Germany")); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingBiMapAddDuplicateValue_shouldThrowException() { + HashBiMap capitalCountryMap = HashBiMap.create(); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + capitalCountryMap.put("Pretoria", "South Africa"); + assertEquals("Berlin", capitalCountryMap.inverse().get("Germany")); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/java/map/initialize/MapInitializerUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java/map/initialize/MapInitializerUnitTest.java new file mode 100644 index 0000000000..80a8983d6f --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/map/initialize/MapInitializerUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.java.map.initialize; + +import static org.junit.Assert.assertEquals; + +import java.util.Map; + +import org.junit.Test; + +public class MapInitializerUnitTest { + + @Test + public void givenStaticMap_whenUpdated_thenCorrect() { + + MapInitializer.articleMapOne.put("NewArticle1", "Convert array to List"); + + assertEquals(MapInitializer.articleMapOne.get("NewArticle1"), "Convert array to List"); + + } + + @Test(expected=UnsupportedOperationException.class) + public void givenSingleTonMap_whenEntriesAdded_throwsException() { + + Map map = MapInitializer.createSingletonMap(); + map.put("username2", "password2"); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/java/set/HashSetInitalizingUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java/set/HashSetInitalizingUnitTest.java new file mode 100644 index 0000000000..2e736501cf --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/set/HashSetInitalizingUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.java.set; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; + +public class HashSetInitalizingUnitTest { + @Test + public void whenUsingJava_usingArraysStaticMethod_thenCorrectSize() { + Set set = new HashSet<>(Arrays.asList("a", "b", "c")); + assertEquals(3, set.size()); + } + + @Test + public void whenUsingJava_usingAnonymousClass_thenCorrectSize() { + Set set = new HashSet(){{ + add("a"); + add("b"); + add("c"); + }}; + assertEquals(3, set.size()); + } + + @Test + public void whenUsingJava_creatingSingletonSet_thenCorrectSize() { + Set set = Collections.singleton("a"); + assertEquals(1, set.size()); + } + + public static final Set newHashSet(T... objs) { + Set set = new HashSet(); + Collections.addAll(set, objs); + return set; + } + + @Test + public void whenUsingJava_usingCustomStaticUtilMethod_thenCorrectSize() { + Set set = newHashSet("a","b","c"); + assertEquals(3, set.size()); + } + + @Test + public void whenUsingJava8_usingCollectOnStream_thenCorrectSize() { + Set set = Stream.of("a", "b", "c").collect(Collectors.toCollection(HashSet::new)); + assertEquals(3, set.size()); + } + + @Test + public void whenUsingGoogleGuava_createMutableSet_thenCorrectSize() { + Set set = Sets.newHashSet("a", "b", "c"); + assertEquals(3, set.size()); + } + + @Test + public void whenUsingGoogleGuava_createImmutableSet_thenCorrectSize() { + Set set = ImmutableSet.of("a", "b", "c"); + assertEquals(3, set.size()); + } + +} + diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8MaxMinUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java8/Java8MaxMinUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/Java8MaxMinUnitTest.java rename to core-java-collections/src/test/java/com/baeldung/java8/Java8MaxMinUnitTest.java diff --git a/core-java-collections/src/test/java/com/baeldung/list/listoflist/AddElementsToListUnitTest.java b/core-java-collections/src/test/java/com/baeldung/list/listoflist/AddElementsToListUnitTest.java new file mode 100644 index 0000000000..299a87026f --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/list/listoflist/AddElementsToListUnitTest.java @@ -0,0 +1,69 @@ +package com.baeldung.list.listoflist; + +import com.baeldung.java.list.Flower; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import java.util.*; +import static org.junit.Assert.*; + +public class AddElementsToListUnitTest { + + List flowers; + + @Before + public void init() { + this.flowers = new ArrayList<>(Arrays.asList( + new Flower("Poppy", 12), + new Flower("Anemone", 8), + new Flower("Catmint", 12))); + } + @Test + public void givenAList_whenTargetListIsEmpty_thenReturnTargetListWithNewItems() { + List anotherList = new ArrayList<>(); + anotherList.addAll(flowers); + assertEquals(anotherList.size(), flowers.size()); + Assert.assertTrue(anotherList.containsAll(flowers)); + } + @Test + public void givenAList_whenTargetListIsEmpty_thenReturnTargetListWithOneModifiedElementByConstructor() { + List anotherList = new ArrayList<>(); + anotherList.addAll(flowers); + Flower flower = anotherList.get(0); + flower.setPetals(flowers.get(0).getPetals() * 3); + assertEquals(anotherList.size(), flowers.size()); + Assert.assertTrue(anotherList.containsAll(flowers)); + } + @Test + public void givenAListAndElements_whenUseCollectionsAddAll_thenAddElementsToTargetList() { + List target = new ArrayList<>(); + Collections.addAll(target, flowers.get(0), flowers.get(1), flowers.get(2), flowers.get(0)); + assertEquals(target.size(), 4); + } + @Test + public void givenTwoList_whenSourceListDoesNotHaveNullElements_thenAddElementsToTargetListSkipFirstElementByStreamProcess() { + List flowerVase = new ArrayList<>(); + flowers.stream() + .skip(1) + .forEachOrdered(flowerVase::add); + assertEquals(flowerVase.size() + 1, flowers.size()); + assertFalse(flowerVase.containsAll(flowers)); + } + @Test + public void givenTwoList_whenSourceListDoesNotHaveNullElements_thenAddElementsToTargetListFilteringElementsByStreamProcess() { + List flowerVase = new ArrayList<>(); + flowers.stream() + .filter(f -> f.getPetals() > 10) + .forEachOrdered(flowerVase::add); + assertEquals(flowerVase.size() + 1, flowers.size()); + assertFalse(flowerVase.containsAll(flowers)); + } + @Test + public void givenAList_whenListIsNotNull_thenAddElementsToListByStreamProcessWihtOptional() { + List target = new ArrayList<>(); + Optional.ofNullable(flowers) + .ifPresent(target::addAll); + assertNotNull(target); + assertEquals(target.size(), 3); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/list/removeall/RemoveAllUnitTest.java b/core-java-collections/src/test/java/com/baeldung/list/removeall/RemoveAllUnitTest.java new file mode 100644 index 0000000000..c23121053b --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/list/removeall/RemoveAllUnitTest.java @@ -0,0 +1,210 @@ +package com.baeldung.list.removeall; + +import static com.baeldung.list.removeall.RemoveAll.removeWithCallingRemoveUntilModifies; +import static com.baeldung.list.removeall.RemoveAll.removeWithCollectingAndReturningRemainingElements; +import static com.baeldung.list.removeall.RemoveAll.removeWithCollectingRemainingElementsAndAddingToOriginalList; +import static com.baeldung.list.removeall.RemoveAll.removeWithForEachLoop; +import static com.baeldung.list.removeall.RemoveAll.removeWithForLoopDecrementOnRemove; +import static com.baeldung.list.removeall.RemoveAll.removeWithForLoopIncrementIfRemains; +import static com.baeldung.list.removeall.RemoveAll.removeWithIterator; +import static com.baeldung.list.removeall.RemoveAll.removeWithRemoveIf; +import static com.baeldung.list.removeall.RemoveAll.removeWithStandardForLoopUsingIndex; +import static com.baeldung.list.removeall.RemoveAll.removeWithStreamFilter; +import static com.baeldung.list.removeall.RemoveAll.removeWithWhileLoopNonPrimitiveElement; +import static com.baeldung.list.removeall.RemoveAll.removeWithWhileLoopPrimitiveElement; +import static com.baeldung.list.removeall.RemoveAll.removeWithWhileLoopStoringFirstOccurrenceIndex; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.ConcurrentModificationException; +import java.util.List; + +import org.junit.Test; + +public class RemoveAllUnitTest { + + private List list(Integer... elements) { + return new ArrayList<>(Arrays.asList(elements)); + } + + @Test + public void givenAList_whenRemovingElementsWithWhileLoopUsingPrimitiveElement_thenTheResultCorrect() { + // given + List list = list(1, 2, 3); + int valueToRemove = 1; + + // when + assertThatThrownBy(() -> removeWithWhileLoopPrimitiveElement(list, valueToRemove)) + .isInstanceOf(IndexOutOfBoundsException.class); + } + + @Test + public void givenAList_whenRemovingElementsWithWhileLoopUsingNonPrimitiveElement_thenTheResultCorrect() { + // given + List list = list(1, 2, 3); + int valueToRemove = 1; + + // when + removeWithWhileLoopNonPrimitiveElement(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + + @Test + public void givenAList_whenRemovingElementsWithWhileLoopStoringFirstOccurrenceIndex_thenTheResultCorrect() { + // given + List list = list(1, 2, 3); + int valueToRemove = 1; + + // when + removeWithWhileLoopStoringFirstOccurrenceIndex(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + + @Test + public void givenAList_whenRemovingElementsWithCallingRemoveUntilModifies_thenTheResultIsCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + removeWithCallingRemoveUntilModifies(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + + @Test + public void givenAListWithoutDuplication_whenRemovingElementsWithStandardForLoopUsingIndex_thenTheResultIsCorrect() { + // given + List list = list(1, 2, 3); + int valueToRemove = 1; + + // when + removeWithStandardForLoopUsingIndex(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + + @Test + public void givenAListWithAdjacentElements_whenRemovingElementsWithStandardForLoop_thenTheResultIsInCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + removeWithStandardForLoopUsingIndex(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(1, 2, 3)); + } + + @Test + public void givenAListWithAdjacentElements_whenRemovingElementsWithForLoopAndDecrementOnRemove_thenTheResultIsCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + removeWithForLoopDecrementOnRemove(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + + @Test + public void givenAListWithAdjacentElements_whenRemovingElementsWithForLoopAndIncrementIfRemains_thenTheResultIsCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + removeWithForLoopIncrementIfRemains(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + + @Test + public void givenAList_whenRemovingElementsWithForEachLoop_thenExceptionIsThrown() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + assertThatThrownBy(() -> removeWithForEachLoop(list, valueToRemove)) + .isInstanceOf(ConcurrentModificationException.class); + } + + @Test + public void givenAList_whenRemovingElementsWithIterator_thenTheResultIsCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + removeWithIterator(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + + @Test + public void givenAList_whenRemovingElementsWithCollectingAndReturningRemainingElements_thenTheResultIsCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + List result = removeWithCollectingAndReturningRemainingElements(list, valueToRemove); + + // then + assertThat(result).isEqualTo(list(2, 3)); + } + + @Test + public void givenAList_whenRemovingElementsWithCollectingRemainingAndAddingToOriginalList_thenTheResultIsCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + removeWithCollectingRemainingElementsAndAddingToOriginalList(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + + @Test + public void givenAList_whenRemovingElementsWithStreamFilter_thenTheResultIsCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + List result = removeWithStreamFilter(list, valueToRemove); + + // then + assertThat(result).isEqualTo(list(2, 3)); + } + + @Test + public void givenAList_whenRemovingElementsWithCallingRemoveIf_thenTheResultIsCorrect() { + // given + List list = list(1, 1, 2, 3); + int valueToRemove = 1; + + // when + removeWithRemoveIf(list, valueToRemove); + + // then + assertThat(list).isEqualTo(list(2, 3)); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/list/removefirst/RemoveFirstElementUnitTest.java b/core-java-collections/src/test/java/com/baeldung/list/removefirst/RemoveFirstElementUnitTest.java new file mode 100644 index 0000000000..f2b1bd9d88 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/list/removefirst/RemoveFirstElementUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.list.removefirst; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class RemoveFirstElementUnitTest { + + private List list = new ArrayList<>(); + private LinkedList linkedList = new LinkedList<>(); + + @Before + public void init() { + + list.add("cat"); + list.add("dog"); + list.add("pig"); + list.add("cow"); + list.add("goat"); + + linkedList.add("cat"); + linkedList.add("dog"); + linkedList.add("pig"); + linkedList.add("cow"); + linkedList.add("goat"); + } + + @Test + public void givenList_whenRemoveFirst_thenRemoved() { + list.remove(0); + + assertThat(list, hasSize(4)); + assertThat(list, not(contains("cat"))); + } + + @Test + public void givenLinkedList_whenRemoveFirst_thenRemoved() { + + linkedList.removeFirst(); + + assertThat(linkedList, hasSize(4)); + assertThat(linkedList, not(contains("cat"))); + } + + @Test + public void givenStringArray_whenRemovingFirstElement_thenArrayIsSmallerAndElementRemoved() { + String[] stringArray = {"foo", "bar", "baz"}; + + String[] modifiedArray = Arrays.copyOfRange(stringArray, 1, stringArray.length); + + assertThat(modifiedArray.length, is(2)); + assertThat(modifiedArray[0], is("bar")); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/map/util/MapMaxUnitTest.java b/core-java-collections/src/test/java/com/baeldung/map/util/MapMaxUnitTest.java new file mode 100644 index 0000000000..883265cc8b --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/map/util/MapMaxUnitTest.java @@ -0,0 +1,59 @@ +package com.baeldung.map.util; + + + +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +public class MapMaxUnitTest { + + Map map = null; + MapMax mapMax = null; + + + @Before + public void setupTestData() { + map = new HashMap(); + map.put(23, 12); + map.put(46, 24); + map.put(27, 38); + mapMax = new MapMax(); + } + + @Test + public void givenMap_whenIterated_thenReturnMaxValue() { + assertEquals(new Integer(38), mapMax.maxUsingIteration(map)); + } + + @Test + public void givenMap_whenUsingCollectionsMax_thenReturnMaxValue() { + assertEquals(new Integer(38), mapMax.maxUsingCollectionsMax(map)); + } + + @Test + public void givenMap_whenUsingCollectionsMaxAndLambda_thenReturnMaxValue() { + assertEquals(new Integer(38), mapMax.maxUsingCollectionsMaxAndLambda(map)); + } + + @Test + public void givenMap_whenUsingCollectionsMaxAndMethodReference_thenReturnMaxValue() { + assertEquals(new Integer(38), mapMax.maxUsingCollectionsMaxAndMethodReference(map)); + } + + @Test + public void givenMap_whenUsingStreamAndLambda_thenReturnMaxValue() { + assertEquals(new Integer(38), mapMax.maxUsingStreamAndLambda(map)); + } + + @Test + public void givenMap_whenUsingStreamAndMethodReference_thenReturnMaxValue() { + assertEquals(new Integer(38), mapMax.maxUsingStreamAndMethodReference (map)); + } + + +} diff --git a/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java b/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java new file mode 100644 index 0000000000..875045946d --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; +import org.junit.Test; +import static org.junit.Assert.*; + +public class NullSafeCollectionStreamsUsingCommonsEmptyIfNullUnitTest { + + private final NullSafeCollectionStreamsUsingCommonsEmptyIfNull instance = + new NullSafeCollectionStreamsUsingCommonsEmptyIfNull(); + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java b/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java new file mode 100644 index 0000000000..402f1a6a19 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; +import org.junit.Test; +import static org.junit.Assert.*; + +public class NullSafeCollectionStreamsUsingJava8OptionalContainerUnitTest { + + private final NullSafeCollectionStreamsUsingJava8OptionalContainer instance = + new NullSafeCollectionStreamsUsingJava8OptionalContainer(); + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java b/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java new file mode 100644 index 0000000000..bb6152371d --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/nullsafecollectionstreams/NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.nullsafecollectionstreams; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.stream.Stream; +import org.junit.Test; +import static org.junit.Assert.*; + +public class NullSafeCollectionStreamsUsingNullDereferenceCheckUnitTest { + + private final NullSafeCollectionStreamsUsingNullDereferenceCheck instance = + new NullSafeCollectionStreamsUsingNullDereferenceCheck(); + + @Test + public void whenCollectionIsNull_thenExpectAnEmptyStream() { + Collection collection = null; + Stream expResult = Stream.empty(); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + @Test + public void whenCollectionHasElements_thenExpectAStreamOfExactlyTheSameElements() { + Collection collection = Arrays.asList("a", "b", "c"); + Stream expResult = Arrays.stream(new String[] { "a", "b", "c" }); + Stream result = instance.collectionAsStream(collection); + assertStreamEquals(expResult, result); + } + + private static void assertStreamEquals(Stream s1, Stream s2) { + Iterator iter1 = s1.iterator(), iter2 = s2.iterator(); + while (iter1.hasNext() && iter2.hasNext()) + assertEquals(iter1.next(), iter2.next()); + assert !iter1.hasNext() && !iter2.hasNext(); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java b/core-java-collections/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java rename to core-java-collections/src/test/java/com/baeldung/shufflingcollections/ShufflingCollectionsUnitTest.java diff --git a/core-java-collections/src/test/java/com/baeldung/stack_tests/MultithreadingCorrectnessStackUnitTest.java b/core-java-collections/src/test/java/com/baeldung/stack_tests/MultithreadingCorrectnessStackUnitTest.java new file mode 100644 index 0000000000..4550994aa3 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/stack_tests/MultithreadingCorrectnessStackUnitTest.java @@ -0,0 +1,101 @@ +package com.baeldung.stack_tests; + +import com.baeldung.thread_safe_lifo.DequeBasedSynchronizedStack; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayDeque; +import java.util.concurrent.ConcurrentLinkedDeque; + +import static java.util.stream.IntStream.range; + +/** + * Correctness tests for Stack in multi threaded environment. + */ +public class MultithreadingCorrectnessStackUnitTest { + + @Test + public void givenSynchronizedDeque_whenExecutedParallel_thenWorkRight() { + + DequeBasedSynchronizedStack deque = new DequeBasedSynchronizedStack<>(); + + // Serial execution of push on ConcurrentLinkedQueue will always result in correct execution. + range(1, 10000).forEach(value -> deque.push(value)); + + int sum = 0; + while(deque.peek() != null) { + sum += deque.pop(); + } + + Assert.assertEquals(49995000, sum); + + // Parallel execution of push on ConcurrentLinkedQueue will always result in correct execution. + range(1, 10000).parallel().forEach(value -> deque.push(value)); + + sum = 0; + while(deque.peek() != null) { + sum += deque.pop(); + } + + Assert.assertEquals(49995000, sum); + } + + @Test + public void givenConcurrentLinkedQueue_whenExecutedParallel_thenWorkRight() { + + ConcurrentLinkedDeque deque = new ConcurrentLinkedDeque<>(); + + // Serial execution of push on ConcurrentLinkedQueue will always result in correct execution. + range(1, 10000).forEach(value -> deque.push(value)); + + int sum = 0; + while(deque.peek() != null) { + sum += deque.pop(); + } + + Assert.assertEquals(49995000, sum); + + // Parallel execution of push on ConcurrentLinkedQueue will always result in correct execution. + range(1, 10000).parallel().forEach(value -> deque.push(value)); + + sum = 0; + while(deque.peek() != null) { + sum += deque.pop(); + } + + Assert.assertEquals(49995000, sum); + } + + @Test + public void givenArrayDeque_whenExecutedParallel_thenShouldFail() { + + ArrayDeque deque = new ArrayDeque<>(); + + // Serial execution of push on ArrayDeque will always result in correct execution. + range(1, 10000).forEach(value -> deque.push(value)); + + int sum = 0; + while(deque.peek() != null) { + sum += deque.pop(); + } + + Assert.assertEquals(49995000, sum); + + // Parallel execution of push on ArrayDeque will not result in correct execution. + range(1, 10000).parallel().forEach(value -> deque.push(value)); + + sum = 0; + while(deque.peek() != null) { + sum += deque.pop(); + } + + // This shouldn't happen. + if(sum == 49995000) { + System.out.println("Something wrong in the environment, Please try some big value and check"); + // To safe-guard build without test failures. + return; + } + + Assert.assertNotEquals(49995000, sum); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/stack_tests/StackUnitTest.java b/core-java-collections/src/test/java/com/baeldung/stack_tests/StackUnitTest.java new file mode 100644 index 0000000000..07c4760186 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/stack_tests/StackUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.stack_tests; + +import com.baeldung.thread_safe_lifo.DequeBasedSynchronizedStack; +import com.google.common.collect.Streams; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Collections; +import java.util.Stack; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.stream.Stream; + +import static java.util.stream.IntStream.range; + +/** + * These tests are to understand the Stack implementation in Java Collections. + */ +public class StackUnitTest { + + @Test + public void givenStack_whenPushPopPeek_thenWorkRight() { + Stack namesStack = new Stack<>(); + + namesStack.push("Bill Gates"); + namesStack.push("Elon Musk"); + + Assert.assertEquals("Elon Musk", namesStack.peek()); + Assert.assertEquals("Elon Musk", namesStack.pop()); + Assert.assertEquals("Bill Gates", namesStack.pop()); + + Assert.assertEquals(0, namesStack.size()); + } + + @Test + public void givenSynchronizedDeque_whenPushPopPeek_thenWorkRight() { + DequeBasedSynchronizedStack namesStack = new DequeBasedSynchronizedStack<>(); + + namesStack.push("Bill Gates"); + namesStack.push("Elon Musk"); + + Assert.assertEquals("Elon Musk", namesStack.peek()); + Assert.assertEquals("Elon Musk", namesStack.pop()); + Assert.assertEquals("Bill Gates", namesStack.pop()); + + Assert.assertEquals(0, namesStack.size()); + } + + @Test + public void givenConcurrentLinkedDeque_whenPushPopPeek_thenWorkRight() { + ConcurrentLinkedDeque namesStack = new ConcurrentLinkedDeque<>(); + + namesStack.push("Bill Gates"); + namesStack.push("Elon Musk"); + + Assert.assertEquals("Elon Musk", namesStack.peek()); + Assert.assertEquals("Elon Musk", namesStack.pop()); + Assert.assertEquals("Bill Gates", namesStack.pop()); + + Assert.assertEquals(0, namesStack.size()); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedCollectionUnitTest.java b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedCollectionUnitTest.java new file mode 100644 index 0000000000..84feeb6eaa --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedCollectionUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.synchronizedcollections.test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class SynchronizedCollectionUnitTest { + + @Test + public void givenSynchronizedCollection_whenTwoThreadsAddElements_thenCorrectCollectionSize() throws InterruptedException { + Collection syncCollection = Collections.synchronizedCollection(new ArrayList<>()); + + Runnable listOperations = () -> { + syncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6)); + }; + Thread thread1 = new Thread(listOperations); + Thread thread2 = new Thread(listOperations); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + assertThat(syncCollection.size()).isEqualTo(12); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedListUnitTest.java b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedListUnitTest.java new file mode 100644 index 0000000000..68fc3becd4 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedListUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.synchronizedcollections.test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class SynchronizedListUnitTest { + + @Test + public void givenSynchronizedList_whenTwoThreadsAddElements_thenCorrectListSize() throws InterruptedException { + List syncList = Collections.synchronizedList(new ArrayList<>()); + + Runnable listOperations = () -> { + syncList.addAll(Arrays.asList(1, 2, 3, 4, 5, 6)); + }; + Thread thread1 = new Thread(listOperations); + Thread thread2 = new Thread(listOperations); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + assertThat(syncList.size()).isEqualTo(12); + } + + @Test + public void givenStringList_whenTwoThreadsIterateOnSynchronizedList_thenCorrectResult() throws InterruptedException { + List syncCollection = Collections.synchronizedList(Arrays.asList("a", "b", "c")); + List uppercasedCollection = new ArrayList<>(); + + Runnable listOperations = () -> { + synchronized (syncCollection) { + syncCollection.forEach((e) -> { + uppercasedCollection.add(e.toUpperCase()); + }); + } + }; + + Thread thread1 = new Thread(listOperations); + Thread thread2 = new Thread(listOperations); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + assertThat(uppercasedCollection.get(0)).isEqualTo("A"); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedMapUnitTest.java b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedMapUnitTest.java new file mode 100644 index 0000000000..abfb866e9c --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedMapUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.synchronizedcollections.test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class SynchronizedMapUnitTest { + + @Test + public void givenSynchronizedMap_whenTwoThreadsAddElements_thenCorrectMapSize() throws InterruptedException { + Map syncMap = Collections.synchronizedMap(new HashMap<>()); + + Runnable mapOperations = () -> { + syncMap.put(1, "one"); + syncMap.put(2, "two"); + syncMap.put(3, "three"); + + }; + Thread thread1 = new Thread(mapOperations); + Thread thread2 = new Thread(mapOperations); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + assertThat(syncMap.size()).isEqualTo(3); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSetUnitTest.java b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSetUnitTest.java new file mode 100644 index 0000000000..58a33b207d --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSetUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.synchronizedcollections.test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class SynchronizedSetUnitTest { + + @Test + public void givenSynchronizedSet_whenTwoThreadsAddElements_thenCorrectSetSize() throws InterruptedException { + Set syncSet = Collections.synchronizedSet(new HashSet<>()); + + Runnable setOperations = () -> {syncSet.addAll(Arrays.asList(1, 2, 3, 4, 5, 6));}; + Thread thread1 = new Thread(setOperations); + Thread thread2 = new Thread(setOperations); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + assertThat(syncSet.size()).isEqualTo(6); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSortedMapUnitTest.java b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSortedMapUnitTest.java new file mode 100644 index 0000000000..4b0ed6d8c8 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSortedMapUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.synchronizedcollections.test; + +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class SynchronizedSortedMapUnitTest { + + @Test + public void givenSynchronizedSorteMap_whenTwoThreadsAddElements_thenCorrectSortedMapSize() throws InterruptedException { + Map syncSortedMap = Collections.synchronizedSortedMap(new TreeMap<>()); + + Runnable sortedMapOperations = () -> { + syncSortedMap.put(1, "One"); + syncSortedMap.put(2, "Two"); + syncSortedMap.put(3, "Three"); + }; + Thread thread1 = new Thread(sortedMapOperations); + Thread thread2 = new Thread(sortedMapOperations); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + assertThat(syncSortedMap.size()).isEqualTo(3); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSortedSetUnitTest.java b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSortedSetUnitTest.java new file mode 100644 index 0000000000..0e26c6eb1c --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/synchronizedcollections/test/SynchronizedSortedSetUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.synchronizedcollections.test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.SortedSet; +import java.util.TreeSet; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class SynchronizedSortedSetUnitTest { + + @Test + public void givenSynchronizedSortedSet_whenTwoThreadsAddElements_thenCorrectSortedSetSize() throws InterruptedException { + SortedSet syncSortedSet = Collections.synchronizedSortedSet(new TreeSet<>()); + + Runnable sortedSetOperations = () -> {syncSortedSet.addAll(Arrays.asList(1, 2, 3, 4, 5, 6));}; + sortedSetOperations.run(); + sortedSetOperations.run(); + Thread thread1 = new Thread(sortedSetOperations); + Thread thread2 = new Thread(sortedSetOperations); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + assertThat(syncSortedSet.size()).isEqualTo(6); + } +} diff --git a/core-java-collections/src/test/java/org/baeldung/java/collections/CollectionsEmpty.java b/core-java-collections/src/test/java/org/baeldung/java/collections/CollectionsEmpty.java new file mode 100644 index 0000000000..09ecebe47b --- /dev/null +++ b/core-java-collections/src/test/java/org/baeldung/java/collections/CollectionsEmpty.java @@ -0,0 +1,26 @@ +package org.baeldung.java.collections; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; + +class CollectionsEmpty { + + @Test + public void givenArrayList_whenAddingElement_addsNewElement() { + ArrayList mutableList = new ArrayList<>(); + mutableList.add("test"); + + Assert.assertEquals(mutableList.size(), 1); + Assert.assertEquals(mutableList.get(0), "test"); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenCollectionsEmptyList_whenAddingElement_throwsUnsupportedOperationException() { + List immutableList = Collections.emptyList(); + immutableList.add("test"); + } + +} diff --git a/core-java-concurrency-collections/.gitignore b/core-java-concurrency-collections/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/core-java-concurrency-collections/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/core-java-concurrency-collections/README.md b/core-java-concurrency-collections/README.md new file mode 100644 index 0000000000..b982a91861 --- /dev/null +++ b/core-java-concurrency-collections/README.md @@ -0,0 +1,15 @@ +========= + +## Core Java Concurrency Collections Examples + +### Relevant Articles: +- [Guide to java.util.concurrent.BlockingQueue](http://www.baeldung.com/java-blocking-queue) +- [A Guide to ConcurrentMap](http://www.baeldung.com/java-concurrent-map) +- [Guide to PriorityBlockingQueue in Java](http://www.baeldung.com/java-priority-blocking-queue) +- [Avoiding the ConcurrentModificationException in Java](http://www.baeldung.com/java-concurrentmodificationexception) +- [Custom Thread Pools In Java 8 Parallel Streams](http://www.baeldung.com/java-8-parallel-streams-custom-threadpool) +- [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) +- [A Guide to Java SynchronousQueue](http://www.baeldung.com/java-synchronous-queue) +- [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue) +- [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map) +- [Guide to CopyOnWriteArrayList](http://www.baeldung.com/java-copy-on-write-arraylist) diff --git a/core-java-concurrency-collections/pom.xml b/core-java-concurrency-collections/pom.xml new file mode 100644 index 0000000000..9473de8c51 --- /dev/null +++ b/core-java-concurrency-collections/pom.xml @@ -0,0 +1,74 @@ + + 4.0.0 + com.baeldung + core-java-concurrency-collections + 0.1.0-SNAPSHOT + jar + core-java-concurrency-collections + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + + + core-java-concurrency-collections + + + src/main/resources + true + + + + + + + 21.0 + 3.5 + 3.6.1 + 4.1 + 4.01 + + 3.6.1 + 1.7.0 + + + diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java similarity index 79% rename from core-java-concurrency/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java index 052136bfe4..842d4e630e 100644 --- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java +++ b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/blockingqueue/BlockingQueueUsage.java @@ -10,15 +10,18 @@ public class BlockingQueueUsage { int N_CONSUMERS = Runtime.getRuntime().availableProcessors(); int poisonPill = Integer.MAX_VALUE; int poisonPillPerProducer = N_CONSUMERS / N_PRODUCERS; - + int mod = N_CONSUMERS % N_PRODUCERS; BlockingQueue queue = new LinkedBlockingQueue<>(BOUND); - for (int i = 0; i < N_PRODUCERS; i++) { + for (int i = 1; i < N_PRODUCERS; i++) { new Thread(new NumbersProducer(queue, poisonPill, poisonPillPerProducer)).start(); } for (int j = 0; j < N_CONSUMERS; j++) { new Thread(new NumbersConsumer(queue, poisonPill)).start(); } + + new Thread(new NumbersProducer(queue, poisonPill, poisonPillPerProducer+mod)).start(); + } } \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersConsumer.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/blockingqueue/NumbersProducer.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/delayqueue/DelayObject.java b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/delayqueue/DelayObject.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/concurrent/delayqueue/DelayObject.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/delayqueue/DelayObject.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/delayqueue/DelayQueueConsumer.java b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/delayqueue/DelayQueueConsumer.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/concurrent/delayqueue/DelayQueueConsumer.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/delayqueue/DelayQueueConsumer.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/delayqueue/DelayQueueProducer.java b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/delayqueue/DelayQueueProducer.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/concurrent/delayqueue/DelayQueueProducer.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/delayqueue/DelayQueueProducer.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/skiplist/Event.java b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/skiplist/Event.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/concurrent/skiplist/Event.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/skiplist/Event.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/skiplist/EventWindowSort.java b/core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/skiplist/EventWindowSort.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/concurrent/skiplist/EventWindowSort.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/concurrent/skiplist/EventWindowSort.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/transferqueue/Consumer.java b/core-java-concurrency-collections/src/main/java/com/baeldung/transferqueue/Consumer.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/transferqueue/Consumer.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/transferqueue/Consumer.java diff --git a/core-java-concurrency/src/main/java/com/baeldung/transferqueue/Producer.java b/core-java-concurrency-collections/src/main/java/com/baeldung/transferqueue/Producer.java similarity index 100% rename from core-java-concurrency/src/main/java/com/baeldung/transferqueue/Producer.java rename to core-java-concurrency-collections/src/main/java/com/baeldung/transferqueue/Producer.java diff --git a/spring-data-elasticsearch/src/main/resources/logback.xml b/core-java-concurrency-collections/src/main/resources/logback.xml similarity index 100% rename from spring-data-elasticsearch/src/main/resources/logback.xml rename to core-java-concurrency-collections/src/main/resources/logback.xml diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/copyonwrite/CopyOnWriteArrayListUnitTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/concurrent/copyonwrite/CopyOnWriteArrayListUnitTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/concurrent/copyonwrite/CopyOnWriteArrayListUnitTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/concurrent/copyonwrite/CopyOnWriteArrayListUnitTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/delayqueue/DelayQueueIntegrationTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/concurrent/delayqueue/DelayQueueIntegrationTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/concurrent/delayqueue/DelayQueueIntegrationTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/concurrent/delayqueue/DelayQueueIntegrationTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/priorityblockingqueue/PriorityBlockingQueueIntegrationTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/concurrent/priorityblockingqueue/PriorityBlockingQueueIntegrationTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/concurrent/priorityblockingqueue/PriorityBlockingQueueIntegrationTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/concurrent/priorityblockingqueue/PriorityBlockingQueueIntegrationTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/skiplist/ConcurrentSkipListSetIntegrationTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/concurrent/skiplist/ConcurrentSkipListSetIntegrationTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/concurrent/skiplist/ConcurrentSkipListSetIntegrationTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/concurrent/skiplist/ConcurrentSkipListSetIntegrationTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusManualTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusManualTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusManualTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusManualTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueManualTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueManualTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueManualTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueManualTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceManualTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceManualTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceManualTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceManualTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapManualTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapManualTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapManualTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapManualTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyManualTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyManualTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyManualTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyManualTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/java/concurrentmodification/ConcurrentModificationUnitTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmodification/ConcurrentModificationUnitTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/java/concurrentmodification/ConcurrentModificationUnitTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/java/concurrentmodification/ConcurrentModificationUnitTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/synchronousqueue/SynchronousQueueIntegrationTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/synchronousqueue/SynchronousQueueIntegrationTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/synchronousqueue/SynchronousQueueIntegrationTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/synchronousqueue/SynchronousQueueIntegrationTest.java diff --git a/core-java-concurrency/src/test/java/com/baeldung/transferqueue/TransferQueueIntegrationTest.java b/core-java-concurrency-collections/src/test/java/com/baeldung/transferqueue/TransferQueueIntegrationTest.java similarity index 100% rename from core-java-concurrency/src/test/java/com/baeldung/transferqueue/TransferQueueIntegrationTest.java rename to core-java-concurrency-collections/src/test/java/com/baeldung/transferqueue/TransferQueueIntegrationTest.java diff --git a/core-java-concurrency/src/test/java/org/baeldung/java/streams/ThreadPoolInParallelStreamIntegrationTest.java b/core-java-concurrency-collections/src/test/java/org/baeldung/java/streams/ThreadPoolInParallelStreamIntegrationTest.java similarity index 100% rename from core-java-concurrency/src/test/java/org/baeldung/java/streams/ThreadPoolInParallelStreamIntegrationTest.java rename to core-java-concurrency-collections/src/test/java/org/baeldung/java/streams/ThreadPoolInParallelStreamIntegrationTest.java diff --git a/out/production/main122/.gitignore b/core-java-concurrency-collections/src/test/resources/.gitignore similarity index 100% rename from out/production/main122/.gitignore rename to core-java-concurrency-collections/src/test/resources/.gitignore diff --git a/core-java-concurrency/README.md b/core-java-concurrency/README.md index 8192a8e301..eeb9a83748 100644 --- a/core-java-concurrency/README.md +++ b/core-java-concurrency/README.md @@ -7,22 +7,12 @@ - [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial) - [Introduction to Thread Pools in Java](http://www.baeldung.com/thread-pool-java-and-guava) - [Guide to java.util.concurrent.Future](http://www.baeldung.com/java-future) -- [Guide to java.util.concurrent.BlockingQueue](http://www.baeldung.com/java-blocking-queue) - [Guide to CountDownLatch in Java](http://www.baeldung.com/java-countdown-latch) -- [A Guide to ConcurrentMap](http://www.baeldung.com/java-concurrent-map) -- [Guide to PriorityBlockingQueue in Java](http://www.baeldung.com/java-priority-blocking-queue) -- [Avoiding the ConcurrentModificationException in Java](http://www.baeldung.com/java-concurrentmodificationexception) -- [Custom Thread Pools In Java 8 Parallel Streams](http://www.baeldung.com/java-8-parallel-streams-custom-threadpool) - [Guide to java.util.concurrent.Locks](http://www.baeldung.com/java-concurrent-locks) - [An Introduction to ThreadLocal in Java](http://www.baeldung.com/java-threadlocal) -- [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) -- [A Guide to Java SynchronousQueue](http://www.baeldung.com/java-synchronous-queue) -- [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue) -- [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map) - [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) - [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator) - [The Dining Philosophers Problem in Java](http://www.baeldung.com/java-dining-philoshophers) -- [Guide to CopyOnWriteArrayList](http://www.baeldung.com/java-copy-on-write-arraylist) - [Guide to the Java Phaser](http://www.baeldung.com/java-phaser) - [Guide to Synchronized Keyword in Java](http://www.baeldung.com/java-synchronized) - [An Introduction to Atomic Variables in Java](http://www.baeldung.com/java-atomic-variables) @@ -38,3 +28,5 @@ - [Priority-based Job Scheduling in Java](http://www.baeldung.com/java-priority-job-schedule) - [A Custom Spring SecurityConfigurer](http://www.baeldung.com/spring-security-custom-configurer) - [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle) +- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable) +- [Brief Introduction to Java Thread.yield()](https://www.baeldung.com/java-thread-yield) diff --git a/core-java-concurrency/pom.xml b/core-java-concurrency/pom.xml index 7e162abc64..bd22253c2c 100644 --- a/core-java-concurrency/pom.xml +++ b/core-java-concurrency/pom.xml @@ -1,5 +1,5 @@ + 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 core-java-concurrency @@ -10,8 +10,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java @@ -57,112 +57,6 @@ true - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - - @@ -170,7 +64,6 @@ 21.0 3.5 3.6.1 - 2.5 4.1 4.01 diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java new file mode 100644 index 0000000000..b31a04015f --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java @@ -0,0 +1,17 @@ +package com.baeldung.concurrent.yield; + +public class ThreadYield { + public static void main(String[] args) { + Runnable r = () -> { + int counter = 0; + while (counter < 2) { + System.out.println(Thread.currentThread() + .getName()); + counter++; + Thread.yield(); + } + }; + new Thread(r).start(); + new Thread(r).start(); + } +} diff --git a/core-java-concurrency/src/main/resources/logback.xml b/core-java-concurrency/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/core-java-concurrency/src/main/resources/logback.xml +++ b/core-java-concurrency/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/core-java-concurrency/src/test/java/com/baeldung/completablefuture/CompletableFutureLongRunningUnitTest.java b/core-java-concurrency/src/test/java/com/baeldung/completablefuture/CompletableFutureLongRunningUnitTest.java index 45d2ec68e4..d9cf8ae019 100644 --- a/core-java-concurrency/src/test/java/com/baeldung/completablefuture/CompletableFutureLongRunningUnitTest.java +++ b/core-java-concurrency/src/test/java/com/baeldung/completablefuture/CompletableFutureLongRunningUnitTest.java @@ -184,5 +184,25 @@ public class CompletableFutureLongRunningUnitTest { assertEquals("Hello World", future.get()); } + + @Test + public void whenPassingTransformation_thenFunctionExecutionWithThenApply() throws InterruptedException, ExecutionException { + CompletableFuture finalResult = compute().thenApply(s -> s + 1); + assertTrue(finalResult.get() == 11); + } + + @Test + public void whenPassingPreviousStage_thenFunctionExecutionWithThenCompose() throws InterruptedException, ExecutionException { + CompletableFuture finalResult = compute().thenCompose(this::computeAnother); + assertTrue(finalResult.get() == 20); + } + + public CompletableFuture compute(){ + return CompletableFuture.supplyAsync(() -> 10); + } + + public CompletableFuture computeAnother(Integer i){ + return CompletableFuture.supplyAsync(() -> 10 + i); + } } \ No newline at end of file diff --git a/core-java-io/README.md b/core-java-io/README.md index 011282af12..58e331b6fc 100644 --- a/core-java-io/README.md +++ b/core-java-io/README.md @@ -28,3 +28,7 @@ - [Guide to Java NIO2 Asynchronous Channel APIs](http://www.baeldung.com/java-nio-2-async-channels) - [A Guide to NIO2 Asynchronous Socket Channel](http://www.baeldung.com/java-nio2-async-socket-channel) - [Download a File From an URL in Java](http://www.baeldung.com/java-download-file) +- [Create a Symbolic Link with Java](http://www.baeldung.com/java-symlink) +- [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter) +- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) +- [ Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist) diff --git a/core-java-io/pom.xml b/core-java-io/pom.xml index a98b489d9d..cf3e950cb8 100644 --- a/core-java-io/pom.xml +++ b/core-java-io/pom.xml @@ -1,7 +1,6 @@ + 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 core-java-io 0.1.0-SNAPSHOT jar @@ -10,8 +9,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java @@ -74,23 +73,6 @@ log4j ${log4j.version} - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - - org.slf4j log4j-over-slf4j @@ -103,42 +85,12 @@ provided - - org.hamcrest - hamcrest-all - ${hamcrest-all.version} - test - - - junit - junit - ${junit.version} - test - - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - org.assertj assertj-core ${assertj.version} test - - org.mockito - mockito-core - ${mockito.version} - test - com.jayway.awaitility awaitility @@ -213,35 +165,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*LiveTest.java - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - - true - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - org.codehaus.mojo exec-maven-plugin @@ -253,7 +176,7 @@ -Xmx300m -XX:+UseParallelGC -classpath - + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed @@ -275,32 +198,6 @@ integration - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - - - json - - - org.codehaus.mojo exec-maven-plugin @@ -318,7 +215,7 @@ java -classpath - + org.openjdk.jmh.Main .* @@ -335,18 +232,12 @@ 2.8.5 - - 1.7.21 - 1.1.7 - - 22.0 3.5 1.55 1.10 3.6.1 1.0.3 - 2.5 4.1 4.01 0.4 @@ -358,17 +249,10 @@ 0.9.0 - 1.3 - 4.12 - 2.8.9 3.6.1 1.7.0 - 3.7.0 - 2.19.1 - 1.8 - 1.8 3.0.0-M1 2.4.0 2.1.0.1 diff --git a/core-java-io/src/main/java/com/baeldung/stream/OutputStreamExamples.java b/core-java-io/src/main/java/com/baeldung/stream/OutputStreamExamples.java new file mode 100644 index 0000000000..c7168c5b26 --- /dev/null +++ b/core-java-io/src/main/java/com/baeldung/stream/OutputStreamExamples.java @@ -0,0 +1,48 @@ +package com.baeldung.stream; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +public class OutputStreamExamples { + + public void fileOutputStreamByteSequence(String file, String data) throws IOException { + byte[] bytes = data.getBytes(); + try (OutputStream out = new FileOutputStream(file)) { + out.write(bytes); + } + } + + public void fileOutputStreamByteSubSequence(String file, String data) throws IOException { + byte[] bytes = data.getBytes(); + try (OutputStream out = new FileOutputStream(file)) { + out.write(bytes, 6, 5); + } + } + + public void fileOutputStreamByteSingle(String file, String data) throws IOException { + byte[] bytes = data.getBytes(); + try (OutputStream out = new FileOutputStream(file)) { + out.write(bytes[6]); + } + } + + public void bufferedOutputStream(String file, String... data) throws IOException { + try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file))) { + for (String s : data) { + out.write(s.getBytes()); + out.write(" ".getBytes()); + } + } + } + + public void outputStreamWriter(String file, String data) throws IOException { + try (OutputStream out = new FileOutputStream(file); Writer writer = new OutputStreamWriter(out, "UTF-8")) { + writer.write(data); + } + } + +} diff --git a/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java b/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java new file mode 100644 index 0000000000..63ee0f14b1 --- /dev/null +++ b/core-java-io/src/main/java/com/baeldung/symlink/SymLinkExample.java @@ -0,0 +1,54 @@ +package com.baeldung.symlink; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import static java.nio.file.StandardOpenOption.*; +import java.util.stream.IntStream; + +public class SymLinkExample { + + public void createSymbolicLink(Path link, Path target) throws IOException { + if (Files.exists(link)) { + Files.delete(link); + } + Files.createSymbolicLink(link, target); + } + + public void createHardLink(Path link, Path target) throws IOException { + if (Files.exists(link)) { + Files.delete(link); + } + Files.createLink(link, target); + } + + public Path createTextFile() throws IOException { + byte[] content = IntStream.range(0, 10000) + .mapToObj(i -> i + System.lineSeparator()) + .reduce("", String::concat) + .getBytes(StandardCharsets.UTF_8); + Path filePath = Paths.get(".", "target_link.txt"); + Files.write(filePath, content, CREATE, TRUNCATE_EXISTING); + return filePath; + } + + public void printLinkFiles(Path path) throws IOException { + try (DirectoryStream stream = Files.newDirectoryStream(path)) { + for (Path file : stream) { + if (Files.isDirectory(file)) { + printLinkFiles(file); + } else if (Files.isSymbolicLink(file)) { + System.out.format("File link '%s' with target '%s'%n", file, Files.readSymbolicLink(file)); + } + } + } + } + + public static void main(String[] args) throws IOException { + new SymLinkExample().printLinkFiles(Paths.get(".")); + } + +} diff --git a/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java b/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java index 7da71a093d..42147b07db 100644 --- a/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java +++ b/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java @@ -24,6 +24,13 @@ public class ZipDirectory { return; } if (fileToZip.isDirectory()) { + if (fileName.endsWith("/")) { + zipOut.putNextEntry(new ZipEntry(fileName)); + zipOut.closeEntry(); + } else { + zipOut.putNextEntry(new ZipEntry(fileName + "/")); + zipOut.closeEntry(); + } final File[] children = fileToZip.listFiles(); for (final File childFile : children) { zipFile(childFile, fileName + "/" + childFile.getName(), zipOut); diff --git a/core-java-io/src/main/resources/logback.xml b/core-java-io/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/core-java-io/src/main/resources/logback.xml +++ b/core-java-io/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/core-java-io/src/main/resources/zipTest/test1.txt b/core-java-io/src/main/resources/zipTest/test1.txt new file mode 100644 index 0000000000..e88ded96ab --- /dev/null +++ b/core-java-io/src/main/resources/zipTest/test1.txt @@ -0,0 +1 @@ +Test1 \ No newline at end of file diff --git a/core-java-io/src/main/resources/zipTest/test2.txt b/core-java-io/src/main/resources/zipTest/test2.txt new file mode 100644 index 0000000000..da8f209890 --- /dev/null +++ b/core-java-io/src/main/resources/zipTest/test2.txt @@ -0,0 +1 @@ +Test2 \ No newline at end of file diff --git a/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java b/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java index 7968967679..e781489808 100644 --- a/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java +++ b/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java @@ -1,6 +1,7 @@ package com.baeldung.file; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; import org.junit.Test; @@ -17,6 +18,7 @@ import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.stream.Collectors; import java.util.stream.Stream; import static org.junit.Assert.assertEquals; @@ -49,7 +51,7 @@ public class FileOperationsManualTest { @Test public void givenFileName_whenUsingJarFile_thenFileData() throws IOException { - String expectedData = "BSD License"; + String expectedData = "MIT License"; Class clazz = Matchers.class; InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt"); @@ -78,7 +80,7 @@ public class FileOperationsManualTest { ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("fileTest.txt").getFile()); - String data = FileUtils.readFileToString(file); + String data = FileUtils.readFileToString(file, "UTF-8"); assertEquals(expectedData, data.trim()); } @@ -101,12 +103,11 @@ public class FileOperationsManualTest { Path path = Paths.get(getClass().getClassLoader().getResource("fileTest.txt").toURI()); - StringBuilder data = new StringBuilder(); Stream lines = Files.lines(path); - lines.forEach(line -> data.append(line).append("\n")); + String data = lines.collect(Collectors.joining("\n")); lines.close(); - assertEquals(expectedData, data.toString().trim()); + assertEquals(expectedData, data.trim()); } private String readFromInputStream(InputStream inputStream) throws IOException { @@ -120,4 +121,14 @@ public class FileOperationsManualTest { return resultStringBuilder.toString(); } + + @Test + public void givenFileName_whenUsingIOUtils_thenFileData() throws IOException { + String expectedData = "This is a content of the file"; + + FileInputStream fis = new FileInputStream("src/test/resources/fileToRead.txt"); + String data = IOUtils.toString(fis, "UTF-8"); + + assertEquals(expectedData, data.trim()); + } } \ No newline at end of file diff --git a/core-java-io/src/test/java/com/baeldung/file/FilenameFilterManualTest.java b/core-java-io/src/test/java/com/baeldung/file/FilenameFilterManualTest.java new file mode 100644 index 0000000000..f9a2ce972d --- /dev/null +++ b/core-java-io/src/test/java/com/baeldung/file/FilenameFilterManualTest.java @@ -0,0 +1,48 @@ +package com.baeldung.file; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class FilenameFilterManualTest { + + private static File directory; + + @BeforeClass + public static void setupClass() { + directory = new File(FilenameFilterManualTest.class.getClassLoader() + .getResource("fileNameFilterManualTestFolder") + .getFile()); + } + + @Test + public void whenFilteringFilesEndingWithJson_thenEqualExpectedFiles() { + FilenameFilter filter = (dir, name) -> name.endsWith(".json"); + + String[] expectedFiles = { "people.json", "students.json" }; + String[] actualFiles = directory.list(filter); + + Assert.assertArrayEquals(expectedFiles, actualFiles); + } + + @Test + public void whenFilteringFilesEndingWithXml_thenEqualExpectedFiles() { + Predicate predicate = (name) -> name.endsWith(".xml"); + + String[] expectedFiles = { "teachers.xml", "workers.xml" }; + List files = Arrays.stream(directory.list()) + .filter(predicate) + .collect(Collectors.toList()); + String[] actualFiles = files.toArray(new String[files.size()]); + + Assert.assertArrayEquals(expectedFiles, actualFiles); + } + +} diff --git a/core-java-io/src/test/java/com/baeldung/stream/OutputStreamExamplesUnitTest.java b/core-java-io/src/test/java/com/baeldung/stream/OutputStreamExamplesUnitTest.java new file mode 100644 index 0000000000..aa949259a0 --- /dev/null +++ b/core-java-io/src/test/java/com/baeldung/stream/OutputStreamExamplesUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.stream; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; + +public class OutputStreamExamplesUnitTest { + + StringBuilder filePath = new StringBuilder(); + + @Before + public void init() { + filePath.append("src"); + filePath.append(File.separator); + filePath.append("test"); + filePath.append(File.separator); + filePath.append("resources"); + filePath.append(File.separator); + filePath.append("output_file.txt"); + } + + @Test + public void givenOutputStream_whenWriteSingleByteCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.fileOutputStreamByteSingle(filePath.toString(), "Hello World!"); + assertTrue(file.exists()); + file.delete(); + } + + @Test + public void givenOutputStream_whenWriteByteSequenceCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.fileOutputStreamByteSequence(filePath.toString(), "Hello World!"); + assertTrue(file.exists()); + file.delete(); + } + + @Test + public void givenOutputStream_whenWriteByteSubSequenceCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.fileOutputStreamByteSubSequence(filePath.toString(), "Hello World!"); + assertTrue(file.exists()); + file.delete(); + } + + @Test + public void givenBufferedOutputStream_whenCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.bufferedOutputStream(filePath.toString(), "Hello", "World!"); + assertTrue(file.exists()); + file.delete(); + } + + @Test + public void givenOutputStreamWriter_whenCalled_thenOutputCreated() throws IOException { + + final File file = new File(filePath.toString()); + OutputStreamExamples examples = new OutputStreamExamples(); + examples.outputStreamWriter(filePath.toString(), "Hello World!"); + assertTrue(file.exists()); + file.delete(); + } + +} diff --git a/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java b/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java new file mode 100644 index 0000000000..caa7049475 --- /dev/null +++ b/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java @@ -0,0 +1,36 @@ +package com.baeldung.symlink; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.junit.Test; + +public class SymLinkExampleManualTest { + + @Test + public void whenUsingFiles_thenCreateSymbolicLink() throws IOException { + SymLinkExample example = new SymLinkExample(); + Path filePath = example.createTextFile(); + Path linkPath = Paths.get(".", "symbolic_link.txt"); + example.createSymbolicLink(linkPath, filePath); + assertTrue(Files.isSymbolicLink(linkPath)); + } + + @Test + public void whenUsingFiles_thenCreateHardLink() throws IOException { + SymLinkExample example = new SymLinkExample(); + Path filePath = example.createTextFile(); + Path linkPath = Paths.get(".", "hard_link.txt"); + example.createHardLink(linkPath, filePath); + assertFalse(Files.isSymbolicLink(linkPath)); + assertEquals(filePath.toFile() + .length(), + linkPath.toFile() + .length()); + } + +} diff --git a/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java b/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java index f1bea1eefb..c49681efb8 100644 --- a/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java +++ b/core-java-io/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java @@ -14,8 +14,10 @@ import org.slf4j.LoggerFactory; import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.Scanner; +import java.util.UUID; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.hamcrest.Matchers.equalTo; @@ -111,6 +113,19 @@ public class JavaInputStreamToXUnitTest { assertThat(writer.toString(), equalTo(originalString)); } + + @Test + public final void givenUsingTempFile_whenConvertingAnInputStreamToAString_thenCorrect() throws IOException { + final String originalString = randomAlphabetic(DEFAULT_SIZE); + final InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); + + // When + Path tempFile = java.nio.file.Files.createTempDirectory("").resolve(UUID.randomUUID().toString() + ".tmp"); + java.nio.file.Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); + String result = new String(java.nio.file.Files.readAllBytes(tempFile)); + + assertThat(result, equalTo(originalString)); + } // tests - InputStream to byte[] diff --git a/core-java-io/src/test/java/org/baeldung/java/io/JavaXToInputStreamUnitTest.java b/core-java-io/src/test/java/org/baeldung/java/io/JavaXToInputStreamUnitTest.java index 08a4c673cd..6604d75ed1 100644 --- a/core-java-io/src/test/java/org/baeldung/java/io/JavaXToInputStreamUnitTest.java +++ b/core-java-io/src/test/java/org/baeldung/java/io/JavaXToInputStreamUnitTest.java @@ -1,10 +1,12 @@ package org.baeldung.java.io; import java.io.ByteArrayInputStream; +import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.SequenceInputStream; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -74,6 +76,28 @@ public class JavaXToInputStreamUnitTest { IOUtils.closeQuietly(targetStream); } + @Test + public final void givenUsingPlainJava_whenConvertingFileToDataInputStream_thenCorrect() throws IOException { + final File initialFile = new File("src/test/resources/sample.txt"); + final InputStream targetStream = new DataInputStream(new FileInputStream(initialFile)); + + IOUtils.closeQuietly(targetStream); + } + + @Test + public final void givenUsingPlainJava_whenConvertingFileToSequenceInputStream_thenCorrect() throws IOException { + final File initialFile = new File("src/test/resources/sample.txt"); + final File anotherFile = new File("src/test/resources/anothersample.txt"); + final InputStream targetStream = new FileInputStream(initialFile); + final InputStream anotherTargetStream = new FileInputStream(anotherFile); + + InputStream sequenceTargetStream = new SequenceInputStream(targetStream, anotherTargetStream); + + IOUtils.closeQuietly(targetStream); + IOUtils.closeQuietly(anotherTargetStream); + IOUtils.closeQuietly(sequenceTargetStream); + } + @Test public final void givenUsingGuava_whenConvertingFileToInputStream_thenCorrect() throws IOException { final File initialFile = new File("src/test/resources/sample.txt"); diff --git a/core-java-io/src/test/resources/anothersample.txt b/core-java-io/src/test/resources/anothersample.txt new file mode 100644 index 0000000000..f06f18ce02 --- /dev/null +++ b/core-java-io/src/test/resources/anothersample.txt @@ -0,0 +1 @@ +...Continues \ No newline at end of file diff --git a/core-java-io/src/test/resources/fileNameFilterManualTestFolder/people.json b/core-java-io/src/test/resources/fileNameFilterManualTestFolder/people.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/core-java-io/src/test/resources/fileNameFilterManualTestFolder/people.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/core-java-io/src/test/resources/fileNameFilterManualTestFolder/students.json b/core-java-io/src/test/resources/fileNameFilterManualTestFolder/students.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/core-java-io/src/test/resources/fileNameFilterManualTestFolder/students.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/core-java-io/src/test/resources/fileNameFilterManualTestFolder/teachers.xml b/core-java-io/src/test/resources/fileNameFilterManualTestFolder/teachers.xml new file mode 100644 index 0000000000..19b16cc72c --- /dev/null +++ b/core-java-io/src/test/resources/fileNameFilterManualTestFolder/teachers.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core-java-io/src/test/resources/fileNameFilterManualTestFolder/workers.xml b/core-java-io/src/test/resources/fileNameFilterManualTestFolder/workers.xml new file mode 100644 index 0000000000..19b16cc72c --- /dev/null +++ b/core-java-io/src/test/resources/fileNameFilterManualTestFolder/workers.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/core-java-io/src/test/resources/fileTest.txt b/core-java-io/src/test/resources/fileTest.txt new file mode 100644 index 0000000000..ce4bea208b --- /dev/null +++ b/core-java-io/src/test/resources/fileTest.txt @@ -0,0 +1 @@ +Hello World from fileTest.txt!!! \ No newline at end of file diff --git a/core-java-persistence/README.md b/core-java-persistence/README.md new file mode 100644 index 0000000000..ca0ce81eef --- /dev/null +++ b/core-java-persistence/README.md @@ -0,0 +1,9 @@ +========= + +## Core Java Persistence Examples + +### Relevant Articles: +- [Introduction to JDBC](http://www.baeldung.com/java-jdbc) +- [Batch Processing in JDBC](http://www.baeldung.com/jdbc-batch-processing) +- [Introduction to the JDBC RowSet Interface in Java](http://www.baeldung.com/java-jdbc-rowset) +- [A Simple Guide to Connection Pooling in Java](https://www.baeldung.com/java-connection-pooling) diff --git a/core-java-persistence/pom.xml b/core-java-persistence/pom.xml new file mode 100644 index 0000000000..7279fd763b --- /dev/null +++ b/core-java-persistence/pom.xml @@ -0,0 +1,71 @@ + + 4.0.0 + com.baeldung.core-java-persistence + core-java-persistence + 0.1.0-SNAPSHOT + jar + core-java-persistence + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + org.assertj + assertj-core + ${assertj-core.version} + test + + + com.h2database + h2 + ${h2database.version} + + + org.apache.commons + commons-dbcp2 + ${commons-dbcp2.version} + + + com.zaxxer + HikariCP + ${HikariCP.version} + + + com.mchange + c3p0 + ${c3p0.version} + + + org.springframework + spring-web + ${springframework.spring-web.version} + + + org.springframework.boot + spring-boot-starter + ${springframework.boot.spring-boot-starter.version} + + + + core-java-persistence + + + src/main/resources + true + + + + + 3.10.0 + 1.4.197 + 2.4.0 + 3.2.0 + 0.9.5.2 + 1.5.8.RELEASE + 4.3.4.RELEASE + + \ No newline at end of file diff --git a/core-java-persistence/src/main/java/com/baeldung/connectionpool/BasicConnectionPool.java b/core-java-persistence/src/main/java/com/baeldung/connectionpool/BasicConnectionPool.java new file mode 100644 index 0000000000..289db18c53 --- /dev/null +++ b/core-java-persistence/src/main/java/com/baeldung/connectionpool/BasicConnectionPool.java @@ -0,0 +1,92 @@ +package com.baeldung.connectionpool; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class BasicConnectionPool implements ConnectionPool { + + private final String url; + private final String user; + private final String password; + private final List connectionPool; + private final List usedConnections = new ArrayList<>(); + private static final int INITIAL_POOL_SIZE = 10; + private final int MAX_POOL_SIZE = 20; + + public static BasicConnectionPool create(String url, String user, String password) throws SQLException { + List pool = new ArrayList<>(INITIAL_POOL_SIZE); + for (int i = 0; i < INITIAL_POOL_SIZE; i++) { + pool.add(createConnection(url, user, password)); + } + return new BasicConnectionPool(url, user, password, pool); + } + + private BasicConnectionPool(String url, String user, String password, List connectionPool) { + this.url = url; + this.user = user; + this.password = password; + this.connectionPool = connectionPool; + } + + @Override + public Connection getConnection() throws SQLException { + if (connectionPool.isEmpty()) { + if (usedConnections.size() < MAX_POOL_SIZE) { + connectionPool.add(createConnection(url, user, password)); + } else { + throw new RuntimeException("Maximum pool size reached, no available connections!"); + } + } + + Connection connection = connectionPool.remove(connectionPool.size() - 1); + usedConnections.add(connection); + return connection; + } + + @Override + public boolean releaseConnection(Connection connection) { + connectionPool.add(connection); + return usedConnections.remove(connection); + } + + private static Connection createConnection(String url, String user, String password) throws SQLException { + return DriverManager.getConnection(url, user, password); + } + + @Override + public int getSize() { + return connectionPool.size() + usedConnections.size(); + } + + @Override + public List getConnectionPool() { + return connectionPool; + } + + @Override + public String getUrl() { + return url; + } + + @Override + public String getUser() { + return user; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public void shutdown() throws SQLException { + usedConnections.forEach(this::releaseConnection); + for (Connection c : connectionPool) { + c.close(); + } + connectionPool.clear(); + } +} diff --git a/core-java-persistence/src/main/java/com/baeldung/connectionpool/C3poDataSource.java b/core-java-persistence/src/main/java/com/baeldung/connectionpool/C3poDataSource.java new file mode 100644 index 0000000000..78642459d5 --- /dev/null +++ b/core-java-persistence/src/main/java/com/baeldung/connectionpool/C3poDataSource.java @@ -0,0 +1,28 @@ +package com.baeldung.connectionpool; + +import com.mchange.v2.c3p0.ComboPooledDataSource; +import java.beans.PropertyVetoException; +import java.sql.Connection; +import java.sql.SQLException; + +public class C3poDataSource { + + private static final ComboPooledDataSource cpds = new ComboPooledDataSource(); + + static { + try { + cpds.setDriverClass("org.h2.Driver"); + cpds.setJdbcUrl("jdbc:h2:mem:test"); + cpds.setUser("user"); + cpds.setPassword("password"); + } catch (PropertyVetoException e) { + e.printStackTrace(); + } + } + + public static Connection getConnection() throws SQLException { + return cpds.getConnection(); + } + + private C3poDataSource(){} +} \ No newline at end of file diff --git a/core-java-persistence/src/main/java/com/baeldung/connectionpool/ConnectionPool.java b/core-java-persistence/src/main/java/com/baeldung/connectionpool/ConnectionPool.java new file mode 100644 index 0000000000..fa9355721b --- /dev/null +++ b/core-java-persistence/src/main/java/com/baeldung/connectionpool/ConnectionPool.java @@ -0,0 +1,24 @@ +package com.baeldung.connectionpool; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; + +public interface ConnectionPool { + + Connection getConnection() throws SQLException; + + boolean releaseConnection(Connection connection); + + List getConnectionPool(); + + int getSize(); + + String getUrl(); + + String getUser(); + + String getPassword(); + + void shutdown() throws SQLException;; +} \ No newline at end of file diff --git a/core-java-persistence/src/main/java/com/baeldung/connectionpool/DBCPDataSource.java b/core-java-persistence/src/main/java/com/baeldung/connectionpool/DBCPDataSource.java new file mode 100644 index 0000000000..1e33a08d46 --- /dev/null +++ b/core-java-persistence/src/main/java/com/baeldung/connectionpool/DBCPDataSource.java @@ -0,0 +1,25 @@ +package com.baeldung.connectionpool; + +import java.sql.Connection; +import java.sql.SQLException; +import org.apache.commons.dbcp2.BasicDataSource; + +public class DBCPDataSource { + + private static final BasicDataSource ds = new BasicDataSource(); + + static { + ds.setUrl("jdbc:h2:mem:test"); + ds.setUsername("user"); + ds.setPassword("password"); + ds.setMinIdle(5); + ds.setMaxIdle(10); + ds.setMaxOpenPreparedStatements(100); + } + + public static Connection getConnection() throws SQLException { + return ds.getConnection(); + } + + private DBCPDataSource(){} +} diff --git a/core-java-persistence/src/main/java/com/baeldung/connectionpool/HikariCPDataSource.java b/core-java-persistence/src/main/java/com/baeldung/connectionpool/HikariCPDataSource.java new file mode 100644 index 0000000000..cc0cc24520 --- /dev/null +++ b/core-java-persistence/src/main/java/com/baeldung/connectionpool/HikariCPDataSource.java @@ -0,0 +1,28 @@ +package com.baeldung.connectionpool; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import java.sql.Connection; +import java.sql.SQLException; + +public class HikariCPDataSource { + + private static final HikariConfig config = new HikariConfig(); + private static final HikariDataSource ds; + + static { + config.setJdbcUrl("jdbc:h2:mem:test"); + config.setUsername("user"); + config.setPassword("password"); + config.addDataSourceProperty("cachePrepStmts", "true"); + config.addDataSourceProperty("prepStmtCacheSize", "250"); + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + ds = new HikariDataSource(config); + } + + public static Connection getConnection() throws SQLException { + return ds.getConnection(); + } + + private HikariCPDataSource(){} +} diff --git a/core-java/src/main/java/com/baeldung/jdbc/BatchProcessing.java b/core-java-persistence/src/main/java/com/baeldung/jdbc/BatchProcessing.java similarity index 100% rename from core-java/src/main/java/com/baeldung/jdbc/BatchProcessing.java rename to core-java-persistence/src/main/java/com/baeldung/jdbc/BatchProcessing.java diff --git a/core-java/src/main/java/com/baeldung/jdbc/Employee.java b/core-java-persistence/src/main/java/com/baeldung/jdbc/Employee.java similarity index 100% rename from core-java/src/main/java/com/baeldung/jdbc/Employee.java rename to core-java-persistence/src/main/java/com/baeldung/jdbc/Employee.java diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java b/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java similarity index 100% rename from core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java rename to core-java-persistence/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java b/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java similarity index 100% rename from core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java rename to core-java-persistence/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java b/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/FilterExample.java similarity index 100% rename from core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java rename to core-java-persistence/src/main/java/com/baeldung/jdbcrowset/FilterExample.java diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java b/core-java-persistence/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java similarity index 100% rename from core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java rename to core-java-persistence/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java diff --git a/core-java-persistence/src/main/resources/logback.xml b/core-java-persistence/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-java-persistence/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-persistence/src/test/java/com/baeldung/connectionpool/BasicConnectionPoolUnitTest.java b/core-java-persistence/src/test/java/com/baeldung/connectionpool/BasicConnectionPoolUnitTest.java new file mode 100644 index 0000000000..479cd0db25 --- /dev/null +++ b/core-java-persistence/src/test/java/com/baeldung/connectionpool/BasicConnectionPoolUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.connectionpool; + +import java.sql.Connection; +import java.sql.SQLException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class BasicConnectionPoolUnitTest { + + private static ConnectionPool connectionPool; + + @BeforeClass + public static void setUpBasicConnectionPoolInstance() throws SQLException { + connectionPool = BasicConnectionPool.create("jdbc:h2:mem:test", "user", "password"); + } + + @Test + public void givenBasicConnectionPoolInstance_whenCalledgetConnection_thenCorrect() throws Exception { + assertTrue(connectionPool.getConnection().isValid(1)); + } + + @Test + public void givenBasicConnectionPoolInstance_whenCalledreleaseConnection_thenCorrect() throws Exception { + Connection connection = connectionPool.getConnection(); + assertThat(connectionPool.releaseConnection(connection)).isTrue(); + } + + @Test + public void givenBasicConnectionPoolInstance_whenCalledgetUrl_thenCorrect() { + assertThat(connectionPool.getUrl()).isEqualTo("jdbc:h2:mem:test"); + } + + @Test + public void givenBasicConnectionPoolInstance_whenCalledgetUser_thenCorrect() { + assertThat(connectionPool.getUser()).isEqualTo("user"); + } + + @Test + public void givenBasicConnectionPoolInstance_whenCalledgetPassword_thenCorrect() { + assertThat(connectionPool.getPassword()).isEqualTo("password"); + } + + @Test(expected = RuntimeException.class) + public void givenBasicConnectionPoolInstance_whenAskedForMoreThanMax_thenError() throws Exception { + // this test needs to be independent so it doesn't share the same connection pool as other tests + ConnectionPool cp = BasicConnectionPool.create("jdbc:h2:mem:test", "user", "password"); + final int MAX_POOL_SIZE = 20; + for (int i = 0; i < MAX_POOL_SIZE + 1; i++) { + cp.getConnection(); + } + fail(); + } + + @Test + public void givenBasicConnectionPoolInstance_whenSutdown_thenEmpty() throws Exception { + ConnectionPool cp = BasicConnectionPool.create("jdbc:h2:mem:test", "user", "password"); + assertThat(((BasicConnectionPool)cp).getSize()).isEqualTo(10); + + ((BasicConnectionPool) cp).shutdown(); + assertThat(((BasicConnectionPool)cp).getSize()).isEqualTo(0); + } +} diff --git a/core-java-persistence/src/test/java/com/baeldung/connectionpool/C3poDataSourceUnitTest.java b/core-java-persistence/src/test/java/com/baeldung/connectionpool/C3poDataSourceUnitTest.java new file mode 100644 index 0000000000..a07fa9e74b --- /dev/null +++ b/core-java-persistence/src/test/java/com/baeldung/connectionpool/C3poDataSourceUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.connectionpool; + +import java.sql.SQLException; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class C3poDataSourceUnitTest { + + @Test + public void givenC3poDataSourceClass_whenCalledgetConnection_thenCorrect() throws SQLException { + assertTrue(C3poDataSource.getConnection().isValid(1)); + } +} \ No newline at end of file diff --git a/core-java-persistence/src/test/java/com/baeldung/connectionpool/DBCPDataSourceUnitTest.java b/core-java-persistence/src/test/java/com/baeldung/connectionpool/DBCPDataSourceUnitTest.java new file mode 100644 index 0000000000..43aaf330b6 --- /dev/null +++ b/core-java-persistence/src/test/java/com/baeldung/connectionpool/DBCPDataSourceUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.connectionpool; + +import java.sql.SQLException; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class DBCPDataSourceUnitTest { + + @Test + public void givenDBCPDataSourceClass_whenCalledgetConnection_thenCorrect() throws SQLException { + assertTrue(DBCPDataSource.getConnection().isValid(1)); + } +} \ No newline at end of file diff --git a/core-java-persistence/src/test/java/com/baeldung/connectionpool/HikariCPDataSourceUnitTest.java b/core-java-persistence/src/test/java/com/baeldung/connectionpool/HikariCPDataSourceUnitTest.java new file mode 100644 index 0000000000..b20ce70efd --- /dev/null +++ b/core-java-persistence/src/test/java/com/baeldung/connectionpool/HikariCPDataSourceUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.connectionpool; + +import java.sql.SQLException; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class HikariCPDataSourceUnitTest { + + @Test + public void givenHikariDataSourceClass_whenCalledgetConnection_thenCorrect() throws SQLException { + assertTrue(HikariCPDataSource.getConnection().isValid(1)); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/jdbc/BatchProcessingLiveTest.java b/core-java-persistence/src/test/java/com/baeldung/jdbc/BatchProcessingLiveTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/jdbc/BatchProcessingLiveTest.java rename to core-java-persistence/src/test/java/com/baeldung/jdbc/BatchProcessingLiveTest.java diff --git a/core-java/src/test/java/com/baeldung/jdbc/JdbcLiveTest.java b/core-java-persistence/src/test/java/com/baeldung/jdbc/JdbcLiveTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/jdbc/JdbcLiveTest.java rename to core-java-persistence/src/test/java/com/baeldung/jdbc/JdbcLiveTest.java diff --git a/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetLiveTest.java b/core-java-persistence/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetLiveTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetLiveTest.java rename to core-java-persistence/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetLiveTest.java diff --git a/core-java-sun/pom.xml b/core-java-sun/pom.xml index 8662884095..57d5e9da5b 100644 --- a/core-java-sun/pom.xml +++ b/core-java-sun/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 com.baeldung core-java-sun @@ -9,8 +10,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java @@ -73,23 +74,6 @@ log4j ${log4j.version} - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - - org.slf4j log4j-over-slf4j @@ -102,42 +86,12 @@ provided - - org.hamcrest - hamcrest-all - ${hamcrest-all.version} - test - - - junit - junit - ${junit.version} - test - - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - org.assertj assertj-core ${assertj.version} test - - org.mockito - mockito-core - ${mockito.version} - test - com.jayway.awaitility awaitility @@ -212,25 +166,10 @@ - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - org.apache.maven.plugins maven-jar-plugin + ${maven-jar-plugin.version} @@ -241,79 +180,6 @@ - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - org.codehaus.mojo exec-maven-plugin @@ -325,7 +191,7 @@ -Xmx300m -XX:+UseParallelGC -classpath - + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed @@ -381,7 +247,7 @@ java -classpath - + org.openjdk.jmh.Main .* @@ -398,10 +264,6 @@ 2.8.5 - - 1.7.21 - 1.1.7 - 23.0 3.5 @@ -409,7 +271,6 @@ 1.10 3.6.1 1.0.3 - 2.5 4.1 4.01 0.4 @@ -419,18 +280,16 @@ 1.13 0.6.5 0.9.0 + 4.3.4.RELEASE - 1.3 - 2.8.9 3.6.1 1.7.0 - 3.7.0 - 2.19.1 + 2.21.0 1.8.0 - 4.3.4.RELEASE + 3.0.2 \ No newline at end of file diff --git a/core-java-sun/src/main/resources/logback.xml b/core-java-sun/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/core-java-sun/src/main/resources/logback.xml +++ b/core-java-sun/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/core-java/README.md b/core-java/README.md index 8800e2b862..9e38dfc47d 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -3,19 +3,14 @@ ## Core Java Cookbooks and Examples ### Relevant Articles: -- [Java – Random Long, Float, Integer and Double](http://www.baeldung.com/java-generate-random-long-float-integer-double) -- [Java – Generate Random String](http://www.baeldung.com/java-random-string) - [Java Timer](http://www.baeldung.com/java-timer-and-timertask) - [How to Run a Shell Command in Java](http://www.baeldung.com/run-shell-command-in-java) - [MD5 Hashing in Java](http://www.baeldung.com/java-md5) - [Guide to Java Reflection](http://www.baeldung.com/java-reflection) - [A Guide to Java Sockets](http://www.baeldung.com/a-guide-to-java-sockets) -- [Convert char to String in Java](http://www.baeldung.com/java-convert-char-to-string) -- [Convert String to int or Integer in Java](http://www.baeldung.com/java-convert-string-to-int-or-integer) - [Java – Try with Resources](http://www.baeldung.com/java-try-with-resources) - [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join) - [How to Print Screen in Java](http://www.baeldung.com/print-screen-in-java) -- [How to Convert String to different data types in Java](http://www.baeldung.com/java-string-conversions) - [Introduction to Java Generics](http://www.baeldung.com/java-generics) - [Generate equals() and hashCode() with Eclipse](http://www.baeldung.com/java-eclipse-equals-and-hashcode) - [A Guide To Java Regular Expressions API](http://www.baeldung.com/regular-expressions-java) @@ -30,7 +25,6 @@ - [The Traveling Salesman Problem in Java](http://www.baeldung.com/java-simulated-annealing-for-traveling-salesman) - [How to Create an Executable JAR with Maven](http://www.baeldung.com/executable-jar-with-maven) - [How to Design a Genetic Algorithm in Java](http://www.baeldung.com/java-genetic-algorithm) -- [Spring Security – Cache Control Headers](http://www.baeldung.com/spring-security-cache-control-headers) - [Basic Introduction to JMX](http://www.baeldung.com/java-management-extensions) - [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda) - [Introduction to Nashorn](http://www.baeldung.com/java-nashorn) @@ -38,63 +32,46 @@ - [A Quick JUnit vs TestNG Comparison](http://www.baeldung.com/junit-vs-testng) - [Java Primitive Conversions](http://www.baeldung.com/java-primitive-conversions) - [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency) -- [Using Math.pow in Java](http://www.baeldung.com/java-math-pow) -- [Converting Strings to Enums in Java](http://www.baeldung.com/java-string-to-enum) -- [Quick Guide to the Java StringTokenizer](http://www.baeldung.com/java-stringtokenizer) - [JVM Log Forging](http://www.baeldung.com/jvm-log-forging) - [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) - [How to Perform a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request) - [Call Methods at Runtime Using Java Reflection](http://www.baeldung.com/java-method-reflection) -- [Guide to UUID in JAVA](http://www.baeldung.com/guide-to-uuid-in-java) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) - [Iterating Over Enum Values in Java](http://www.baeldung.com/java-enum-iteration) - [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) -- [How to Round a Number to N Decimal Places in Java](http://www.baeldung.com/java-round-decimal-number) - [Changing Annotation Parameters At Runtime](http://www.baeldung.com/java-reflection-change-annotation-params) - [How to Find all Getters Returning Null](http://www.baeldung.com/java-getters-returning-null) - [Changing the Order in a Sum Operation Can Produce Different Results?](http://www.baeldung.com/java-floating-point-sum-order) - [How to Get a Name of a Method Being Executed?](http://www.baeldung.com/java-name-of-executing-method) - [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies) - [How to Copy an Array in Java](http://www.baeldung.com/java-array-copy) -- [Introduction to JDBC](http://www.baeldung.com/java-jdbc) -- [Period and Duration in Java](http://www.baeldung.com/java-period-duration) - [Converting a Stack Trace to a String in Java](http://www.baeldung.com/java-stacktrace-to-string) -- [Count Occurrences of a Char in a String](http://www.baeldung.com/java-count-chars) - [Java Double Brace Initialization](http://www.baeldung.com/java-double-brace-initialization) - [The StackOverflowError in Java](http://www.baeldung.com/java-stack-overflow-error) -- [Split a String in Java](http://www.baeldung.com/java-split-string) - [Introduction to Java Serialization](http://www.baeldung.com/java-serialization) -- [How to Remove the Last Character of a String?](http://www.baeldung.com/java-remove-last-character-of-string) - [ClassNotFoundException vs NoClassDefFoundError](http://www.baeldung.com/java-classnotfoundexception-and-noclassdeffounderror) - [Guide to UUID in Java](http://www.baeldung.com/java-uuid) - [Guide to Escaping Characters in Java RegExps](http://www.baeldung.com/java-regexp-escape-char) - [Guide to hashCode() in Java](http://www.baeldung.com/java-hashcode) - [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri) - [Broadcasting and Multicasting in Java](http://www.baeldung.com/java-broadcast-multicast) -- [CharSequence vs. String in Java](http://www.baeldung.com/java-char-sequence-string) - [Period and Duration in Java](http://www.baeldung.com/java-period-duration) - [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator) - [“Sneaky Throws” in Java](http://www.baeldung.com/java-sneaky-throws) - [OutOfMemoryError: GC Overhead Limit Exceeded](http://www.baeldung.com/java-gc-overhead-limit-exceeded) -- [StringBuilder and StringBuffer in Java](http://www.baeldung.com/java-string-builder-string-buffer) -- [Number of Digits in an Integer in Java](http://www.baeldung.com/java-number-of-digits-in-int) - [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) - [A Guide to the Static Keyword in Java](http://www.baeldung.com/java-static) - [Initializing Arrays in Java](http://www.baeldung.com/java-initialize-array) -- [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) - [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable) - [Quick Guide to Java Stack](http://www.baeldung.com/java-stack) - [The Java continue and break Keywords](http://www.baeldung.com/java-continue-and-break) - [Guide to java.util.Formatter](http://www.baeldung.com/java-string-formatter) -- [Batch Processing in JDBC](http://www.baeldung.com/jdbc-batch-processing) - [Check if a Java Array Contains a Value](http://www.baeldung.com/java-array-contains-value) - [How to Invert an Array in Java](http://www.baeldung.com/java-invert-array) - [Guide to the Cipher Class](http://www.baeldung.com/java-cipher-class) - [A Guide to Java Initialization](http://www.baeldung.com/java-initialization) - [Implementing a Binary Tree in Java](http://www.baeldung.com/java-binary-tree) - [A Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random) -- [RegEx for matching Date Pattern in Java](http://www.baeldung.com/java-date-regular-expressions) -- [Introduction to the JDBC RowSet Interface in Java](http://www.baeldung.com/java-jdbc-rowset) - [Nested Classes in Java](http://www.baeldung.com/java-nested-classes) - [A Guide to Java Loops](http://www.baeldung.com/java-loops) - [Varargs in Java](http://www.baeldung.com/java-varargs) @@ -109,16 +86,12 @@ - [The Trie Data Structure in Java](http://www.baeldung.com/trie-java) - [Introduction to Javadoc](http://www.baeldung.com/javadoc) - [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy) -- [Check if a String is a Palindrome](http://www.baeldung.com/java-palindrome) -- [Comparing Strings in Java](http://www.baeldung.com/java-compare-strings) - [Guide to Inheritance in Java](http://www.baeldung.com/java-inheritance) - [Guide to Externalizable Interface in Java](http://www.baeldung.com/java-externalizable) - [Object Type Casting in Java](http://www.baeldung.com/java-type-casting) - [A Practical Guide to DecimalFormat](http://www.baeldung.com/java-decimalformat) - [How to Detect the OS Using Java](http://www.baeldung.com/java-detect-os) - [ASCII Art in Java](http://www.baeldung.com/ascii-art-in-java) -- [An Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced) -- [Handling Daylight Savings Time in Java](http://www.baeldung.com/java-daylight-savings) - [Inheritance and Composition (Is-a vs Has-a relationship) in Java](http://www.baeldung.com/java-inheritance-composition) - [Finding Max/Min of a List or Collection](http://www.baeldung.com/java-collection-min-max) - [The "final" Keyword in Java](http://www.baeldung.com/java-final) @@ -132,8 +105,6 @@ - [Find Sum and Average in a Java Array](http://www.baeldung.com/java-array-sum-average) - [Java List UnsupportedOperationException](http://www.baeldung.com/java-list-unsupported-operation-exception) - [Type Erasure in Java Explained](http://www.baeldung.com/java-type-erasure) -- [BigDecimal and BigInteger in Java](http://www.baeldung.com/java-bigdecimal-biginteger) -- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones) - [Join and Split Arrays and Collections in Java](http://www.baeldung.com/java-join-and-split) - [Check If Two Lists are Equal in Java](http://www.baeldung.com/java-test-a-list-for-ordinality-and-equality) - [Sending Emails with Java](http://www.baeldung.com/java-email) @@ -144,12 +115,9 @@ - [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) - [Variable and Method Hiding in Java](http://www.baeldung.com/java-variable-method-hiding) - [Access Modifiers in Java](http://www.baeldung.com/java-access-modifiers) -- [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) @@ -161,3 +129,30 @@ - [Guide to the this Java Keyword](http://www.baeldung.com/java-this) - [Jagged Arrays In Java](http://www.baeldung.com/java-jagged-arrays) - [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class) +- [How to Get the File Extension of a File in Java](http://www.baeldung.com/java-file-extension) +- [Immutable Objects in Java](http://www.baeldung.com/java-immutable-object) +- [Console I/O in Java](http://www.baeldung.com/java-console-input-output) +- [Guide to the java.util.Arrays Class](http://www.baeldung.com/java-util-arrays) +- [Create a Custom Exception in Java](http://www.baeldung.com/java-new-custom-exception) +- [Java Global Exception Handler](http://www.baeldung.com/java-global-exception-handler) +- [Encrypting and Decrypting Files in Java](http://www.baeldung.com/java-cipher-input-output-stream) +- [How to Get the Size of an Object in Java](http://www.baeldung.com/java-size-of-object) +- [Exception Handling in Java](http://www.baeldung.com/java-exceptions) +- [Guide to Java Instrumentation](http://www.baeldung.com/java-instrumentation) +- [Getting a File’s Mime Type in Java](http://www.baeldung.com/java-file-mime-type) +- [Common Java Exceptions](http://www.baeldung.com/java-common-exceptions) +- [Java Constructors vs Static Factory Methods](https://www.baeldung.com/java-constructors-vs-static-factory-methods) +- [Differences Between Final, Finally and Finalize in Java](https://www.baeldung.com/java-final-finally-finalize) +- [Static and Dynamic Binding in Java](https://www.baeldung.com/java-static-dynamic-binding) +- [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line) +- [Difference Between Throw and Throws in Java](https://www.baeldung.com/java-throw-throws) +- [ClassCastException: Arrays$ArrayList cannot be cast to ArrayList](https://www.baeldung.com/java-classcastexception-arrays-arraylist) +- [Throw Exception in Optional in Java 8](https://www.baeldung.com/java-optional-throw-exception) +- [Add a Character to a String at a Given Position](https://www.baeldung.com/java-add-character-to-string) +- [Synthetic Constructs in Java](https://www.baeldung.com/java-synthetic) +- [Convert Double to String, Removing Decimal Places](https://www.baeldung.com/java-double-to-string) +- [Different Ways to Capture Java Heap Dumps](https://www.baeldung.com/java-heap-dump-capture) +- [How to Separate Double into Integer and Decimal Parts](https://www.baeldung.com/java-separate-double-into-integer-decimal-parts) +- [ZoneOffset in Java](https://www.baeldung.com/java-zone-offset) +- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing) +- [Java Switch Statement](https://www.baeldung.com/java-switch) diff --git a/core-java/pom.xml b/core-java/pom.xml index cad458596b..477a01375d 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -25,16 +25,6 @@ commons-lang3 ${commons-lang3.version} - - org.apache.commons - commons-math3 - ${commons-math3.version} - - - org.decimal4j - decimal4j - ${decimal4j.version} - org.bouncycastle bcprov-jdk15on @@ -68,23 +58,6 @@ log4j ${log4j.version} - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - - org.slf4j log4j-over-slf4j @@ -97,42 +70,13 @@ provided - - org.hamcrest - hamcrest-all - ${hamcrest-all.version} - test - - - junit - junit - ${junit.version} - test - - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - org.assertj assertj-core - ${assertj.version} - test - - - org.mockito - mockito-core - ${mockito.version} + ${assertj-core.version} test + commons-codec commons-codec @@ -183,11 +127,6 @@ spring-web ${springframework.spring-web.version} - - org.springframework.boot - spring-boot-starter - ${springframework.boot.spring-boot-starter.version} - com.h2database h2 @@ -197,11 +136,30 @@ javax.mail mail ${javax.mail.version} - + + - com.ibm.icu - icu4j - ${icu4j.version} + org.apache.tika + tika-core + ${tika.version} + + + net.sf.jmimemagic + jmimemagic + ${jmime-magic.version} + + + + org.javassist + javassist + ${javaassist.version} + + + com.sun + tools + 1.8.0 + system + ${java.home}/../lib/tools.jar @@ -298,8 +256,7 @@ true - + org.baeldung.executable.ExecutableMavenJar @@ -354,12 +311,12 @@ -Xmx300m -XX:+UseParallelGC -classpath - + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed - + org.apache.maven.plugins maven-javadoc-plugin @@ -406,7 +363,7 @@ org.codehaus.mojo exec-maven-plugin - + ${exec-maven-plugin.version} run-benchmarks @@ -420,7 +377,7 @@ java -classpath - + org.openjdk.jmh.Main .* @@ -431,25 +388,126 @@ + + + + buildAgentLoader + + + + org.apache.maven.plugins + maven-jar-plugin + + + package + + jar + + + agentLoader + target/classes + + + true + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + com/baeldung/instrumentation/application/AgentLoader.class + com/baeldung/instrumentation/application/Launcher.class + + + + + + + + + + buildApplication + + + + org.apache.maven.plugins + maven-jar-plugin + + + package + + jar + + + application + target/classes + + + true + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + com/baeldung/instrumentation/application/MyAtm.class + com/baeldung/instrumentation/application/MyAtmApplication.class + com/baeldung/instrumentation/application/Launcher.class + + + + + + + + + + buildAgent + + + + org.apache.maven.plugins + maven-jar-plugin + + + package + + jar + + + agent + target/classes + + + true + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + + com/baeldung/instrumentation/agent/AtmTransformer.class + com/baeldung/instrumentation/agent/MyInstrumentationAgent.class + + + + + + + + + 2.8.5 2.8.2 - - 1.7.21 - 1.1.7 - 1.2.17 - 3.5 1.55 1.10 + 2.5 3.6.1 1.0.3 - 2.5 0.4 1.8.7 1.16.12 @@ -459,29 +517,31 @@ 0.9.0 - 1.3 - 2.8.9 - 3.6.1 + 3.10.0 - 3.7.0 - 2.19.1 + 2.21.0 4.3.4.RELEASE - 1.5.8.RELEASE + 1.1 - 1.3 1.4.197 2.1.0.1 1.19 + 1.19 3.0.0-M1 - 1.6.0 1.5.0-b01 3.0.2 1.4.4 3.1.1 2.0.3.RELEASE + 1.6.0 61.1 + + 1.18 + 0.1.5 + + 3.21.0-GA - \ No newline at end of file + diff --git a/core-java/src/main/java/com/baeldung/array/ArrayReferenceGuide.java b/core-java/src/main/java/com/baeldung/array/ArrayReferenceGuide.java new file mode 100644 index 0000000000..7d7dec85b0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/array/ArrayReferenceGuide.java @@ -0,0 +1,159 @@ +package com.baeldung.array; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class ArrayReferenceGuide { + + public static void main(String[] args) { + declaration(); + + initialization(); + + access(); + + iterating(); + + varargs(); + + transformIntoList(); + + transformIntoStream(); + + sort(); + + search(); + + merge(); + } + + private static void declaration() { + int[] anArray; + int anotherArray[]; + } + + private static void initialization() { + int[] anArray = new int[10]; + anArray[0] = 10; + anArray[5] = 4; + + int[] anotherArray = new int[] {1, 2, 3, 4, 5}; + } + + private static void access() { + int[] anArray = new int[10]; + anArray[0] = 10; + anArray[5] = 4; + + System.out.println(anArray[0]); + } + + private static void iterating() { + int[] anArray = new int[] {1, 2, 3, 4, 5}; + for (int i = 0; i < anArray.length; i++) { + System.out.println(anArray[i]); + } + + for (int element : anArray) { + System.out.println(element); + } + } + + private static void varargs() { + String[] groceries = new String[] {"Milk", "Tomato", "Chips"}; + varargMethod(groceries); + varargMethod("Milk", "Tomato", "Chips"); + } + + private static void varargMethod(String... varargs) { + for (String element : varargs) { + System.out.println(element); + } + } + + private static void transformIntoList() { + Integer[] anArray = new Integer[] {1, 2, 3, 4, 5}; + + // Naïve implementation + List aList = new ArrayList<>(); // We create an empty list + for (int element : anArray) { + // We iterate over array's elements and add them to the list + aList.add(element); + } + + // Pretty implementation + aList = Arrays.asList(anArray); + + // Drawbacks + try { + aList.remove(0); + } catch (UnsupportedOperationException e) { + System.out.println(e.getMessage()); + } + + try { + aList.add(6); + } catch (UnsupportedOperationException e) { + System.out.println(e.getMessage()); + } + + int[] anotherArray = new int[] {1, 2, 3, 4, 5}; +// List anotherList = Arrays.asList(anotherArray); + } + + private static void transformIntoStream() { + int[] anArray = new int[] {1, 2, 3, 4, 5}; + IntStream aStream = Arrays.stream(anArray); + + Integer[] anotherArray = new Integer[] {1, 2, 3, 4, 5}; + Stream anotherStream = Arrays.stream(anotherArray, 2, 4); + } + + private static void sort() { + int[] anArray = new int[] {5, 2, 1, 4, 8}; + Arrays.sort(anArray); // anArray is now {1, 2, 4, 5, 8} + + Integer[] anotherArray = new Integer[] {5, 2, 1, 4, 8}; + Arrays.sort(anotherArray); // anArray is now {1, 2, 4, 5, 8} + + String[] yetAnotherArray = new String[] {"A", "E", "Z", "B", "C"}; + Arrays.sort(yetAnotherArray, 1, 3, Comparator.comparing(String::toString).reversed()); // yetAnotherArray is now {"A", "Z", "E", "B", "C"} + } + + private static void search() { + int[] anArray = new int[] {5, 2, 1, 4, 8}; + for (int i = 0; i < anArray.length; i++) { + if (anArray[i] == 4) { + System.out.println("Found at index " + i); + break; + } + } + + Arrays.sort(anArray); + int index = Arrays.binarySearch(anArray, 4); + System.out.println("Found at index " + index); + } + + private static void merge() { + int[] anArray = new int[] {5, 2, 1, 4, 8}; + int[] anotherArray = new int[] {10, 4, 9, 11, 2}; + + int[] resultArray = new int[anArray.length + anotherArray.length]; + for (int i = 0; i < resultArray.length; i++) { + resultArray[i] = (i < anArray.length ? anArray[i] : anotherArray[i - anArray.length]); + } + for (int element : resultArray) { + System.out.println(element); + } + + Arrays.setAll(resultArray, i -> (i < anArray.length ? anArray[i] : anotherArray[i - anArray.length])); + for (int element : resultArray) { + System.out.println(element); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/binding/Animal.java b/core-java/src/main/java/com/baeldung/binding/Animal.java new file mode 100644 index 0000000000..12eaa2a7a3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/binding/Animal.java @@ -0,0 +1,23 @@ +package com.baeldung.binding; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by madhumita.g on 25-07-2018. + */ +public class Animal { + + final static Logger logger = LoggerFactory.getLogger(Animal.class); + + public void makeNoise() { + logger.info("generic animal noise"); + } + + public void makeNoise(Integer repetitions) { + while(repetitions != 0) { + logger.info("generic animal noise countdown " + repetitions); + repetitions -= 1; + } + } +} diff --git a/core-java/src/main/java/com/baeldung/binding/AnimalActivity.java b/core-java/src/main/java/com/baeldung/binding/AnimalActivity.java new file mode 100644 index 0000000000..1bd36123e3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/binding/AnimalActivity.java @@ -0,0 +1,43 @@ +package com.baeldung.binding; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by madhumita.g on 25-07-2018. + */ +public class AnimalActivity { + + final static Logger logger = LoggerFactory.getLogger(AnimalActivity.class); + + + public static void sleep(Animal animal) { + logger.info("Animal is sleeping"); + } + + public static void sleep(Cat cat) { + logger.info("Cat is sleeping"); + } + + public static void main(String[] args) { + + Animal animal = new Animal(); + + //calling methods of animal object + animal.makeNoise(); + + animal.makeNoise(3); + + + //assigning a dog object to reference of type Animal + Animal catAnimal = new Cat(); + + catAnimal.makeNoise(); + + // calling static function + AnimalActivity.sleep(catAnimal); + + return; + + } +} diff --git a/core-java/src/main/java/com/baeldung/binding/Cat.java b/core-java/src/main/java/com/baeldung/binding/Cat.java new file mode 100644 index 0000000000..bbe740e412 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/binding/Cat.java @@ -0,0 +1,18 @@ +package com.baeldung.binding; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by madhumita.g on 25-07-2018. + */ +public class Cat extends Animal { + + final static Logger logger = LoggerFactory.getLogger(Cat.class); + + public void makeNoise() { + + logger.info("meow"); + } + +} diff --git a/core-java/src/main/java/com/baeldung/classcastexception/ClassCastException.java b/core-java/src/main/java/com/baeldung/classcastexception/ClassCastException.java new file mode 100644 index 0000000000..26e5bf0c6b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/classcastexception/ClassCastException.java @@ -0,0 +1,21 @@ +package com.baeldung.classcastexception; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ClassCastException { + + public static void main(String[] args) { + + String p1 = new String("John"); + String p2 = new String("Snow"); + String[] strArray = new String[] { p1, p2 }; + ArrayList strList = (ArrayList) Arrays.asList(strArray); + // To fix the ClassCastException at above line, modify the code as: + // List strList = Arrays.asList(strArray); + System.out.println("String list: " + strList); + + } + +} diff --git a/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java b/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java index c44e863776..532adce1ab 100644 --- a/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java +++ b/core-java/src/main/java/com/baeldung/classloader/CustomClassLoader.java @@ -1,11 +1,14 @@ package com.baeldung.classloader; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; public class CustomClassLoader extends ClassLoader { - - public Class getClass(String name) throws ClassNotFoundException { + @Override + public Class findClass(String name) throws ClassNotFoundException { byte[] b = loadClassFromFile(name); return defineClass(name, b, 0, b.length); } diff --git a/core-java/src/main/java/com/baeldung/constructorsstaticfactorymethods/application/Application.java b/core-java/src/main/java/com/baeldung/constructorsstaticfactorymethods/application/Application.java new file mode 100644 index 0000000000..d19772072f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/constructorsstaticfactorymethods/application/Application.java @@ -0,0 +1,12 @@ +package com.baeldung.constructorsstaticfactorymethods.application; + +import com.baeldung.constructorsstaticfactorymethods.entities.User; + +public class Application { + + public static void main(String[] args) { + User user1 = User.createWithDefaultCountry("John", "john@domain.com"); + User user2 = User.createWithLoggedInstantiationTime("John", "john@domain.com", "Argentina"); + User user3 = User.getSingletonInstance("John", "john@domain.com", "Argentina"); + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/constructorsstaticfactorymethods/entities/User.java b/core-java/src/main/java/com/baeldung/constructorsstaticfactorymethods/entities/User.java new file mode 100644 index 0000000000..4036b622c6 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/constructorsstaticfactorymethods/entities/User.java @@ -0,0 +1,63 @@ +package com.baeldung.constructorsstaticfactorymethods.entities; + +import java.time.LocalTime; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +public class User { + + private static volatile User instance = null; + private static final Logger LOGGER = Logger.getLogger(User.class.getName()); + private final String name; + private final String email; + private final String country; + + public static User createWithDefaultCountry(String name, String email) { + return new User(name, email, "Argentina"); + } + + public static User createWithLoggedInstantiationTime(String name, String email, String country) { + setLoggerProperties(); + LOGGER.log(Level.INFO, "Creating User instance at : {0}", LocalTime.now()); + return new User(name, email, country); + } + + public static User getSingletonInstance(String name, String email, String country) { + if (instance == null) { + synchronized (User.class) { + if (instance == null) { + instance = new User(name, email, country); + } + } + } + return instance; + + } + + private User(String name, String email, String country) { + this.name = name; + this.email = email; + this.country = country; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + + public String getCountry() { + return country; + } + + private static void setLoggerProperties() { + ConsoleHandler handler = new ConsoleHandler(); + handler.setLevel(Level.INFO); + handler.setFormatter(new SimpleFormatter()); + LOGGER.addHandler(handler); + } +} diff --git a/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java b/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java new file mode 100644 index 0000000000..a28ac3d5a1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java @@ -0,0 +1,40 @@ +package com.baeldung.doubles; + +import java.math.BigDecimal; + +public class SplitFloatingPointNumbers { + + public static void main(String[] args) { + + double doubleNumber = 24.04; + splitUsingFloatingTypes(doubleNumber); + splitUsingString(doubleNumber); + splitUsingBigDecimal(doubleNumber); + } + + private static void splitUsingFloatingTypes(double doubleNumber) { + System.out.println("Using Floating Point Arithmetics:"); + int intPart = (int) doubleNumber; + System.out.println("Double Number: "+doubleNumber); + System.out.println("Integer Part: "+ intPart); + System.out.println("Decimal Part: "+ (doubleNumber - intPart)); + } + + private static void splitUsingString(double doubleNumber) { + System.out.println("Using String Operations:"); + String doubleAsString = String.valueOf(doubleNumber); + int indexOfDecimal = doubleAsString.indexOf("."); + System.out.println("Double Number: "+doubleNumber); + System.out.println("Integer Part: "+ doubleAsString.substring(0, indexOfDecimal)); + System.out.println("Decimal Part: "+ doubleAsString.substring(indexOfDecimal)); + } + + private static void splitUsingBigDecimal(double doubleNumber) { + System.out.println("Using BigDecimal Operations:"); + BigDecimal bigDecimal = new BigDecimal(String.valueOf(doubleNumber)); + int intValue = bigDecimal.intValue(); + System.out.println("Double Number: "+bigDecimal.toPlainString()); + System.out.println("Integer Part: "+intValue); + System.out.println("Decimal Part: "+bigDecimal.subtract(new BigDecimal(intValue)).toPlainString()); + } +} diff --git a/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java b/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java new file mode 100644 index 0000000000..b557ccf31a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/encrypt/FileEncrypterDecrypter.java @@ -0,0 +1,60 @@ +package com.baeldung.encrypt; + +import javax.crypto.*; +import javax.crypto.spec.IvParameterSpec; +import java.io.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +class FileEncrypterDecrypter { + + private SecretKey secretKey; + private Cipher cipher; + + FileEncrypterDecrypter(SecretKey secretKey, String cipher) throws NoSuchPaddingException, NoSuchAlgorithmException { + this.secretKey = secretKey; + this.cipher = Cipher.getInstance(cipher); + } + + void encrypt(String content, String fileName) throws InvalidKeyException, IOException { + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + byte[] iv = cipher.getIV(); + + try ( + FileOutputStream fileOut = new FileOutputStream(fileName); + CipherOutputStream cipherOut = new CipherOutputStream(fileOut, cipher) + ) { + fileOut.write(iv); + cipherOut.write(content.getBytes()); + } + + } + + String decrypt(String fileName) throws InvalidAlgorithmParameterException, InvalidKeyException, IOException { + + String content; + + try (FileInputStream fileIn = new FileInputStream(fileName)) { + byte[] fileIv = new byte[16]; + fileIn.read(fileIv); + cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(fileIv)); + + try ( + CipherInputStream cipherIn = new CipherInputStream(fileIn, cipher); + InputStreamReader inputReader = new InputStreamReader(cipherIn); + BufferedReader reader = new BufferedReader(inputReader) + ) { + + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + content = sb.toString(); + } + + } + return content; + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptionhandling/Exceptions.java b/core-java/src/main/java/com/baeldung/exceptionhandling/Exceptions.java new file mode 100644 index 0000000000..9690648386 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptionhandling/Exceptions.java @@ -0,0 +1,212 @@ +package com.baeldung.exceptionhandling; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Scanner; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +public class Exceptions { + + private final static Logger logger = Logger.getLogger("ExceptionLogging"); + + public static List getPlayers() throws IOException { + Path path = Paths.get("players.dat"); + List players = Files.readAllLines(path); + + return players.stream() + .map(Player::new) + .collect(Collectors.toList()); + } + + public List loadAllPlayers(String playersFile) throws IOException{ + try { + throw new IOException(); + } catch(IOException ex) { + throw new IllegalStateException(); + } + } + + public int getPlayerScoreThrows(String playerFile) throws FileNotFoundException { + Scanner contents = new Scanner(new File(playerFile)); + return Integer.parseInt(contents.nextLine()); + } + + public int getPlayerScoreTryCatch(String playerFile) { + try { + Scanner contents = new Scanner(new File(playerFile)); + return Integer.parseInt(contents.nextLine()); + } catch (FileNotFoundException noFile) { + throw new IllegalArgumentException("File not found"); + } + } + + public int getPlayerScoreTryCatchRecovery(String playerFile) { + try { + Scanner contents = new Scanner(new File(playerFile)); + return Integer.parseInt(contents.nextLine()); + } catch ( FileNotFoundException noFile ) { + logger.warning("File not found, resetting score."); + return 0; + } + } + + public int getPlayerScoreFinally(String playerFile) throws FileNotFoundException { + Scanner contents = null; + try { + contents = new Scanner(new File(playerFile)); + return Integer.parseInt(contents.nextLine()); + } finally { + if (contents != null) { + contents.close(); + } + } + } + + public int getPlayerScoreTryWithResources(String playerFile) { + try (Scanner contents = new Scanner(new File(playerFile))) { + return Integer.parseInt(contents.nextLine()); + } catch (FileNotFoundException e ) { + logger.warning("File not found, resetting score."); + return 0; + } + } + + public int getPlayerScoreMultipleCatchBlocks(String playerFile) { + try (Scanner contents = new Scanner(new File(playerFile))) { + return Integer.parseInt(contents.nextLine()); + } catch (IOException e) { + logger.warning("Player file wouldn't load!"); + return 0; + } catch (NumberFormatException e) { + logger.warning("Player file was corrupted!"); + return 0; + } + } + + public int getPlayerScoreMultipleCatchBlocksAlternative(String playerFile) { + try (Scanner contents = new Scanner(new File(playerFile)) ) { + return Integer.parseInt(contents.nextLine()); + } catch (FileNotFoundException e) { + logger.warning("Player file not found!"); + return 0; + } catch (IOException e) { + logger.warning("Player file wouldn't load!"); + return 0; + } catch (NumberFormatException e) { + logger.warning("Player file was corrupted!"); + return 0; + } + } + + public int getPlayerScoreUnionCatchBlocks(String playerFile) { + try (Scanner contents = new Scanner(new File(playerFile))) { + return Integer.parseInt(contents.nextLine()); + } catch (IOException | NumberFormatException e) { + logger.warning("Failed to load score!"); + return 0; + } + } + + public List loadAllPlayersThrowingChecked(String playersFile) throws TimeoutException { + boolean tooLong = true; + + while (!tooLong) { + // ... potentially long operation + } + throw new TimeoutException("This operation took too long"); + } + + public List loadAllPlayersThrowingUnchecked(String playersFile) throws TimeoutException { + if(!isFilenameValid(playersFile)) { + throw new IllegalArgumentException("Filename isn't valid!"); + } + return null; + + // ... + } + + public List loadAllPlayersWrapping(String playersFile) throws IOException { + try { + throw new IOException(); + } catch (IOException io) { + throw io; + } + } + + public List loadAllPlayersRethrowing(String playersFile) throws PlayerLoadException { + try { + throw new IOException(); + } catch (IOException io) { + throw new PlayerLoadException(io); + } + } + + public List loadAllPlayersThrowable(String playersFile) { + try { + throw new NullPointerException(); + } catch ( Throwable t ) { + throw t; + } + } + + class FewerExceptions extends Exceptions { + @Override + public List loadAllPlayers(String playersFile) { //can't add "throws MyCheckedException + return null; + // overridden + } + } + + public void throwAsGotoAntiPattern() throws MyException { + try { + // bunch of code + throw new MyException(); + // second bunch of code + } catch ( MyException e ) { + // third bunch of code + } + } + + public int getPlayerScoreSwallowingExceptionAntiPattern(String playerFile) { + try { + // ... + } catch (Exception e) {} // <== catch and swallow + return 0; + } + + public int getPlayerScoreSwallowingExceptionAntiPatternAlternative(String playerFile) { + try { + // ... + } catch (Exception e) { + e.printStackTrace(); + } + return 0; + } + + public int getPlayerScoreSwallowingExceptionAntiPatternAlternative2(String playerFile) throws PlayerScoreException { + try { + throw new IOException(); + } catch (IOException e) { + throw new PlayerScoreException(e); + } + } + + public int getPlayerScoreReturnInFinallyAntiPattern(String playerFile) { + int score = 0; + try { + throw new IOException(); + } finally { + return score; // <== the IOException is dropped + } + } + + private boolean isFilenameValid(String name) { + return false; + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptionhandling/MyException.java b/core-java/src/main/java/com/baeldung/exceptionhandling/MyException.java new file mode 100644 index 0000000000..5a50acc4de --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptionhandling/MyException.java @@ -0,0 +1,5 @@ +package com.baeldung.exceptionhandling; + +public class MyException extends Throwable { + +} diff --git a/core-java/src/main/java/com/baeldung/exceptionhandling/Player.java b/core-java/src/main/java/com/baeldung/exceptionhandling/Player.java new file mode 100644 index 0000000000..4efd37134f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptionhandling/Player.java @@ -0,0 +1,12 @@ +package com.baeldung.exceptionhandling; + +public class Player { + + public int id; + public String name; + + public Player(String name) { + this.name = name; + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptionhandling/PlayerLoadException.java b/core-java/src/main/java/com/baeldung/exceptionhandling/PlayerLoadException.java new file mode 100644 index 0000000000..5302fd8e7d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptionhandling/PlayerLoadException.java @@ -0,0 +1,11 @@ +package com.baeldung.exceptionhandling; + +import java.io.IOException; + +public class PlayerLoadException extends Exception { + + public PlayerLoadException(IOException io) { + super(io); + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptionhandling/PlayerScoreException.java b/core-java/src/main/java/com/baeldung/exceptionhandling/PlayerScoreException.java new file mode 100644 index 0000000000..d11159217e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptionhandling/PlayerScoreException.java @@ -0,0 +1,8 @@ +package com.baeldung.exceptionhandling; + +public class PlayerScoreException extends Exception { + + public PlayerScoreException(Exception e) { + super(e); + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptionhandling/TimeoutException.java b/core-java/src/main/java/com/baeldung/exceptionhandling/TimeoutException.java new file mode 100644 index 0000000000..294ad542d3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptionhandling/TimeoutException.java @@ -0,0 +1,8 @@ +package com.baeldung.exceptionhandling; + +public class TimeoutException extends Exception { + + public TimeoutException(String message) { + super(message); + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java b/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java new file mode 100644 index 0000000000..138916ec60 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/Arithmetic.java @@ -0,0 +1,20 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Arithmetic { + + private static Logger LOGGER = LoggerFactory.getLogger(Arithmetic.class); + + public static void main(String[] args) { + + try { + int result = 30 / 0; // Trying to divide by zero + } catch (ArithmeticException e) { + LOGGER.error("ArithmeticException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java b/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java new file mode 100644 index 0000000000..93b53f284c --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ArrayIndexOutOfBounds.java @@ -0,0 +1,24 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ArrayIndexOutOfBounds { + + private static Logger LOGGER = LoggerFactory.getLogger(ArrayIndexOutOfBounds.class); + + public static void main(String[] args) { + + int[] nums = new int[] { 1, 2, 3 }; + + try { + int numFromNegativeIndex = nums[-1]; // Trying to access at negative index + int numFromGreaterIndex = nums[4]; // Trying to access at greater index + int numFromLengthIndex = nums[3]; // Trying to access at index equal to size of the array + } catch (ArrayIndexOutOfBoundsException e) { + LOGGER.error("ArrayIndexOutOfBoundsException caught"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java b/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java new file mode 100644 index 0000000000..183f8f54a3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ClassCast.java @@ -0,0 +1,36 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class Animal { + +} + +class Dog extends Animal { + +} + +class Lion extends Animal { + +} + +public class ClassCast { + + private static Logger LOGGER = LoggerFactory.getLogger(ClassCast.class); + + public static void main(String[] args) { + + try { + Animal animalOne = new Dog(); // At runtime the instance is dog + Dog bruno = (Dog) animalOne; // Downcasting + + Animal animalTwo = new Lion(); // At runtime the instance is animal + Dog tommy = (Dog) animalTwo; // Downcasting + } catch (ClassCastException e) { + LOGGER.error("ClassCastException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java b/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java new file mode 100644 index 0000000000..bb9e0bf4ac --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/FileNotFound.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileNotFound { + + private static Logger LOGGER = LoggerFactory.getLogger(FileNotFound.class); + + public static void main(String[] args) { + + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(new File("/invalid/file/location"))); + } catch (FileNotFoundException e) { + LOGGER.error("FileNotFoundException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java b/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java new file mode 100644 index 0000000000..ab46c83da4 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,28 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GlobalExceptionHandler { + + public static void main(String[] args) { + + Handler globalExceptionHandler = new Handler(); + Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler); + new GlobalExceptionHandler().performArithmeticOperation(10, 0); + } + + public int performArithmeticOperation(int num1, int num2) { + return num1/num2; + } + +} + +class Handler implements Thread.UncaughtExceptionHandler { + + private static Logger LOGGER = LoggerFactory.getLogger(Handler.class); + + public void uncaughtException(Thread t, Throwable e) { + LOGGER.info("Unhandled exception caught!"); + } +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java b/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java new file mode 100644 index 0000000000..801536cb2d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/IllegalArgument.java @@ -0,0 +1,18 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IllegalArgument { + + private static Logger LOGGER = LoggerFactory.getLogger(IllegalArgument.class); + + public static void main(String[] args) { + try { + Thread.sleep(-1000); + } catch (InterruptedException e) { + LOGGER.error("IllegalArgumentException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java b/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java new file mode 100644 index 0000000000..e8ddcea3c2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/IllegalState.java @@ -0,0 +1,32 @@ +package com.baeldung.exceptions; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IllegalState { + + private static Logger LOGGER = LoggerFactory.getLogger(IllegalState.class); + + public static void main(String[] args) { + + List intList = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + intList.add(i); + } + + Iterator intListIterator = intList.iterator(); // Initialized with index at -1 + + try { + intListIterator.remove(); // IllegalStateException + } catch (IllegalStateException e) { + LOGGER.error("IllegalStateException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java b/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java new file mode 100644 index 0000000000..319fd33591 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/InterruptedExceptionExample.java @@ -0,0 +1,28 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class ChildThread extends Thread { + + private static Logger LOGGER = LoggerFactory.getLogger(ChildThread.class); + + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + LOGGER.error("InterruptedException caught!"); + } + } + +} + +public class InterruptedExceptionExample { + + public static void main(String[] args) throws InterruptedException { + ChildThread childThread = new ChildThread(); + childThread.start(); + childThread.interrupt(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java b/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java new file mode 100644 index 0000000000..57fcddf76b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/MalformedURL.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MalformedURL { + + private static Logger LOGGER = LoggerFactory.getLogger(MalformedURL.class); + + public static void main(String[] args) { + + URL baeldungURL = null; + + try { + baeldungURL = new URL("malformedurl"); + } catch (MalformedURLException e) { + LOGGER.error("MalformedURLException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java b/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java new file mode 100644 index 0000000000..2402a786a9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/NullPointer.java @@ -0,0 +1,36 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NullPointer { + + private static Logger LOGGER = LoggerFactory.getLogger(NullPointer.class); + + public static void main(String[] args) { + + Person personObj = null; + + try { + String name = personObj.personName; // Accessing the field of a null object + personObj.personName = "Jon Doe"; // Modifying the field of a null object + } catch (NullPointerException e) { + LOGGER.error("NullPointerException caught!"); + } + + } +} + +class Person { + + public String personName; + + public String getPersonName() { + return personName; + } + + public void setPersonName(String personName) { + this.personName = personName; + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java b/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java new file mode 100644 index 0000000000..7050e70aee --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/NumberFormat.java @@ -0,0 +1,23 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NumberFormat { + + private static Logger LOGGER = LoggerFactory.getLogger(NumberFormat.class); + + public static void main(String[] args) { + + String str1 = "100ABCD"; + + try { + int x = Integer.parseInt(str1); // Converting string with inappropriate format + int y = Integer.valueOf(str1); + } catch (NumberFormatException e) { + LOGGER.error("NumberFormatException caught!"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java b/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java new file mode 100644 index 0000000000..f7fb4c91e4 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/ParseExceptionExample.java @@ -0,0 +1,25 @@ +package com.baeldung.exceptions; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ParseExceptionExample { + + private static Logger LOGGER = LoggerFactory.getLogger(ParseExceptionExample.class); + + public static void main(String[] args) { + + DateFormat format = new SimpleDateFormat("MM, dd, yyyy"); + + try { + format.parse("01, , 2010"); + } catch (ParseException e) { + LOGGER.error("ParseException caught!"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java b/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java new file mode 100644 index 0000000000..bc297be498 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/exceptions/StringIndexOutOfBounds.java @@ -0,0 +1,23 @@ +package com.baeldung.exceptions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StringIndexOutOfBounds { + + private static Logger LOGGER = LoggerFactory.getLogger(StringIndexOutOfBounds.class); + + public static void main(String[] args) { + + String str = "Hello World"; + + try { + char charAtNegativeIndex = str.charAt(-1); // Trying to access at negative index + char charAtLengthIndex = str.charAt(11); // Trying to access at index equal to size of the string + } catch (StringIndexOutOfBoundsException e) { + LOGGER.error("StringIndexOutOfBoundsException caught"); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/fileparser/BufferedReaderExample.java b/core-java/src/main/java/com/baeldung/fileparser/BufferedReaderExample.java new file mode 100644 index 0000000000..45ff486a79 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/fileparser/BufferedReaderExample.java @@ -0,0 +1,24 @@ +package com.baeldung.fileparser; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; + +public class BufferedReaderExample { + + protected static ArrayList generateArrayListFromFile(String filename) throws IOException { + + ArrayList result = new ArrayList<>(); + + try (BufferedReader br = new BufferedReader(new FileReader(filename))) { + + while (br.ready()) { + result.add(br.readLine()); + } + return result; + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/fileparser/FileReaderExample.java b/core-java/src/main/java/com/baeldung/fileparser/FileReaderExample.java new file mode 100644 index 0000000000..f9dd2a9ec5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/fileparser/FileReaderExample.java @@ -0,0 +1,31 @@ +package com.baeldung.fileparser; + +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; + +public class FileReaderExample { + + protected static ArrayList generateArrayListFromFile(String filename) throws IOException { + + ArrayList result = new ArrayList<>(); + + try (FileReader f = new FileReader(filename)) { + StringBuffer sb = new StringBuffer(); + while (f.ready()) { + char c = (char) f.read(); + if (c == '\n') { + result.add(sb.toString()); + sb = new StringBuffer(); + } else { + sb.append(c); + } + } + if (sb.length() > 0) { + result.add(sb.toString()); + } + } + + return result; + } +} diff --git a/core-java/src/main/java/com/baeldung/fileparser/FilesReadLinesExample.java b/core-java/src/main/java/com/baeldung/fileparser/FilesReadLinesExample.java new file mode 100644 index 0000000000..8e74f7d386 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/fileparser/FilesReadLinesExample.java @@ -0,0 +1,18 @@ +package com.baeldung.fileparser; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class FilesReadLinesExample { + + protected static ArrayList generateArrayListFromFile(String filename) throws IOException { + + List result = Files.readAllLines(Paths.get(filename)); + + return (ArrayList) result; + } + +} diff --git a/core-java/src/main/java/com/baeldung/fileparser/ScannerIntExample.java b/core-java/src/main/java/com/baeldung/fileparser/ScannerIntExample.java new file mode 100644 index 0000000000..25d17af4ea --- /dev/null +++ b/core-java/src/main/java/com/baeldung/fileparser/ScannerIntExample.java @@ -0,0 +1,24 @@ +package com.baeldung.fileparser; + +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +public class ScannerIntExample { + + protected static ArrayList generateArrayListFromFile(String filename) throws IOException { + + ArrayList result = new ArrayList<>(); + + try (Scanner s = new Scanner(new FileReader(filename))) { + + while (s.hasNext()) { + result.add(s.nextInt()); + } + return result; + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/fileparser/ScannerStringExample.java b/core-java/src/main/java/com/baeldung/fileparser/ScannerStringExample.java new file mode 100644 index 0000000000..ec213c9490 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/fileparser/ScannerStringExample.java @@ -0,0 +1,24 @@ +package com.baeldung.fileparser; + +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Scanner; + +public class ScannerStringExample { + + protected static ArrayList generateArrayListFromFile(String filename) throws IOException { + + ArrayList result = new ArrayList<>(); + + try (Scanner s = new Scanner(new FileReader(filename))) { + + while (s.hasNext()) { + result.add(s.nextLine()); + } + return result; + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/hashcode/entities/User.java b/core-java/src/main/java/com/baeldung/hashcode/entities/User.java index c46c3de65a..524f176e6b 100644 --- a/core-java/src/main/java/com/baeldung/hashcode/entities/User.java +++ b/core-java/src/main/java/com/baeldung/hashcode/entities/User.java @@ -25,7 +25,7 @@ public class User { if (this.getClass() != o.getClass()) return false; User user = (User) o; - return id != user.id && (!name.equals(user.name) && !email.equals(user.email)); + return id == user.id && (name.equals(user.name) && email.equals(user.email)); } @Override @@ -38,4 +38,5 @@ public class User { return hash; } // getters and setters here + } diff --git a/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java b/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java new file mode 100644 index 0000000000..8cce20de8d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java @@ -0,0 +1,25 @@ +package com.baeldung.heapdump; + +import com.sun.management.HotSpotDiagnosticMXBean; + +import javax.management.MBeanServer; + +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.nio.file.Paths; + +public class HeapDump { + + public static void dumpHeap(String filePath, boolean live) throws IOException { + MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy( + server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class); + mxBean.dumpHeap(filePath, live); + } + + public static void main(String[] args) throws IOException { + String file = Paths.get("dump.hprof").toFile().getPath(); + + dumpHeap(file, true); + } +} diff --git a/core-java/src/main/java/com/baeldung/heapsort/Heap.java b/core-java/src/main/java/com/baeldung/heapsort/Heap.java new file mode 100644 index 0000000000..95e0e1d8cd --- /dev/null +++ b/core-java/src/main/java/com/baeldung/heapsort/Heap.java @@ -0,0 +1,136 @@ +package com.baeldung.heapsort; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Heap> { + + private List elements = new ArrayList<>(); + + public static > List sort(Iterable elements) { + Heap heap = of(elements); + + List result = new ArrayList<>(); + + while (!heap.isEmpty()) { + result.add(heap.pop()); + } + + return result; + } + + public static > Heap of(E... elements) { + return of(Arrays.asList(elements)); + } + + public static > Heap of(Iterable elements) { + Heap result = new Heap<>(); + for (E element : elements) { + result.add(element); + } + return result; + } + + public void add(E e) { + elements.add(e); + int elementIndex = elements.size() - 1; + while (!isRoot(elementIndex) && !isCorrectChild(elementIndex)) { + int parentIndex = parentIndex(elementIndex); + swap(elementIndex, parentIndex); + elementIndex = parentIndex; + } + } + + public E pop() { + if (isEmpty()) { + throw new IllegalStateException("You cannot pop from an empty heap"); + } + + E result = elementAt(0); + + int lasElementIndex = elements.size() - 1; + swap(0, lasElementIndex); + elements.remove(lasElementIndex); + + int elementIndex = 0; + while (!isLeaf(elementIndex) && !isCorrectParent(elementIndex)) { + int smallerChildIndex = smallerChildIndex(elementIndex); + swap(elementIndex, smallerChildIndex); + elementIndex = smallerChildIndex; + } + + return result; + } + + public boolean isEmpty() { + return elements.isEmpty(); + } + + private boolean isRoot(int index) { + return index == 0; + } + + private int smallerChildIndex(int index) { + int leftChildIndex = leftChildIndex(index); + int rightChildIndex = rightChildIndex(index); + + if (!isValidIndex(rightChildIndex)) { + return leftChildIndex; + } + + if (elementAt(leftChildIndex).compareTo(elementAt(rightChildIndex)) < 0) { + return leftChildIndex; + } + + return rightChildIndex; + } + + private boolean isLeaf(int index) { + return !isValidIndex(leftChildIndex(index)); + } + + private boolean isCorrectParent(int index) { + return isCorrect(index, leftChildIndex(index)) && isCorrect(index, rightChildIndex(index)); + } + + private boolean isCorrectChild(int index) { + return isCorrect(parentIndex(index), index); + } + + private boolean isCorrect(int parentIndex, int childIndex) { + if (!isValidIndex(parentIndex) || !isValidIndex(childIndex)) { + return true; + } + + return elementAt(parentIndex).compareTo(elementAt(childIndex)) < 0; + } + + private boolean isValidIndex(int index) { + return index < elements.size(); + } + + private void swap(int index1, int index2) { + E element1 = elementAt(index1); + E element2 = elementAt(index2); + elements.set(index1, element2); + elements.set(index2, element1); + } + + private E elementAt(int index) { + return elements.get(index); + } + + private int parentIndex(int index) { + return (index - 1) / 2; + } + + private int leftChildIndex(int index) { + return 2 * index + 1; + } + + private int rightChildIndex(int index) { + return 2 * index + 2; + } + +} diff --git a/core-java/src/main/java/com/baeldung/instrumentation/agent/AtmTransformer.java b/core-java/src/main/java/com/baeldung/instrumentation/agent/AtmTransformer.java new file mode 100644 index 0000000000..3c83912f54 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/instrumentation/agent/AtmTransformer.java @@ -0,0 +1,70 @@ +package com.baeldung.instrumentation.agent; + +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.NotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.security.ProtectionDomain; + +public class AtmTransformer implements ClassFileTransformer { + + private static Logger LOGGER = LoggerFactory.getLogger(AtmTransformer.class); + + private static final String WITHDRAW_MONEY_METHOD = "withdrawMoney"; + + /** The internal form class name of the class to transform */ + private String targetClassName; + /** The class loader of the class we want to transform */ + private ClassLoader targetClassLoader; + + public AtmTransformer(String targetClassName, ClassLoader targetClassLoader) { + this.targetClassName = targetClassName; + this.targetClassLoader = targetClassLoader; + } + + @Override + public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { + byte[] byteCode = classfileBuffer; + + String finalTargetClassName = this.targetClassName.replaceAll("\\.", "/"); //replace . with / + if (!className.equals(finalTargetClassName)) { + return byteCode; + } + + if (className.equals(finalTargetClassName) && loader.equals(targetClassLoader)) { + LOGGER.info("[Agent] Transforming class MyAtm"); + try { + ClassPool cp = ClassPool.getDefault(); + CtClass cc = cp.get(targetClassName); + CtMethod m = cc.getDeclaredMethod(WITHDRAW_MONEY_METHOD); + m.addLocalVariable("startTime", CtClass.longType); + m.insertBefore("startTime = System.currentTimeMillis();"); + + StringBuilder endBlock = new StringBuilder(); + + m.addLocalVariable("endTime", CtClass.longType); + m.addLocalVariable("opTime", CtClass.longType); + endBlock.append("endTime = System.currentTimeMillis();"); + endBlock.append("opTime = (endTime-startTime)/1000;"); + + endBlock.append("LOGGER.info(\"[Application] Withdrawal operation completed in:\" + opTime + \" seconds!\");"); + + m.insertAfter(endBlock.toString()); + + byteCode = cc.toBytecode(); + cc.detach(); + } catch (NotFoundException | CannotCompileException | IOException e) { + LOGGER.error("Exception", e); + } + } + return byteCode; + } +} diff --git a/core-java/src/main/java/com/baeldung/instrumentation/agent/MyInstrumentationAgent.java b/core-java/src/main/java/com/baeldung/instrumentation/agent/MyInstrumentationAgent.java new file mode 100644 index 0000000000..685520276e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/instrumentation/agent/MyInstrumentationAgent.java @@ -0,0 +1,59 @@ +package com.baeldung.instrumentation.agent; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.instrument.Instrumentation; + +public class MyInstrumentationAgent { + private static Logger LOGGER = LoggerFactory.getLogger(MyInstrumentationAgent.class); + + public static void premain(String agentArgs, Instrumentation inst) { + LOGGER.info("[Agent] In premain method"); + + String className = "com.baeldung.instrumentation.application.MyAtm"; + transformClass(className,inst); + } + + public static void agentmain(String agentArgs, Instrumentation inst) { + LOGGER.info("[Agent] In agentmain method"); + + String className = "com.baeldung.instrumentation.application.MyAtm"; + transformClass(className,inst); + } + + private static void transformClass(String className, Instrumentation instrumentation) { + Class targetCls = null; + ClassLoader targetClassLoader = null; + // see if we can get the class using forName + try { + targetCls = Class.forName(className); + targetClassLoader = targetCls.getClassLoader(); + transform(targetCls, targetClassLoader, instrumentation); + return; + } catch (Exception ex) { + LOGGER.error("Class [{}] not found with Class.forName"); + } + // otherwise iterate all loaded classes and find what we want + for(Class clazz: instrumentation.getAllLoadedClasses()) { + if(clazz.getName().equals(className)) { + targetCls = clazz; + targetClassLoader = targetCls.getClassLoader(); + transform(targetCls, targetClassLoader, instrumentation); + return; + } + } + throw new RuntimeException("Failed to find class [" + className + "]"); + } + + private static void transform(Class clazz, ClassLoader classLoader, Instrumentation instrumentation) { + AtmTransformer dt = new AtmTransformer(clazz.getName(), classLoader); + instrumentation.addTransformer(dt, true); + try { + instrumentation.retransformClasses(clazz); + } catch (Exception ex) { + throw new RuntimeException("Transform failed for class: [" + clazz.getName() + "]", ex); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/instrumentation/application/AgentLoader.java b/core-java/src/main/java/com/baeldung/instrumentation/application/AgentLoader.java new file mode 100644 index 0000000000..2c1cd759a5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/instrumentation/application/AgentLoader.java @@ -0,0 +1,46 @@ +package com.baeldung.instrumentation.application; + +import com.sun.tools.attach.VirtualMachine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.Optional; + +/** + * Created by adi on 6/10/18. + */ +public class AgentLoader { + private static Logger LOGGER = LoggerFactory.getLogger(AgentLoader.class); + + public static void run(String[] args) { + String agentFilePath = "/home/adi/Desktop/agent-1.0.0-jar-with-dependencies.jar"; + String applicationName = "MyAtmApplication"; + + //iterate all jvms and get the first one that matches our application name + Optional jvmProcessOpt = Optional.ofNullable(VirtualMachine.list() + .stream() + .filter(jvm -> { + LOGGER.info("jvm:{}", jvm.displayName()); + return jvm.displayName().contains(applicationName); + }) + .findFirst().get().id()); + + if(!jvmProcessOpt.isPresent()) { + LOGGER.error("Target Application not found"); + return; + } + File agentFile = new File(agentFilePath); + try { + String jvmPid = jvmProcessOpt.get(); + LOGGER.info("Attaching to target JVM with PID: " + jvmPid); + VirtualMachine jvm = VirtualMachine.attach(jvmPid); + jvm.loadAgent(agentFile.getAbsolutePath()); + jvm.detach(); + LOGGER.info("Attached to target JVM and loaded Java agent successfully"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/instrumentation/application/Launcher.java b/core-java/src/main/java/com/baeldung/instrumentation/application/Launcher.java new file mode 100644 index 0000000000..87e494baab --- /dev/null +++ b/core-java/src/main/java/com/baeldung/instrumentation/application/Launcher.java @@ -0,0 +1,14 @@ +package com.baeldung.instrumentation.application; + +/** + * Created by adi on 6/14/18. + */ +public class Launcher { + public static void main(String[] args) throws Exception { + if(args[0].equals("StartMyAtmApplication")) { + new MyAtmApplication().run(args); + } else if(args[0].equals("LoadAgent")) { + new AgentLoader().run(args); + } + } +} diff --git a/core-java/src/main/java/com/baeldung/instrumentation/application/MyAtm.java b/core-java/src/main/java/com/baeldung/instrumentation/application/MyAtm.java new file mode 100644 index 0000000000..f826e82975 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/instrumentation/application/MyAtm.java @@ -0,0 +1,19 @@ +package com.baeldung.instrumentation.application; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by adi on 6/11/18. + */ +public class MyAtm { + private static Logger LOGGER = LoggerFactory.getLogger(MyAtm.class); + + private static final int account = 10; + + public static void withdrawMoney(int amount) throws InterruptedException { + Thread.sleep(2000l); //processing going on here + LOGGER.info("[Application] Successful Withdrawal of [{}] units!", amount); + + } +} diff --git a/core-java/src/main/java/com/baeldung/instrumentation/application/MyAtmApplication.java b/core-java/src/main/java/com/baeldung/instrumentation/application/MyAtmApplication.java new file mode 100644 index 0000000000..425511285e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/instrumentation/application/MyAtmApplication.java @@ -0,0 +1,19 @@ +package com.baeldung.instrumentation.application; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MyAtmApplication { + + private static Logger LOGGER = LoggerFactory.getLogger(MyAtmApplication.class); + + public static void run(String[] args) throws Exception { + LOGGER.info("[Application] Starting ATM application"); + MyAtm.withdrawMoney(Integer.parseInt(args[2])); + + Thread.sleep(Long.valueOf(args[1])); + + MyAtm.withdrawMoney(Integer.parseInt(args[3])); + } + +} diff --git a/core-java/src/main/java/com/baeldung/keywords/finalize/FinalizeObject.java b/core-java/src/main/java/com/baeldung/keywords/finalize/FinalizeObject.java new file mode 100644 index 0000000000..af0449c0da --- /dev/null +++ b/core-java/src/main/java/com/baeldung/keywords/finalize/FinalizeObject.java @@ -0,0 +1,18 @@ +package com.baeldung.keywords.finalize; + +public class FinalizeObject { + + @Override + protected void finalize() throws Throwable { + System.out.println("Execute finalize method"); + super.finalize(); + } + + public static void main(String[] args) throws Exception { + FinalizeObject object = new FinalizeObject(); + object = null; + System.gc(); + Thread.sleep(1000); + } + +} diff --git a/core-java/src/main/java/com/baeldung/keywords/finalkeyword/Child.java b/core-java/src/main/java/com/baeldung/keywords/finalkeyword/Child.java new file mode 100644 index 0000000000..8615c78652 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/keywords/finalkeyword/Child.java @@ -0,0 +1,15 @@ +package com.baeldung.keywords.finalkeyword; + +public final class Child extends Parent { + + @Override + void method1(int arg1, final int arg2) { + // OK + } + +/* @Override + void method2() { + // Compilation error + }*/ + +} diff --git a/core-java/src/main/java/com/baeldung/keywords/finalkeyword/GrandChild.java b/core-java/src/main/java/com/baeldung/keywords/finalkeyword/GrandChild.java new file mode 100644 index 0000000000..1530c5037f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/keywords/finalkeyword/GrandChild.java @@ -0,0 +1,5 @@ +package com.baeldung.keywords.finalkeyword; + +/*public class GrandChild extends Child { + // Compilation error +}*/ diff --git a/core-java/src/main/java/com/baeldung/keywords/finalkeyword/Parent.java b/core-java/src/main/java/com/baeldung/keywords/finalkeyword/Parent.java new file mode 100644 index 0000000000..5cd2996e7a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/keywords/finalkeyword/Parent.java @@ -0,0 +1,23 @@ +package com.baeldung.keywords.finalkeyword; + +public class Parent { + + int field1 = 1; + final int field2 = 2; + + Parent() { + field1 = 2; // OK +// field2 = 3; // Compilation error + } + + void method1(int arg1, final int arg2) { + arg1 = 2; // OK +// arg2 = 3; // Compilation error + } + + final void method2() { + final int localVar = 2; // OK +// localVar = 3; // Compilation error + } + +} diff --git a/core-java/src/main/java/com/baeldung/keywords/finallykeyword/FinallyExample.java b/core-java/src/main/java/com/baeldung/keywords/finallykeyword/FinallyExample.java new file mode 100644 index 0000000000..3c0aee3196 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/keywords/finallykeyword/FinallyExample.java @@ -0,0 +1,29 @@ +package com.baeldung.keywords.finallykeyword; + +public class FinallyExample { + + public static void main(String args[]) throws Exception { + try { + System.out.println("Execute try block"); + throw new Exception(); + } catch (Exception e) { + System.out.println("Execute catch block"); + } finally { + System.out.println("Execute finally block"); + } + + try { + System.out.println("Execute try block"); + } finally { + System.out.println("Execute finally block"); + } + + try { + System.out.println("Execute try block"); + throw new Exception(); + } finally { + System.out.println("Execute finally block"); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/maths/BigDecimalImpl.java b/core-java/src/main/java/com/baeldung/maths/BigDecimalImpl.java deleted file mode 100644 index 1472dd7d6d..0000000000 --- a/core-java/src/main/java/com/baeldung/maths/BigDecimalImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.maths; - -import java.math.BigDecimal; -import java.math.RoundingMode; - -public class BigDecimalImpl { - - public static void main(String[] args) { - - BigDecimal serviceTax = new BigDecimal("56.0084578639"); - serviceTax = serviceTax.setScale(2, RoundingMode.CEILING); - - BigDecimal entertainmentTax = new BigDecimal("23.00689"); - entertainmentTax = entertainmentTax.setScale(2, RoundingMode.FLOOR); - - BigDecimal totalTax = serviceTax.add(entertainmentTax); - } -} diff --git a/core-java/src/main/java/com/baeldung/maths/BigIntegerImpl.java b/core-java/src/main/java/com/baeldung/maths/BigIntegerImpl.java deleted file mode 100644 index 9f46345e04..0000000000 --- a/core-java/src/main/java/com/baeldung/maths/BigIntegerImpl.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.maths; - -import java.math.BigInteger; - -public class BigIntegerImpl { - - public static void main(String[] args) { - - BigInteger numStarsMilkyWay = new BigInteger("8731409320171337804361260816606476"); - BigInteger numStarsAndromeda = new BigInteger("5379309320171337804361260816606476"); - - BigInteger totalStars = numStarsMilkyWay.add(numStarsAndromeda); - - } - -} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/equalshashcode/Person.java b/core-java/src/main/java/com/baeldung/memoryleaks/equalshashcode/Person.java new file mode 100755 index 0000000000..e16d1ae6da --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/equalshashcode/Person.java @@ -0,0 +1,9 @@ +package com.baeldung.memoryleaks.equalshashcode; + +public class Person { + public String name; + + public Person(String name) { + this.name = name; + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/equalshashcode/PersonOptimized.java b/core-java/src/main/java/com/baeldung/memoryleaks/equalshashcode/PersonOptimized.java new file mode 100755 index 0000000000..3af70dd1eb --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/equalshashcode/PersonOptimized.java @@ -0,0 +1,25 @@ +package com.baeldung.memoryleaks.equalshashcode; + +public class PersonOptimized { + public String name; + + public PersonOptimized(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!(o instanceof PersonOptimized)) { + return false; + } + PersonOptimized person = (PersonOptimized) o; + return person.name.equals(name); + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + name.hashCode(); + return result; + }} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/finalize/BulkyObject.java b/core-java/src/main/java/com/baeldung/memoryleaks/finalize/BulkyObject.java new file mode 100755 index 0000000000..ce77d883f6 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/finalize/BulkyObject.java @@ -0,0 +1,32 @@ +package com.baeldung.memoryleaks.finalize; + +import java.nio.charset.Charset; +import java.util.Random; + +public class BulkyObject { + private String data[]; + + public BulkyObject() { + data = new String[1000000]; + + for(int i=0; i<1000000; i++) { + data[i] = getRandomString(); + } + } + + private String getRandomString() { + byte[] array = new byte[1000]; + new Random().nextBytes(array); + return new String(array, Charset.forName("UTF-8")); + } + + @Override + public void finalize() { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("Finalizer called"); + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/finalize/BulkyObjectOptimized.java b/core-java/src/main/java/com/baeldung/memoryleaks/finalize/BulkyObjectOptimized.java new file mode 100644 index 0000000000..dc1302432e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/finalize/BulkyObjectOptimized.java @@ -0,0 +1,22 @@ +package com.baeldung.memoryleaks.finalize; + +import java.nio.charset.Charset; +import java.util.Random; + +public class BulkyObjectOptimized { + private String data[]; + + public BulkyObjectOptimized() { + data = new String[1000000]; + + for(int i=0; i<1000000; i++) { + data[i] = getRandomString(); + } + } + + private String getRandomString() { + byte[] array = new byte[1000]; + new Random().nextBytes(array); + return new String(array, Charset.forName("UTF-8")); + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/BulkyObject.java b/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/BulkyObject.java new file mode 100755 index 0000000000..bbd5310182 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/BulkyObject.java @@ -0,0 +1,22 @@ +package com.baeldung.memoryleaks.innerclass; + +import java.nio.charset.Charset; +import java.util.Random; + +public class BulkyObject { + private String data[]; + + public BulkyObject() { + data = new String[1000000]; + + for(int i=0; i<1000000; i++) { + data[i] = getRandomString(); + } + } + + private String getRandomString() { + byte[] array = new byte[1000]; + new Random().nextBytes(array); + return new String(array, Charset.forName("UTF-8")); + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/InnerClassDriver.java b/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/InnerClassDriver.java new file mode 100755 index 0000000000..06f928bc4a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/InnerClassDriver.java @@ -0,0 +1,17 @@ +package com.baeldung.memoryleaks.innerclass; + +public class InnerClassDriver { + public static InnerClassWrapper.SimpleInnerClass getSimpleInnerClassObj() { + return new InnerClassWrapper().new SimpleInnerClass(); + } + + public static void main2(String[] args) { + InnerClassWrapper.SimpleInnerClass simpleInnerClassObj = getSimpleInnerClassObj(); + System.out.println("Debug point"); + } + + public static void main(String[] args) { + StaticNestedClassWrapper.StaticNestedClass simpleInnerClassObj = new StaticNestedClassWrapper.StaticNestedClass(); + System.out.println("Debug point"); + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/InnerClassWrapper.java b/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/InnerClassWrapper.java new file mode 100755 index 0000000000..25fecf9bb3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/InnerClassWrapper.java @@ -0,0 +1,10 @@ +package com.baeldung.memoryleaks.innerclass; + + +public class InnerClassWrapper { + private BulkyObject bulkyObject = new BulkyObject(); + + public class SimpleInnerClass { + + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/StaticNestedClassWrapper.java b/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/StaticNestedClassWrapper.java new file mode 100755 index 0000000000..d1729d78a3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/innerclass/StaticNestedClassWrapper.java @@ -0,0 +1,10 @@ +package com.baeldung.memoryleaks.innerclass; + + +public class StaticNestedClassWrapper { + private BulkyObject bulkyObject = new BulkyObject(); + + public static class StaticNestedClass { + + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/InternedString.java b/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/InternedString.java new file mode 100644 index 0000000000..cbba8f849d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/InternedString.java @@ -0,0 +1,17 @@ +package com.baeldung.memoryleaks.internedstrings; + +public class InternedString { + private static final String FILEPATH = "C:\\bigstring.txt"; + + public void readString() { + String s1 = ReadStringFromFileUtil.read(FILEPATH).intern(); + String s2 = ReadStringFromFileUtil.read(FILEPATH).intern(); + + if (s1 == s2) { + System.out.println("Both the strings objects are same"); + } + else { + System.out.println("Both the strings objects are different"); + } + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/ReadStringFromFileUtil.java b/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/ReadStringFromFileUtil.java new file mode 100644 index 0000000000..2b7d72accc --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/ReadStringFromFileUtil.java @@ -0,0 +1,34 @@ +package com.baeldung.memoryleaks.internedstrings; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +public class ReadStringFromFileUtil { + + public static String read(String fileName) { + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(fileName)); + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + sb.append("\n"); + line = br.readLine(); + } + return sb.toString(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/StringObject.java b/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/StringObject.java new file mode 100644 index 0000000000..e48e448d18 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/internedstrings/StringObject.java @@ -0,0 +1,17 @@ +package com.baeldung.memoryleaks.internedstrings; + +public class StringObject { + private static final String FILEPATH = "C:\\bigstring.txt"; + + public void readString() { + String s1 = ReadStringFromFileUtil.read(FILEPATH); + String s2 = ReadStringFromFileUtil.read(FILEPATH); + + if (s1 == s2) { + System.out.println("Both the strings objects are same"); + } + else { + System.out.println("Both the strings objects are different"); + } + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsDemo.java b/core-java/src/main/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsDemo.java new file mode 100644 index 0000000000..f2b220e76d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsDemo.java @@ -0,0 +1,21 @@ +package com.baeldung.memoryleaks.staticfields; + +import java.util.ArrayList; +import java.util.List; + +public class NonStaticFieldsDemo { + public List list = new ArrayList<>(); + + public void populateList() { + for (int i = 0; i < 10000000; i++) { + list.add(Math.random()); + } + System.out.println("Debug Point 2"); + } + + public static void main(String[] args) { + System.out.println("Debug Point 1"); + new NonStaticFieldsDemo().populateList(); + System.out.println("Debug Point 3"); + } +} diff --git a/core-java/src/main/java/com/baeldung/memoryleaks/staticfields/StaticFieldsDemo.java b/core-java/src/main/java/com/baeldung/memoryleaks/staticfields/StaticFieldsDemo.java new file mode 100644 index 0000000000..17cebc2843 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/memoryleaks/staticfields/StaticFieldsDemo.java @@ -0,0 +1,21 @@ +package com.baeldung.memoryleaks.staticfields; + +import java.util.ArrayList; +import java.util.List; + +public class StaticFieldsDemo { + public static List list = new ArrayList<>(); + + public void populateList() { + for (int i = 0; i < 10000000; i++) { + list.add(Math.random()); + } + System.out.println("Debug Point 2"); + } + + public static void main(String[] args) { + System.out.println("Debug Point 1"); + new StaticFieldsDemo().populateList(); + System.out.println("Debug Point 3"); + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/nth/root/calculator/NthRootCalculator.java b/core-java/src/main/java/com/baeldung/nth/root/calculator/NthRootCalculator.java new file mode 100644 index 0000000000..217f1e06de --- /dev/null +++ b/core-java/src/main/java/com/baeldung/nth/root/calculator/NthRootCalculator.java @@ -0,0 +1,8 @@ +package com.baeldung.nth.root.calculator; + +public class NthRootCalculator +{ + public Double calculate(Double base, Double n) { + return Math.pow(Math.E, Math.log(base)/n); + } +} diff --git a/core-java/src/main/java/com/baeldung/nth/root/main/Main.java b/core-java/src/main/java/com/baeldung/nth/root/main/Main.java new file mode 100644 index 0000000000..3fcd36812f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/nth/root/main/Main.java @@ -0,0 +1,13 @@ +package com.baeldung.nth.root.main; + +import com.baeldung.nth.root.calculator.NthRootCalculator; + +public class Main { + public static void main(String[] args) { + NthRootCalculator calculator = new NthRootCalculator(); + Double base = Double.parseDouble(args[0]); + Double n = Double.parseDouble(args[1]); + Double result = calculator.calculate(base, n); + System.out.println("The " + n + " root of " + base + " equals to " + result + "."); + } +} diff --git a/core-java/src/main/java/com/baeldung/objectsize/InstrumentationAgent.java b/core-java/src/main/java/com/baeldung/objectsize/InstrumentationAgent.java new file mode 100644 index 0000000000..66e9a44af8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/objectsize/InstrumentationAgent.java @@ -0,0 +1,18 @@ +package com.baeldung.objectsize; + +import java.lang.instrument.Instrumentation; + +public class InstrumentationAgent { + private static volatile Instrumentation globalInstrumentation; + + public static void premain(final String agentArgs, final Instrumentation inst) { + globalInstrumentation = inst; + } + + public static long getObjectSize(final Object object) { + if (globalInstrumentation == null) { + throw new IllegalStateException("Agent not initialized."); + } + return globalInstrumentation.getObjectSize(object); + } +} diff --git a/core-java/src/main/java/com/baeldung/objectsize/InstrumentationExample.java b/core-java/src/main/java/com/baeldung/objectsize/InstrumentationExample.java new file mode 100644 index 0000000000..f751d954c8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/objectsize/InstrumentationExample.java @@ -0,0 +1,59 @@ +package com.baeldung.objectsize; + +import java.util.ArrayList; +import java.util.List; + +public class InstrumentationExample { + + public static void printObjectSize(Object object) { + System.out.println("Object type: " + object.getClass() + ", size: " + InstrumentationAgent.getObjectSize(object) + " bytes"); + } + + public static void main(String[] arguments) { + String emptyString = ""; + String string = "Estimating Object Size Using Instrumentation"; + String[] stringArray = { emptyString, string, "com.baeldung" }; + String[] anotherStringArray = new String[100]; + List stringList = new ArrayList<>(); + StringBuilder stringBuilder = new StringBuilder(100); + int maxIntPrimitive = Integer.MAX_VALUE; + int minIntPrimitive = Integer.MIN_VALUE; + Integer maxInteger = Integer.MAX_VALUE; + Integer minInteger = Integer.MIN_VALUE; + long zeroLong = 0L; + double zeroDouble = 0.0; + boolean falseBoolean = false; + Object object = new Object(); + + class EmptyClass { + } + EmptyClass emptyClass = new EmptyClass(); + + class StringClass { + public String s; + } + StringClass stringClass = new StringClass(); + + printObjectSize(emptyString); + printObjectSize(string); + printObjectSize(stringArray); + printObjectSize(anotherStringArray); + printObjectSize(stringList); + printObjectSize(stringBuilder); + printObjectSize(maxIntPrimitive); + printObjectSize(minIntPrimitive); + printObjectSize(maxInteger); + printObjectSize(minInteger); + printObjectSize(zeroLong); + printObjectSize(zeroDouble); + printObjectSize(falseBoolean); + printObjectSize(Day.TUESDAY); + printObjectSize(object); + printObjectSize(emptyClass); + printObjectSize(stringClass); + } + + public enum Day { + MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY + } +} diff --git a/core-java/src/main/java/com/baeldung/objectsize/MANIFEST.MF b/core-java/src/main/java/com/baeldung/objectsize/MANIFEST.MF new file mode 100644 index 0000000000..b814f624d0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/objectsize/MANIFEST.MF @@ -0,0 +1 @@ +Premain-class: com.baeldung.objectsize.InstrumentationAgent diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java new file mode 100644 index 0000000000..e2259e4249 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java @@ -0,0 +1,149 @@ +package com.baeldung.passwordhashing; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Arrays; +import java.util.Base64; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +/** + * Hash passwords for storage, and test passwords against password tokens. + * + * Instances of this class can be used concurrently by multiple threads. + * + * @author erickson + * @see StackOverflow + */ +public final class PBKDF2Hasher +{ + + /** + * Each token produced by this class uses this identifier as a prefix. + */ + public static final String ID = "$31$"; + + /** + * The minimum recommended cost, used by default + */ + public static final int DEFAULT_COST = 16; + + private static final String ALGORITHM = "PBKDF2WithHmacSHA1"; + + private static final int SIZE = 128; + + private static final Pattern layout = Pattern.compile("\\$31\\$(\\d\\d?)\\$(.{43})"); + + private final SecureRandom random; + + private final int cost; + + public PBKDF2Hasher() + { + this(DEFAULT_COST); + } + + /** + * Create a password manager with a specified cost + * + * @param cost the exponential computational cost of hashing a password, 0 to 30 + */ + public PBKDF2Hasher(int cost) + { + iterations(cost); /* Validate cost */ + this.cost = cost; + this.random = new SecureRandom(); + } + + private static int iterations(int cost) + { + if ((cost < 0) || (cost > 30)) + throw new IllegalArgumentException("cost: " + cost); + return 1 << cost; + } + + /** + * Hash a password for storage. + * + * @return a secure authentication token to be stored for later authentication + */ + public String hash(char[] password) + { + byte[] salt = new byte[SIZE / 8]; + random.nextBytes(salt); + byte[] dk = pbkdf2(password, salt, 1 << cost); + byte[] hash = new byte[salt.length + dk.length]; + System.arraycopy(salt, 0, hash, 0, salt.length); + System.arraycopy(dk, 0, hash, salt.length, dk.length); + Base64.Encoder enc = Base64.getUrlEncoder().withoutPadding(); + return ID + cost + '$' + enc.encodeToString(hash); + } + + /** + * Authenticate with a password and a stored password token. + * + * @return true if the password and token match + */ + public boolean checkPassword(char[] password, String token) + { + Matcher m = layout.matcher(token); + if (!m.matches()) + throw new IllegalArgumentException("Invalid token format"); + int iterations = iterations(Integer.parseInt(m.group(1))); + byte[] hash = Base64.getUrlDecoder().decode(m.group(2)); + byte[] salt = Arrays.copyOfRange(hash, 0, SIZE / 8); + byte[] check = pbkdf2(password, salt, iterations); + int zero = 0; + for (int idx = 0; idx < check.length; ++idx) + zero |= hash[salt.length + idx] ^ check[idx]; + return zero == 0; + } + + private static byte[] pbkdf2(char[] password, byte[] salt, int iterations) + { + KeySpec spec = new PBEKeySpec(password, salt, iterations, SIZE); + try { + SecretKeyFactory f = SecretKeyFactory.getInstance(ALGORITHM); + return f.generateSecret(spec).getEncoded(); + } + catch (NoSuchAlgorithmException ex) { + throw new IllegalStateException("Missing algorithm: " + ALGORITHM, ex); + } + catch (InvalidKeySpecException ex) { + throw new IllegalStateException("Invalid SecretKeyFactory", ex); + } + } + + /** + * Hash a password in an immutable {@code String}. + * + *

Passwords should be stored in a {@code char[]} so that it can be filled + * with zeros after use instead of lingering on the heap and elsewhere. + * + * @deprecated Use {@link #hash(char[])} instead + */ + @Deprecated + public String hash(String password) + { + return hash(password.toCharArray()); + } + + /** + * Authenticate with a password in an immutable {@code String} and a stored + * password token. + * + * @deprecated Use {@link #checkPassword(char[],String)} instead. + * @see #hash(String) + */ + @Deprecated + public boolean checkPassword(String password, String token) + { + return checkPassword(password.toCharArray(), token); + } + +} diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java new file mode 100644 index 0000000000..4f5337f963 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java @@ -0,0 +1,35 @@ +package com.baeldung.passwordhashing; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + + +/** A really simple SHA_512 Encryption example. + * + */ +public class SHA512Hasher { + + public String hash(String passwordToHash, byte[] salt){ + String generatedPassword = null; + try { + MessageDigest md = MessageDigest.getInstance("SHA-512"); + md.update(salt); + byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8)); + StringBuilder sb = new StringBuilder(); + for(int i=0; i< bytes.length ;i++){ + sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); + } + generatedPassword = sb.toString(); + } + catch (NoSuchAlgorithmException e){ + e.printStackTrace(); + } + return generatedPassword; + } + + public boolean checkPassword(String hash, String attempt, byte[] salt){ + String generatedHash = hash(attempt, salt); + return hash.equals(generatedHash); + } +} diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java new file mode 100644 index 0000000000..36c9b65070 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java @@ -0,0 +1,18 @@ +package com.baeldung.passwordhashing; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import java.security.spec.KeySpec; + +/** A really simple SimplePBKDF2 Encryption example. + * + */ +public class SimplePBKDF2Hasher { + + public static String hashSimple(String password, byte[] salt) throws Exception{ + KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128); + SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + byte[] hash = f.generateSecret(spec).getEncoded(); + return String.valueOf(hash); + } +} diff --git a/core-java/src/main/java/com/baeldung/string/AppendCharAtPositionX.java b/core-java/src/main/java/com/baeldung/string/AppendCharAtPositionX.java new file mode 100644 index 0000000000..bebffe52f1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/string/AppendCharAtPositionX.java @@ -0,0 +1,45 @@ +/** + * + */ +package com.baeldung.string; + +/** + * @author swpraman + * + */ +public class AppendCharAtPositionX { + + public String addCharUsingCharArray(String str, char ch, int position) { + validate(str, position); + int len = str.length(); + char[] updatedArr = new char[len + 1]; + str.getChars(0, position, updatedArr, 0); + updatedArr[position] = ch; + str.getChars(position, len, updatedArr, position + 1); + return new String(updatedArr); + } + + public String addCharUsingSubstring(String str, char ch, int position) { + validate(str, position); + return str.substring(0, position) + ch + str.substring(position); + } + + public String addCharUsingStringBuilder(String str, char ch, int position) { + validate(str, position); + StringBuilder sb = new StringBuilder(str); + sb.insert(position, ch); + return sb.toString(); + } + + private void validate(String str, int position) { + if (str == null) { + throw new IllegalArgumentException("Str should not be null"); + } + int len = str.length(); + if (position < 0 || position > len) { + throw new IllegalArgumentException("position[" + position + "] should be " + + "in the range 0.." + len + " for string " + str); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java b/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java new file mode 100644 index 0000000000..69e151bfcb --- /dev/null +++ b/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java @@ -0,0 +1,70 @@ +package com.baeldung.switchstatement; + +public class SwitchStatement { + + public String exampleOfIF(String animal) { + + String result; + + if (animal.equals("DOG") || animal.equals("CAT")) { + result = "domestic animal"; + } else if (animal.equals("TIGER")) { + result = "wild animal"; + } else { + result = "unknown animal"; + } + return result; + } + + public String exampleOfSwitch(String animal) { + + String result; + + switch (animal) { + case "DOG": + case "CAT": + result = "domestic animal"; + break; + case "TIGER": + result = "wild animal"; + break; + default: + result = "unknown animal"; + break; + } + return result; + } + + public String forgetBreakInSwitch(String animal) { + + String result; + + switch (animal) { + + case "DOG": + System.out.println("domestic animal"); + result = "domestic animal"; + + default: + System.out.println("unknown animal"); + result = "unknown animal"; + + } + return result; + } + + public String constantCaseValue(String animal) { + + String result = ""; + + final String dog = "DOG"; + + switch (animal) { + + case dog: + result = "domestic animal"; + } + return result; + } + +} diff --git a/core-java/src/main/java/com/baeldung/synthetic/BridgeMethodDemo.java b/core-java/src/main/java/com/baeldung/synthetic/BridgeMethodDemo.java new file mode 100644 index 0000000000..bdf6684f78 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/synthetic/BridgeMethodDemo.java @@ -0,0 +1,23 @@ +package com.baeldung.synthetic; + +import java.util.Comparator; + +/** + * Class which contains a synthetic bridge method. + * + * @author Donato Rimenti + * + */ +public class BridgeMethodDemo implements Comparator { + + /* + * (non-Javadoc) + * + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @Override + public int compare(Integer o1, Integer o2) { + return 0; + } + +} diff --git a/core-java/src/main/java/com/baeldung/synthetic/SyntheticConstructorDemo.java b/core-java/src/main/java/com/baeldung/synthetic/SyntheticConstructorDemo.java new file mode 100644 index 0000000000..d3d75ac05e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/synthetic/SyntheticConstructorDemo.java @@ -0,0 +1,34 @@ +package com.baeldung.synthetic; + +/** + * Wrapper for a class which contains a synthetic constructor. + * + * @author Donato Rimenti + * + */ +public class SyntheticConstructorDemo { + + /** + * We need to instantiate the {@link NestedClass} using a private + * constructor from the enclosing instance in order to generate a synthetic + * constructor. + */ + private NestedClass nestedClass = new NestedClass(); + + /** + * Class which contains a synthetic constructor. + * + * @author Donato Rimenti + * + */ + class NestedClass { + + /** + * In order to generate a synthetic constructor, this class must have a + * private constructor. + */ + private NestedClass() { + } + } + +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/synthetic/SyntheticFieldDemo.java b/core-java/src/main/java/com/baeldung/synthetic/SyntheticFieldDemo.java new file mode 100644 index 0000000000..1813e03953 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/synthetic/SyntheticFieldDemo.java @@ -0,0 +1,22 @@ +package com.baeldung.synthetic; + +/** + * Wrapper for a class which contains a synthetic field reference to the outer + * class. + * + * @author Donato Rimenti + * + */ +public class SyntheticFieldDemo { + + /** + * Class which contains a synthetic field reference to the outer class. + * + * @author Donato Rimenti + * + */ + class NestedClass { + + } + +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/synthetic/SyntheticMethodDemo.java b/core-java/src/main/java/com/baeldung/synthetic/SyntheticMethodDemo.java new file mode 100644 index 0000000000..59be4e1429 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/synthetic/SyntheticMethodDemo.java @@ -0,0 +1,48 @@ +package com.baeldung.synthetic; + +/** + * Wrapper for a class which contains two synthetic methods accessors to a + * private field. + * + * @author Donato Rimenti + * + */ +public class SyntheticMethodDemo { + + /** + * Class which contains two synthetic methods accessors to a private field. + * + * @author Donato Rimenti + * + */ + class NestedClass { + + /** + * Field for which will be generated synthetic methods accessors. It's + * important that this field is private for this purpose. + */ + private String nestedField; + } + + /** + * Gets the private nested field. We need to read the nested field in order + * to generate the synthetic getter. + * + * @return the {@link NestedClass#nestedField} + */ + public String getNestedField() { + return new NestedClass().nestedField; + } + + /** + * Sets the private nested field. We need to write the nested field in order + * to generate the synthetic setter. + * + * @param nestedField + * the {@link NestedClass#nestedField} + */ + public void setNestedField(String nestedField) { + new NestedClass().nestedField = nestedField; + } + +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/throwsexception/DataAccessException.java b/core-java/src/main/java/com/baeldung/throwsexception/DataAccessException.java new file mode 100644 index 0000000000..0b371dcedb --- /dev/null +++ b/core-java/src/main/java/com/baeldung/throwsexception/DataAccessException.java @@ -0,0 +1,9 @@ +package com.baeldung.throwsexception; + +public class DataAccessException extends RuntimeException { + + public DataAccessException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/core-java/src/main/java/com/baeldung/throwsexception/Main.java b/core-java/src/main/java/com/baeldung/throwsexception/Main.java new file mode 100644 index 0000000000..17fbf5a582 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/throwsexception/Main.java @@ -0,0 +1,41 @@ +package com.baeldung.throwsexception; + +import com.sun.mail.iap.ConnectionException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.net.SocketException; + +public class Main { + + public static void main(String[] args) throws FileNotFoundException { + TryCatch tryCatch = new TryCatch(); + + try { + tryCatch.execute(); + } catch (ConnectionException | SocketException ex) { + System.out.println("IOException"); + } catch (Exception ex) { + System.out.println("General exception"); + } + + checkedException(); + checkedExceptionWithThrows(); + } + + private static void checkedExceptionWithThrows() throws FileNotFoundException { + File file = new File("not_existing_file.txt"); + FileInputStream stream = new FileInputStream(file); + } + + private static void checkedException() { + File file = new File("not_existing_file.txt"); + try { + FileInputStream stream = new FileInputStream(file); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/throwsexception/PersonRepository.java b/core-java/src/main/java/com/baeldung/throwsexception/PersonRepository.java new file mode 100644 index 0000000000..7d8345c3c1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/throwsexception/PersonRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.throwsexception; + +import java.sql.SQLException; +import java.util.List; + +public class PersonRepository { + + public List findAll() throws SQLException { + throw new SQLException(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/throwsexception/SimpleService.java b/core-java/src/main/java/com/baeldung/throwsexception/SimpleService.java new file mode 100644 index 0000000000..6bb8b90bf1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/throwsexception/SimpleService.java @@ -0,0 +1,22 @@ +package com.baeldung.throwsexception; + +import java.sql.SQLException; + +public class SimpleService { + + private PersonRepository personRepository = new PersonRepository(); + + public void wrappingException() { + try { + personRepository.findAll(); + } catch (SQLException e) { + throw new DataAccessException("SQL Exception", e); + } + } + + public void runtimeNullPointerException() { + String a = null; + a.length(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/throwsexception/TryCatch.java b/core-java/src/main/java/com/baeldung/throwsexception/TryCatch.java new file mode 100644 index 0000000000..2fd87f124d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/throwsexception/TryCatch.java @@ -0,0 +1,13 @@ +package com.baeldung.throwsexception; + +import com.sun.mail.iap.ConnectionException; + +import java.net.SocketException; + +public class TryCatch { + + public void execute() throws SocketException, ConnectionException, Exception { + //code that would throw any of: SocketException, ConnectionException, Exception + } + +} diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java new file mode 100644 index 0000000000..fb92eb8d0d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java @@ -0,0 +1,13 @@ +package com.baeldung.zoneddatetime; + +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +public class OffsetDateTimeExample { + + public OffsetDateTime getCurrentTimeByZoneOffset(String offset) { + ZoneOffset zoneOffSet= ZoneOffset.of(offset); + OffsetDateTime date = OffsetDateTime.now(zoneOffSet); + return date; + } +} diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java new file mode 100644 index 0000000000..58e2d4d5ad --- /dev/null +++ b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java @@ -0,0 +1,13 @@ +package com.baeldung.zoneddatetime; + +import java.time.OffsetTime; +import java.time.ZoneOffset; + +public class OffsetTimeExample { + + public OffsetTime getCurrentTimeByZoneOffset(String offset) { + ZoneOffset zoneOffSet = ZoneOffset.of(offset); + OffsetTime time = OffsetTime.now(zoneOffSet); + return time; + } +} diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java new file mode 100644 index 0000000000..b54b8c5225 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java @@ -0,0 +1,21 @@ +package com.baeldung.zoneddatetime; + +import java.time.ZoneId; +import java.time.ZonedDateTime; + +public class ZoneDateTimeExample { + + public ZonedDateTime getCurrentTimeByZoneId(String region) { + ZoneId zone = ZoneId.of(region); + ZonedDateTime date = ZonedDateTime.now(zone); + return date; + } + + public ZonedDateTime convertZonedDateTime(ZonedDateTime sourceDate, String destZone) { + + ZoneId destZoneId = ZoneId.of(destZone); + ZonedDateTime destDate = sourceDate.withZoneSameInstant(destZoneId); + + return destDate; + } +} diff --git a/core-java/src/main/resources/META-INF/MANIFEST.MF b/core-java/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..988de3193d --- /dev/null +++ b/core-java/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Agent-Class: com.baeldung.instrumentation.agent.MyInstrumentationAgent +Can-Redefine-Classes: true +Can-Retransform-Classes: true +Premain-Class: com.baeldung.instrumentation.agent.MyInstrumentationAgent +Main-Class: com.baeldung.instrumentation.application.Launcher diff --git a/core-java/src/main/resources/log4j2.xml b/core-java/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..a824bef9b0 --- /dev/null +++ b/core-java/src/main/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/core-java/src/main/resources/logback.xml b/core-java/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/core-java/src/main/resources/logback.xml +++ b/core-java/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/core-java/src/main/resources/product.png b/core-java/src/main/resources/product.png new file mode 100644 index 0000000000..4edd01c0a1 Binary files /dev/null and b/core-java/src/main/resources/product.png differ diff --git a/core-java/src/test/java/com/baeldung/binding/AnimalActivityUnitTest.java b/core-java/src/test/java/com/baeldung/binding/AnimalActivityUnitTest.java new file mode 100644 index 0000000000..41c67ff389 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/binding/AnimalActivityUnitTest.java @@ -0,0 +1,95 @@ +package com.baeldung.binding; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.Appender; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.LoggerFactory; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.verify; + +/** + *https://gist.github.com/bloodredsun/a041de13e57bf3c6c040 + */ +@RunWith(MockitoJUnitRunner.class) + +public class AnimalActivityUnitTest { + + @Mock + private Appender mockAppender; + @Captor + private ArgumentCaptor captorLoggingEvent; + + @Before + public void setup() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.addAppender(mockAppender); + } + + @After + public void teardown() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.detachAppender(mockAppender); + } + + @Test + public void givenAnimalReference__whenRefersAnimalObject_shouldCallFunctionWithAnimalParam() { + + Animal animal = new Animal(); + + AnimalActivity.sleep(animal); + + verify(mockAppender).doAppend(captorLoggingEvent.capture()); + + final LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel(), is(Level.INFO)); + + assertThat(loggingEvent.getFormattedMessage(), + is("Animal is sleeping")); + } + + @Test + public void givenDogReference__whenRefersCatObject_shouldCallFunctionWithAnimalParam() { + + Cat cat = new Cat(); + + AnimalActivity.sleep(cat); + + verify(mockAppender).doAppend(captorLoggingEvent.capture()); + + final LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel(), is(Level.INFO)); + + assertThat(loggingEvent.getFormattedMessage(), + is("Cat is sleeping")); + } + + @Test + public void givenAnimaReference__whenRefersDogObject_shouldCallFunctionWithAnimalParam() { + + Animal cat = new Cat(); + + AnimalActivity.sleep(cat); + + verify(mockAppender).doAppend(captorLoggingEvent.capture()); + + final LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel(), is(Level.INFO)); + + assertThat(loggingEvent.getFormattedMessage(), + is("Animal is sleeping")); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/binding/AnimalUnitTest.java b/core-java/src/test/java/com/baeldung/binding/AnimalUnitTest.java new file mode 100644 index 0000000000..a34640b58a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/binding/AnimalUnitTest.java @@ -0,0 +1,87 @@ +package com.baeldung.binding; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.Appender; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.LoggerFactory; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.List; + +/** + * Created by madhumita.g on 01-08-2018. + */ + +@RunWith(MockitoJUnitRunner.class) +public class AnimalUnitTest { + @Mock + private Appender mockAppender; + @Captor + private ArgumentCaptor captorLoggingEvent; + + @Before + public void setup() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.addAppender(mockAppender); + } + + @After + public void teardown() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.detachAppender(mockAppender); + } + + @Test + public void whenCalledWithoutParameters_shouldCallFunctionMakeNoiseWithoutParameters() { + + Animal animal = new Animal(); + + animal.makeNoise(); + + verify(mockAppender).doAppend(captorLoggingEvent.capture()); + + final LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel(), is(Level.INFO)); + + assertThat(loggingEvent.getFormattedMessage(), + is("generic animal noise")); + } + + @Test + public void whenCalledWithParameters_shouldCallFunctionMakeNoiseWithParameters() { + + Animal animal = new Animal(); + + int testValue = 3; + animal.makeNoise(testValue); + + verify(mockAppender,times(3)).doAppend(captorLoggingEvent.capture()); + + final List loggingEvents = captorLoggingEvent.getAllValues(); + + for(LoggingEvent loggingEvent : loggingEvents) + { + assertThat(loggingEvent.getLevel(), is(Level.INFO)); + + assertThat(loggingEvent.getFormattedMessage(), + is("generic animal noise countdown "+testValue)); + + testValue--; + } + } + +} diff --git a/core-java/src/test/java/com/baeldung/binding/CatUnitTest.java b/core-java/src/test/java/com/baeldung/binding/CatUnitTest.java new file mode 100644 index 0000000000..76ccfb7719 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/binding/CatUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.binding; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.Appender; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.LoggerFactory; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.verify; + +/** + * Created by madhumita.g on 01-08-2018. + */ +@RunWith(MockitoJUnitRunner.class) +public class CatUnitTest { + + @Mock + private Appender mockAppender; + + @Captor + private ArgumentCaptor captorLoggingEvent; + + @Before + public void setup() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.addAppender(mockAppender); + } + + @After + public void teardown() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.detachAppender(mockAppender); + } + + @Test + public void makeNoiseTest() { + + Cat cat = new Cat(); + + cat.makeNoise(); + + verify(mockAppender).doAppend(captorLoggingEvent.capture()); + + final LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel(), is(Level.INFO)); + + assertThat(loggingEvent.getFormattedMessage(), + is("meow")); + + } +} diff --git a/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderUnitTest.java b/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderUnitTest.java index ec35885b84..cabf9f7bdb 100644 --- a/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderUnitTest.java +++ b/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderUnitTest.java @@ -11,7 +11,7 @@ public class CustomClassLoaderUnitTest { public void customLoader() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { CustomClassLoader customClassLoader = new CustomClassLoader(); - Class c = customClassLoader.getClass(PrintClassLoader.class.getName()); + Class c = customClassLoader.findClass(PrintClassLoader.class.getName()); Object ob = c.newInstance(); diff --git a/core-java/src/test/java/com/baeldung/constructorsstaticfactorymethods/UserUnitTest.java b/core-java/src/test/java/com/baeldung/constructorsstaticfactorymethods/UserUnitTest.java new file mode 100644 index 0000000000..0c0266a111 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/constructorsstaticfactorymethods/UserUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.constructorsstaticfactorymethods; + +import com.baeldung.constructorsstaticfactorymethods.entities.User; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class UserUnitTest { + + @Test + public void givenUserClass_whenCalledcreateWithDefaultCountry_thenCorrect() { + assertThat(User.createWithDefaultCountry("John", "john@domain.com")).isInstanceOf(User.class); + } + + @Test + public void givenUserIntanceCreatedWithcreateWithDefaultCountry_whenCalledgetName_thenCorrect() { + User user = User.createWithDefaultCountry("John", "john@domain.com"); + assertThat(user.getName()).isEqualTo("John"); + } + + @Test + public void givenUserIntanceCreatedWithcreateWithDefaultCountry_whenCalledgetEmail_thenCorrect() { + User user = User.createWithDefaultCountry("John", "john@domain.com"); + assertThat(user.getEmail()).isEqualTo("john@domain.com"); + } + + @Test + public void givenUserIntanceCreatedWithcreateWithDefaultCountry_whenCalledgetCountry_thenCorrect() { + User user = User.createWithDefaultCountry("John", "john@domain.com"); + assertThat(user.getCountry()).isEqualTo("Argentina"); + } + + @Test + public void givenUserInstanceCreatedWithcreateWithInstantiationTime_whenCalledcreateWithInstantiationTime_thenCorrect() { + assertThat(User.createWithLoggedInstantiationTime("John", "john@domain.com", "Argentina")).isInstanceOf(User.class); + } + + @Test + public void givenUserInstanceCreatedWithgetSingletonIntance_whenCalledgetSingletonInstance_thenCorrect() { + User user1 = User.getSingletonInstance("John", "john@domain.com", "Argentina"); + User user2 = User.getSingletonInstance("John", "john@domain.com", "Argentina"); + assertThat(user1).isEqualTo(user2); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java b/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java new file mode 100644 index 0000000000..b767a24b16 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/encrypt/FileEncrypterDecrypterIntegrationTest.java @@ -0,0 +1,32 @@ +package com.baeldung.encrypt; + +import org.junit.Test; + +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import java.io.File; +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class FileEncrypterDecrypterIntegrationTest { + + @Test + public void givenStringAndFilename_whenEncryptingIntoFile_andDecryptingFileAgain_thenOriginalStringIsReturned() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, InvalidAlgorithmParameterException { + String originalContent = "foobar"; + SecretKey secretKey = KeyGenerator.getInstance("AES").generateKey(); + + FileEncrypterDecrypter fileEncrypterDecrypter = new FileEncrypterDecrypter(secretKey, "AES/CBC/PKCS5Padding"); + fileEncrypterDecrypter.encrypt(originalContent, "baz.enc"); + + String decryptedContent = fileEncrypterDecrypter.decrypt("baz.enc"); + assertThat(decryptedContent, is(originalContent)); + + new File("baz.enc").delete(); // cleanup + } +} diff --git a/core-java/src/test/java/com/baeldung/enums/PizzaUnitTest.java b/core-java/src/test/java/com/baeldung/enums/PizzaUnitTest.java index 35aa07821c..70bfe168dd 100644 --- a/core-java/src/test/java/com/baeldung/enums/PizzaUnitTest.java +++ b/core-java/src/test/java/com/baeldung/enums/PizzaUnitTest.java @@ -75,26 +75,5 @@ public class PizzaUnitTest { pz.setStatus(Pizza.PizzaStatusEnum.READY); pz.deliver(); assertTrue(pz.getStatus() == Pizza.PizzaStatusEnum.DELIVERED); - } - - @Test - public void whenConvertedIntoEnum_thenGetsConvertedCorrectly() { - String pizzaEnumValue = "READY"; - PizzaStatusEnum pizzaStatusEnum = PizzaStatusEnum.valueOf(pizzaEnumValue); - assertTrue(pizzaStatusEnum == PizzaStatusEnum.READY); - } - - @Test(expected = IllegalArgumentException.class) - public void whenConvertedIntoEnum_thenThrowsException() { - String pizzaEnumValue = "rEAdY"; - PizzaStatusEnum pizzaStatusEnum = PizzaStatusEnum.valueOf(pizzaEnumValue); - } - - @Test(expected = IllegalArgumentException.class) - public void givenInvalidEnumValueContentWiseAsString_whenConvertedIntoEnum_thenThrowsException() { - String pizzaEnumValue = "invalid"; - PizzaStatusEnum pizzaStatusEnum = PizzaStatusEnum.valueOf(pizzaEnumValue); - } - - + } } diff --git a/core-java/src/test/java/com/baeldung/exceptionhandling/ExceptionsUnitTest.java b/core-java/src/test/java/com/baeldung/exceptionhandling/ExceptionsUnitTest.java new file mode 100644 index 0000000000..b3f585cfe4 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/exceptionhandling/ExceptionsUnitTest.java @@ -0,0 +1,80 @@ +package com.baeldung.exceptionhandling; + +import org.junit.Test; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.NoSuchFileException; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class ExceptionsUnitTest { + + Exceptions exceptions = new Exceptions(); + + @Test + public void getPlayers() { + assertThatThrownBy(() -> exceptions.getPlayers()) + .isInstanceOf(NoSuchFileException.class); + } + + @Test + public void loadAllPlayers() { + assertThatThrownBy(() -> exceptions.loadAllPlayers("")) + .isInstanceOf(IllegalStateException.class); + } + + @Test + public void getPlayerScoreThrows() { + assertThatThrownBy(() -> exceptions.getPlayerScoreThrows("")) + .isInstanceOf(FileNotFoundException.class); + } + + @Test + public void getPlayerScoreTryCatch() { + assertThatThrownBy(() -> exceptions.getPlayerScoreTryCatch("")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + public void getPlayerScoreFinally() { + assertThatThrownBy(() -> exceptions.getPlayerScoreFinally("")) + .isInstanceOf(FileNotFoundException.class); + } + + @Test + public void loadAllPlayersThrowingChecked() { + assertThatThrownBy(() -> exceptions.loadAllPlayersThrowingChecked("")) + .isInstanceOf(TimeoutException.class); + } + + @Test + public void loadAllPlayersThrowingUnchecked() { + assertThatThrownBy(() -> exceptions.loadAllPlayersThrowingUnchecked("")) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + public void loadAllPlayersWrapping() { + assertThatThrownBy(() -> exceptions.loadAllPlayersWrapping("")) + .isInstanceOf(IOException.class); + } + + @Test + public void loadAllPlayersRethrowing() { + assertThatThrownBy(() -> exceptions.loadAllPlayersRethrowing("")) + .isInstanceOf(PlayerLoadException.class); + } + + @Test + public void loadAllPlayersThrowable() { + assertThatThrownBy(() -> exceptions.loadAllPlayersThrowable("")) + .isInstanceOf(NullPointerException.class); + } + + @Test + public void getPlayerScoreSwallowingExceptionAntiPatternAlternative2() { + assertThatThrownBy(() -> exceptions.getPlayerScoreSwallowingExceptionAntiPatternAlternative2("")) + .isInstanceOf(PlayerScoreException.class); + } +} diff --git a/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java b/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java new file mode 100644 index 0000000000..394de9c576 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/exceptions/GlobalExceptionHandlerUnitTest.java @@ -0,0 +1,64 @@ +package com.baeldung.exceptions; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.LoggerFactory; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.Appender; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class GlobalExceptionHandlerUnitTest { + + @Mock + private Appender mockAppender; + + @Captor + private ArgumentCaptor captorLoggingEvent; + + @Before + public void setup() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.addAppender(mockAppender); + + Handler globalExceptionHandler = new Handler(); + Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler); + } + + @After + public void teardown() { + final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); + logger.detachAppender(mockAppender); + } + + @Test + public void whenArithmeticException_thenUseUncaughtExceptionHandler() throws InterruptedException { + + Thread globalExceptionHandlerThread = new Thread() { + public void run() { + GlobalExceptionHandler globalExceptionHandlerObj = new GlobalExceptionHandler(); + globalExceptionHandlerObj.performArithmeticOperation(99, 0); + } + }; + + globalExceptionHandlerThread.start(); + globalExceptionHandlerThread.join(); + + verify(mockAppender).doAppend(captorLoggingEvent.capture()); + LoggingEvent loggingEvent = captorLoggingEvent.getValue(); + + assertThat(loggingEvent.getLevel()).isEqualTo(Level.INFO); + assertThat(loggingEvent.getFormattedMessage()).isEqualTo("Unhandled exception caught!"); + } + +} diff --git a/core-java/src/test/java/com/baeldung/fileparser/BufferedReaderUnitTest.java b/core-java/src/test/java/com/baeldung/fileparser/BufferedReaderUnitTest.java new file mode 100644 index 0000000000..78f900d796 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/fileparser/BufferedReaderUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.fileparser; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; + +public class BufferedReaderUnitTest { + + protected static final String TEXT_FILENAME = "src/test/resources/sampleTextFile.txt"; + + @Test + public void whenParsingExistingTextFile_thenGetArrayList() throws IOException { + List lines = BufferedReaderExample.generateArrayListFromFile(TEXT_FILENAME); + assertTrue("File does not has 2 lines", lines.size() == 2); + } +} diff --git a/core-java/src/test/java/com/baeldung/fileparser/FileReaderUnitTest.java b/core-java/src/test/java/com/baeldung/fileparser/FileReaderUnitTest.java new file mode 100644 index 0000000000..a38e58d348 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/fileparser/FileReaderUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.fileparser; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; + +public class FileReaderUnitTest { + + protected static final String TEXT_FILENAME = "src/test/resources/sampleTextFile.txt"; + + @Test + public void whenParsingExistingTextFile_thenGetArrayList() throws IOException { + List lines = FileReaderExample.generateArrayListFromFile(TEXT_FILENAME); + assertTrue("File does not has 2 lines", lines.size() == 2); + } +} diff --git a/core-java/src/test/java/com/baeldung/fileparser/FilesReadAllLinesUnitTest.java b/core-java/src/test/java/com/baeldung/fileparser/FilesReadAllLinesUnitTest.java new file mode 100644 index 0000000000..c0b742fd47 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/fileparser/FilesReadAllLinesUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.fileparser; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; + +public class FilesReadAllLinesUnitTest { + + protected static final String TEXT_FILENAME = "src/test/resources/sampleTextFile.txt"; + + @Test + public void whenParsingExistingTextFile_thenGetArrayList() throws IOException { + List lines = FilesReadLinesExample.generateArrayListFromFile(TEXT_FILENAME); + assertTrue("File does not has 2 lines", lines.size() == 2); + } +} diff --git a/core-java/src/test/java/com/baeldung/fileparser/ScannerIntUnitTest.java b/core-java/src/test/java/com/baeldung/fileparser/ScannerIntUnitTest.java new file mode 100644 index 0000000000..0a398ba7c6 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/fileparser/ScannerIntUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.fileparser; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; + +public class ScannerIntUnitTest { + + protected static final String NUMBER_FILENAME = "src/test/resources/sampleNumberFile.txt"; + + @Test + public void whenParsingExistingTextFile_thenGetIntArrayList() throws IOException { + List numbers = ScannerIntExample.generateArrayListFromFile(NUMBER_FILENAME); + assertTrue("File does not has 2 lines", numbers.size() == 2); + } +} diff --git a/core-java/src/test/java/com/baeldung/fileparser/ScannerStringUnitTest.java b/core-java/src/test/java/com/baeldung/fileparser/ScannerStringUnitTest.java new file mode 100644 index 0000000000..8f9b0a56c0 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/fileparser/ScannerStringUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.fileparser; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; + +public class ScannerStringUnitTest { + + protected static final String TEXT_FILENAME = "src/test/resources/sampleTextFile.txt"; + + @Test + public void whenParsingExistingTextFile_thenGetArrayList() throws IOException { + List lines = ScannerStringExample.generateArrayListFromFile(TEXT_FILENAME); + assertTrue("File does not has 2 lines", lines.size() == 2); + } +} diff --git a/core-java/src/test/java/com/baeldung/heapsort/HeapUnitTest.java b/core-java/src/test/java/com/baeldung/heapsort/HeapUnitTest.java new file mode 100644 index 0000000000..cc3e49b6c9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/heapsort/HeapUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.heapsort; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class HeapUnitTest { + + @Test + public void givenNotEmptyHeap_whenPopCalled_thenItShouldReturnSmallestElement() { + // given + Heap heap = Heap.of(3, 5, 1, 4, 2); + + // when + int head = heap.pop(); + + // then + assertThat(head).isEqualTo(1); + } + + @Test + public void givenNotEmptyIterable_whenSortCalled_thenItShouldReturnElementsInSortedList() { + // given + List elements = Arrays.asList(3, 5, 1, 4, 2); + + // when + List sortedElements = Heap.sort(elements); + + // then + assertThat(sortedElements).isEqualTo(Arrays.asList(1, 2, 3, 4, 5)); + } + +} diff --git a/core-java/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java b/core-java/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java new file mode 100644 index 0000000000..b484eecef7 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java @@ -0,0 +1,59 @@ +package com.baeldung.java.listInitialization; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import lombok.extern.java.Log; + +import org.junit.Assert; +import org.junit.Test; + +@Log +public class ListInitializationUnitTest { + + @Test + public void givenAnonymousInnerClass_thenInitialiseList() { + List cities = new ArrayList() { + { + add("New York"); + add("Rio"); + add("Tokyo"); + } + }; + + Assert.assertTrue(cities.contains("New York")); + } + + @Test + public void givenArraysAsList_thenInitialiseList() { + List list = Arrays.asList("foo", "bar"); + + Assert.assertTrue(list.contains("foo")); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenArraysAsList_whenAdd_thenUnsupportedException() { + List list = Arrays.asList("foo", "bar"); + + list.add("baz"); + } + + @Test + public void givenArrayAsList_whenCreated_thenShareReference() { + String[] array = { "foo", "bar" }; + List list = Arrays.asList(array); + array[0] = "baz"; + Assert.assertEquals("baz", list.get(0)); + } + + @Test + public void givenStream_thenInitializeList() { + List list = Stream.of("foo", "bar") + .collect(Collectors.toList()); + + Assert.assertTrue(list.contains("foo")); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/mimetype/MimeTypeUnitTest.java b/core-java/src/test/java/com/baeldung/java/mimetype/MimeTypeUnitTest.java new file mode 100644 index 0000000000..c8da2c1339 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/mimetype/MimeTypeUnitTest.java @@ -0,0 +1,131 @@ +package com.baeldung.java.mimetype; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.net.FileNameMap; +import java.net.MalformedURLException; +import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Path; + +import javax.activation.MimetypesFileTypeMap; + +import org.apache.tika.Tika; +import org.junit.Test; + +import net.sf.jmimemagic.Magic; +import net.sf.jmimemagic.MagicException; +import net.sf.jmimemagic.MagicMatch; +import net.sf.jmimemagic.MagicMatchNotFoundException; +import net.sf.jmimemagic.MagicParseException; + +/** + * Test class demonstrating various strategies to resolve MIME type of a file. + * @author tritty + * + */ +public class MimeTypeUnitTest { + /** + * Expected Ouput. + */ + public static final String PNG_EXT = "image/png"; + + /** + * The location of the file. + */ + public static final String FILE_LOC = "src/test/resources/product.png"; + + /** + * Test method, demonstrating usage in Java 7. + * + * @throws IOException + */ + @Test + public void whenUsingJava7_thenSuccess() throws IOException { + final Path path = new File(FILE_LOC).toPath(); + final String mimeType = Files.probeContentType(path); + assertEquals(mimeType, PNG_EXT); + } + + /** + * Test method demonstrating the usage of URLConnection to resolve MIME type. + * + * @throws MalformedURLException + * @throws IOException + */ + @Test + public void whenUsingGetContentType_thenSuccess() throws MalformedURLException, IOException { + final File file = new File(FILE_LOC); + final URLConnection connection = file.toURL() + .openConnection(); + final String mimeType = connection.getContentType(); + assertEquals(mimeType, PNG_EXT); + } + + /** + * Test method demonstrating the usage of URLConnection to resolve MIME type. + * + */ + @Test + public void whenUsingGuessContentTypeFromName_thenSuccess() { + final File file = new File(FILE_LOC); + final String mimeType = URLConnection.guessContentTypeFromName(file.getName()); + assertEquals(mimeType, PNG_EXT); + } + + /** + * Test method demonstrating the usage of FileNameMap from URLConnection + * to resolve MIME type of a file. + * + */ + @Test + public void whenUsingGetFileNameMap_thenSuccess() { + final File file = new File(FILE_LOC); + final FileNameMap fileNameMap = URLConnection.getFileNameMap(); + final String mimeType = fileNameMap.getContentTypeFor(file.getName()); + assertEquals(mimeType, PNG_EXT); + } + + /** + * Test method demonstrating the usage of MimeTypesFileTypeMap for resolution of + * MIME type. + * + */ + @Test + public void whenUsingMimeTypesFileTypeMap_thenSuccess() { + final File file = new File(FILE_LOC); + final MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap(); + final String mimeType = fileTypeMap.getContentType(file.getName()); + assertEquals(mimeType, PNG_EXT); + } + + /** + * Test method demonstrating usage of jMimeMagic. + * + * @throws MagicParseException + * @throws MagicMatchNotFoundException + * @throws MagicException + */ + @Test + public void whenUsingJmimeMagic_thenSuccess() throws MagicParseException, MagicMatchNotFoundException, MagicException { + final File file = new File(FILE_LOC); + final Magic magic = new Magic(); + final MagicMatch match = magic.getMagicMatch(file, false); + assertEquals(match.getMimeType(), PNG_EXT); + } + + /** + * Test method demonstrating usage of Apache Tika. + * + * @throws IOException + */ + @Test + public void whenUsingTika_thenSuccess() throws IOException { + final File file = new File(FILE_LOC); + final Tika tika = new Tika(); + final String mimeType = tika.detect(file); + assertEquals(mimeType, PNG_EXT); + } +} diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/equalshashcode/PersonMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/equalshashcode/PersonMemoryLeakUnitTest.java new file mode 100644 index 0000000000..3fa1db18d2 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/memoryleaks/equalshashcode/PersonMemoryLeakUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.memoryleaks.equalshashcode; + +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Ignore; +import org.junit.Test; + +public class PersonMemoryLeakUnitTest { + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenMap_whenEqualsAndHashCodeNotOverridden_thenMemoryLeak() { + Map map = new HashMap(); + for(int i=0; i<10000000; i++) { + map.put(new Person("jon"), 1); + } + assertTrue(map.size() > 1); + System.out.print("Debug Point - VisuaLVM"); + } + + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenMap_whenEqualsAndHashCodeOverridden_thenNoMemoryLeak() { + Map map = new HashMap(); + for(int i=0; i<10000; i++) { + map.put(new PersonOptimized("jon"), 1); + } + assertTrue(map.size() == 1); + System.out.print("Debug Point - VisuaLVM"); + } +} diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/finalize/FinalizeMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/finalize/FinalizeMemoryLeakUnitTest.java new file mode 100644 index 0000000000..b6d81a8968 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/memoryleaks/finalize/FinalizeMemoryLeakUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.memoryleaks.finalize; + +import org.junit.Ignore; +import org.junit.Test; + +public class FinalizeMemoryLeakUnitTest { + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenObjectWithFinalizer_whenCreatingAndDestroyingThisObject_thenMemoryLeak() { + BulkyObject[] stock = new BulkyObject[100000]; + + for(int i=0; i<100000; i++) { + stock[i] = new BulkyObject(); + } + System.out.print("Debug Point - VisuaLVM"); + } + + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenObjectWithoutFinalizer_whenCreatingAndDestroyingThisObject_thenNoMemoryLeak() { + BulkyObjectOptimized[] stock = new BulkyObjectOptimized[100000]; + + for(int i=0; i<100000; i++) { + stock[i] = new BulkyObjectOptimized(); + } + System.out.print("Debug Point - VisuaLVM"); + } +} diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/innerclass/StaticInnerClassMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/innerclass/StaticInnerClassMemoryLeakUnitTest.java new file mode 100644 index 0000000000..0854e4a38a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/memoryleaks/innerclass/StaticInnerClassMemoryLeakUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.memoryleaks.innerclass; + +import org.junit.Ignore; +import org.junit.Test; + +public class StaticInnerClassMemoryLeakUnitTest { + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenUsingInnerClass_whenInitializingInnerClass_thenInnerClassHoldsReferenceOfOuterObject() { + InnerClassWrapper.SimpleInnerClass simpleInnerClassObj = new InnerClassWrapper().new SimpleInnerClass(); + System.out.print("Debug Point - VisuaLVM"); + } + + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenUsingStaticNestedClass_whenInitializingInnerClass_thenStaticNestedClassDoesntReferenceOuterObject() { + StaticNestedClassWrapper.StaticNestedClass staticNestedClassObj = new StaticNestedClassWrapper.StaticNestedClass(); + System.out.print("Debug Point - VisuaLVM"); + } +} diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/internedstrings/StringInternMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/internedstrings/StringInternMemoryLeakUnitTest.java new file mode 100644 index 0000000000..6d363e0bdc --- /dev/null +++ b/core-java/src/test/java/com/baeldung/memoryleaks/internedstrings/StringInternMemoryLeakUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.memoryleaks.internedstrings; + +import org.junit.Ignore; +import org.junit.Test; + +public class StringInternMemoryLeakUnitTest { + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenJava6OrBelow_whenInterningLargeStrings_thenPermgenIncreases() { + new InternedString().readString(); + System.out.print("Debug Point - VisuaLVM"); + } + + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenJava6OrBelow_whenNotInterningLargeStrings_thenPermgenDoesntIncrease() { + new StringObject().readString(); + System.out.print("Debug Point - VisuaLVM"); + } +} diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsMemoryLeakUnitTest.java new file mode 100644 index 0000000000..e64fdb73e0 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsMemoryLeakUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.memoryleaks.staticfields; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; + +public class NonStaticFieldsMemoryLeakUnitTest { + public List list = new ArrayList<>(); + + public void populateList() { + for (int i = 0; i < 10000000; i++) { + list.add(Math.random()); + } + System.out.println("Debug Point 2"); + } + + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenNonStaticLargeList_whenPopulatingList_thenListGarbageCollected() { + System.out.println("Debug Point 1"); + new NonStaticFieldsMemoryLeakUnitTest().populateList(); + System.out.println("Debug Point 3"); + } +} diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/StaticFieldsMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/StaticFieldsMemoryLeakUnitTest.java new file mode 100644 index 0000000000..1765f0cf0d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/StaticFieldsMemoryLeakUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.memoryleaks.staticfields; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; + +public class StaticFieldsMemoryLeakUnitTest { + public static List list = new ArrayList<>(); + + public void populateList() { + for (int i = 0; i < 10000000; i++) { + list.add(Math.random()); + } + System.out.println("Debug Point 2"); + } + + @Test + @Ignore // Test deliberately ignored as memory leak tests consume lots of resources + public void givenStaticLargeList_whenPopulatingList_thenListIsNotGarbageCollected() { + System.out.println("Debug Point 1"); + new StaticFieldsDemo().populateList(); + System.out.println("Debug Point 3"); + } +} diff --git a/core-java/src/test/java/com/baeldung/modulo/ModuloUnitTest.java b/core-java/src/test/java/com/baeldung/modulo/ModuloUnitTest.java new file mode 100644 index 0000000000..8b3685adf3 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/modulo/ModuloUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.modulo; + +import org.junit.Test; +import static org.assertj.core.api.Java6Assertions.*; + +public class ModuloUnitTest { + + @Test + public void whenIntegerDivision_thenLosesRemainder(){ + assertThat(11 / 4).isEqualTo(2); + } + + @Test + public void whenDoubleDivision_thenKeepsRemainder(){ + assertThat(11 / 4.0).isEqualTo(2.75); + } + + @Test + public void whenModulo_thenReturnsRemainder(){ + assertThat(11 % 4).isEqualTo(3); + } + + @Test(expected = ArithmeticException.class) + public void whenDivisionByZero_thenArithmeticException(){ + double result = 1 / 0; + } + + @Test(expected = ArithmeticException.class) + public void whenModuloByZero_thenArithmeticException(){ + double result = 1 % 0; + } + + @Test + public void whenDivisorIsOddAndModulusIs2_thenResultIs1(){ + assertThat(3 % 2).isEqualTo(1); + } + + @Test + public void whenDivisorIsEvenAndModulusIs2_thenResultIs0(){ + assertThat(4 % 2).isEqualTo(0); + } + + @Test + public void whenItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds(){ + int QUEUE_CAPACITY= 10; + int[] circularQueue = new int[QUEUE_CAPACITY]; + int itemsInserted = 0; + for (int value = 0; value < 1000; value++) { + int writeIndex = ++itemsInserted % QUEUE_CAPACITY; + circularQueue[writeIndex] = value; + } + } + +} diff --git a/core-java/src/test/java/com/baeldung/nth/root/calculator/NthRootCalculatorUnitTest.java b/core-java/src/test/java/com/baeldung/nth/root/calculator/NthRootCalculatorUnitTest.java new file mode 100644 index 0000000000..286dffb56a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nth/root/calculator/NthRootCalculatorUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.nth.root.calculator; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class NthRootCalculatorUnitTest { + + @InjectMocks + private NthRootCalculator nthRootCalculator; + + @Test + public void giventThatTheBaseIs125_andTheExpIs3_whenCalculateIsCalled_thenTheResultIsTheCorrectOne() { + Double result = nthRootCalculator.calculate(125.0, 3.0); + assertEquals(result, (Double) 5.0d); + } +} diff --git a/core-java/src/test/java/com/baeldung/nth/root/main/MainUnitTest.java b/core-java/src/test/java/com/baeldung/nth/root/main/MainUnitTest.java new file mode 100644 index 0000000000..a2fd839ba4 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nth/root/main/MainUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.nth.root.main; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import static org.junit.Assert.assertEquals; + +public class MainUnitTest { + @InjectMocks + private Main main; + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final PrintStream originalOut = System.out; + + @Before + public void setUpStreams() { + System.setOut(new PrintStream(outContent)); + } + + @After + public void restoreStreams() { + System.setOut(originalOut); + } + + @Test + public void givenThatTheBaseIs125_andTheExpIs3_whenMainIsCalled_thenTheCorrectResultIsPrinted() { + main.main(new String[]{"125.0", "3.0"}); + assertEquals("The 3.0 root of 125.0 equals to 5.0.\n", outContent.toString().replaceAll("\r", "")); + } +} diff --git a/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java b/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java new file mode 100644 index 0000000000..8e90725c77 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.passwordhashing; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class PBKDF2HasherUnitTest { + + private PBKDF2Hasher mPBKDF2Hasher; + + @Before + public void setUp() throws Exception { + mPBKDF2Hasher = new PBKDF2Hasher(); + } + + @Test + public void givenCorrectMessageAndHash_whenAuthenticated_checkAuthenticationSucceeds() throws Exception { + String message1 = "password123"; + + String hash1 = mPBKDF2Hasher.hash(message1.toCharArray()); + + assertTrue(mPBKDF2Hasher.checkPassword(message1.toCharArray(), hash1)); + + } + + @Test + public void givenWrongMessage_whenAuthenticated_checkAuthenticationFails() throws Exception { + String message1 = "password123"; + + String hash1 = mPBKDF2Hasher.hash(message1.toCharArray()); + + String wrongPasswordAttempt = "IamWrong"; + + assertFalse(mPBKDF2Hasher.checkPassword(wrongPasswordAttempt.toCharArray(), hash1)); + + } + + +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java b/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java new file mode 100644 index 0000000000..3acfb0ba9d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.passwordhashing; + +import org.junit.Before; +import org.junit.Test; + +import java.security.SecureRandom; + +import static org.junit.Assert.*; + +/** + * Created by PhysicsSam on 06-Sep-18. + */ +public class SHA512HasherUnitTest { + + private SHA512Hasher hasher; + private SecureRandom secureRandom; + + @Before + public void setUp() throws Exception { + hasher = new SHA512Hasher(); + secureRandom = new SecureRandom(); + } + + @Test + public void givenSamePasswordAndSalt_whenHashed_checkResultingHashesAreEqual() throws Exception { + + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + + String hash1 = hasher.hash("password", salt); + String hash2 = hasher.hash("password", salt); + + assertEquals(hash1, hash2); + + } + + @Test + public void givenSamePasswordAndDifferentSalt_whenHashed_checkResultingHashesNotEqual() throws Exception { + + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + String hash1 = hasher.hash("password", salt); + //generate a second salt + byte[] secondSalt = new byte[16]; + String hash2 = hasher.hash("password", secondSalt); + + assertNotEquals(hash1, hash2); + + } + + @Test + public void givenPredefinedHash_whenCorrectAttemptGiven_checkAuthenticationSucceeds() throws Exception { + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + + String originalHash = hasher.hash("password123", salt); + + assertTrue(hasher.checkPassword(originalHash, "password123", salt)); + } + + @Test + public void givenPredefinedHash_whenIncorrectAttemptGiven_checkAuthenticationFails() throws Exception { + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + + String originalHash = hasher.hash("password123", salt); + + assertFalse(hasher.checkPassword(originalHash, "password124", salt)); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/regexp/optmization/OptimizedMatcherUnitTest.java b/core-java/src/test/java/com/baeldung/regexp/optmization/OptimizedMatcherUnitTest.java new file mode 100644 index 0000000000..f21a755b01 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/regexp/optmization/OptimizedMatcherUnitTest.java @@ -0,0 +1,109 @@ +package com.baeldung.regexp.optmization; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.Assert.assertTrue; + +public class OptimizedMatcherUnitTest { + + private long time; + private long mstimePreCompiled; + private long mstimeNotPreCompiled; + + private String action; + + private List items; + + @Before + public void setup() { + Random random = new Random(); + items = new ArrayList(); + long average = 0; + + for (int i = 0; i < 100000; ++i) { + StringBuilder s = new StringBuilder(); + int characters = random.nextInt(7) + 1; + for (int k = 0; k < characters; ++ k) { + char c = (char)(random.nextInt('Z' - 'A') + 'A'); + int rep = random.nextInt(95) + 5; + for (int j = 0; j < rep; ++ j) + s.append(c); + average += rep; + } + items.add(s.toString()); + } + + average /= 100000; + System.out.println("generated data, average length: " + average); + } + + + @Test + public void givenANotPreCompiledAndAPreCompiledPatternA_whenMatcheItems_thenPreCompiledFasterThanNotPreCompiled() { + + testPatterns("A*"); + assertTrue(mstimePreCompiled < mstimeNotPreCompiled); + } + + @Test + public void givenANotPreCompiledAndAPreCompiledPatternABC_whenMatcheItems_thenPreCompiledFasterThanNotPreCompiled() { + + testPatterns("A*B*C*"); + assertTrue(mstimePreCompiled < mstimeNotPreCompiled); + } + + @Test + public void givenANotPreCompiledAndAPreCompiledPatternECWF_whenMatcheItems_thenPreCompiledFasterThanNotPreCompiled() { + + testPatterns("E*C*W*F*"); + assertTrue(mstimePreCompiled < mstimeNotPreCompiled); + } + + private void testPatterns(String regex) { + time = System.nanoTime(); + int matched = 0; + int unmatched = 0; + + for (String item : this.items) { + if (item.matches(regex)) { + ++matched; + } + else { + ++unmatched; + } + } + + this.action = "uncompiled: regex=" + regex + " matched=" + matched + " unmatched=" + unmatched; + + this.mstimeNotPreCompiled = (System.nanoTime() - time) / 1000000; + System.out.println(this.action + ": " + mstimeNotPreCompiled + "ms"); + + time = System.nanoTime(); + + Matcher matcher = Pattern.compile(regex).matcher(""); + matched = 0; + unmatched = 0; + + for (String item : this.items) { + if (matcher.reset(item).matches()) { + ++matched; + } + else { + ++unmatched; + } + } + + this.action = "compiled: regex=" + regex + " matched=" + matched + " unmatched=" + unmatched; + + this.mstimePreCompiled = (System.nanoTime() - time) / 1000000; + System.out.println(this.action + ": " + mstimePreCompiled + "ms"); + } +} diff --git a/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java new file mode 100644 index 0000000000..8dbfcaf5e7 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java @@ -0,0 +1,100 @@ +package com.baeldung.removingdecimals; + +import org.junit.Test; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.concurrent.TimeUnit; + +/** + * This benchmark compares some of the approaches to formatting a floating-point + * value into a {@link String} while removing the decimal part. + * + * To run, simply run the {@link RemovingDecimalsManualTest#runBenchmarks()} test + * at the end of this class. + * + * The benchmark takes about 15 minutes to run. Since it is using {@link Mode#Throughput}, + * higher numbers mean better performance. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 5) +@Measurement(iterations = 20) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +public class RemovingDecimalsManualTest { + @Param(value = {"345.56", "345345345.56", "345345345345345345.56"}) double doubleValue; + + NumberFormat nf; + DecimalFormat df; + + @Setup + public void readyFormatters() { + nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(0); + df = new DecimalFormat("#,###"); + } + + @Benchmark + public String whenCastToInt_thenValueIsTruncated() { + return String.valueOf((int) doubleValue); + } + + @Benchmark + public String whenUsingStringFormat_thenValueIsRounded() { + return String.format("%.0f", doubleValue); + } + + @Benchmark + public String whenUsingNumberFormat_thenValueIsRounded() { + nf.setRoundingMode(RoundingMode.HALF_UP); + return nf.format(doubleValue); + } + + @Benchmark + public String whenUsingNumberFormatWithFloor_thenValueIsTruncated() { + nf.setRoundingMode(RoundingMode.FLOOR); + return nf.format(doubleValue); + } + + @Benchmark + public String whenUsingDecimalFormat_thenValueIsRounded() { + df.setRoundingMode(RoundingMode.HALF_UP); + return df.format(doubleValue); + } + + @Benchmark + public String whenUsingDecimalFormatWithFloor_thenValueIsTruncated() { + df.setRoundingMode(RoundingMode.FLOOR); + return df.format(doubleValue); + } + + @Benchmark + public String whenUsingBigDecimalDoubleValue_thenValueIsTruncated() { + BigDecimal big = new BigDecimal(doubleValue); + big = big.setScale(0, RoundingMode.FLOOR); + return big.toString(); + } + + @Benchmark + public String whenUsingBigDecimalDoubleValueWithHalfUp_thenValueIsRounded() { + BigDecimal big = new BigDecimal(doubleValue); + big = big.setScale(0, RoundingMode.HALF_UP); + return big.toString(); + } + + @Test + public void runBenchmarks() throws Exception { + Options options = new OptionsBuilder() + .include(this.getClass().getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true).shouldDoGC(true) + .jvmArgs("-server").build(); + + new Runner(options).run(); + } +} diff --git a/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java new file mode 100644 index 0000000000..2f634b553b --- /dev/null +++ b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java @@ -0,0 +1,95 @@ +package com.baeldung.removingdecimals; + +import org.junit.Test; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.NumberFormat; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +/** + * Tests that demonstrate some different approaches for formatting a + * floating-point value into a {@link String} while removing the decimal part. + */ +public class RemovingDecimalsUnitTest { + private final double doubleValue = 345.56; + + @Test + public void whenCastToInt_thenValueIsTruncated() { + String truncated = String.valueOf((int) doubleValue); + assertEquals("345", truncated); + } + + @Test + public void givenALargeDouble_whenCastToInt_thenValueIsNotTruncated() { + double outOfIntRange = 6_000_000_000.56; + String truncationAttempt = String.valueOf((int) outOfIntRange); + assertNotEquals("6000000000", truncationAttempt); + } + + @Test + public void whenUsingStringFormat_thenValueIsRounded() { + String rounded = String.format("%.0f", doubleValue); + assertEquals("346", rounded); + } + + @Test + public void givenALargeDouble_whenUsingStringFormat_thenValueIsStillRounded() { + double outOfIntRange = 6_000_000_000.56; + String rounded = String.format("%.0f", outOfIntRange); + assertEquals("6000000001", rounded); + } + + @Test + public void whenUsingNumberFormat_thenValueIsRounded() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(0); + nf.setRoundingMode(RoundingMode.HALF_UP); + String rounded = nf.format(doubleValue); + assertEquals("346", rounded); + } + + @Test + public void whenUsingNumberFormatWithFloor_thenValueIsTruncated() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(0); + nf.setRoundingMode(RoundingMode.FLOOR); + String truncated = nf.format(doubleValue); + assertEquals("345", truncated); + } + + @Test + public void whenUsingDecimalFormat_thenValueIsRounded() { + DecimalFormat df = new DecimalFormat("#,###"); + df.setRoundingMode(RoundingMode.HALF_UP); + String rounded = df.format(doubleValue); + assertEquals("346", rounded); + } + + @Test + public void whenUsingDecimalFormatWithFloor_thenValueIsTruncated() { + DecimalFormat df = new DecimalFormat("#,###"); + df.setRoundingMode(RoundingMode.FLOOR); + String truncated = df.format(doubleValue); + assertEquals("345", truncated); + } + + @Test + public void whenUsingBigDecimalDoubleValue_thenValueIsTruncated() { + BigDecimal big = new BigDecimal(doubleValue); + big = big.setScale(0, RoundingMode.FLOOR); + String truncated = big.toString(); + assertEquals("345", truncated); + } + + @Test + public void whenUsingBigDecimalDoubleValueWithHalfUp_thenValueIsRounded() { + BigDecimal big = new BigDecimal(doubleValue); + big = big.setScale(0, RoundingMode.HALF_UP); + String truncated = big.toString(); + assertEquals("346", truncated); + } +} diff --git a/core-java/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java b/core-java/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java new file mode 100644 index 0000000000..2cdf6145d3 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java @@ -0,0 +1,110 @@ +/** + * + */ +package com.baeldung.string; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + * @author swpraman + * + */ +public class AppendCharAtPositionXUnitTest { + + private AppendCharAtPositionX appendCharAtPosition = new AppendCharAtPositionX(); + private String word = "Titanc"; + private char letter = 'i'; + + @Test + public void whenUsingCharacterArrayAndCharacterAddedAtBeginning_shouldAddCharacter() { + assertEquals("iTitanc", appendCharAtPosition.addCharUsingCharArray(word, letter, 0)); + } + + @Test + public void whenUsingSubstringAndCharacterAddedAtBeginning_shouldAddCharacter() { + assertEquals("iTitanc", appendCharAtPosition.addCharUsingSubstring(word, letter, 0)); + } + + @Test + public void whenUsingStringBuilderAndCharacterAddedAtBeginning_shouldAddCharacter() { + assertEquals("iTitanc", appendCharAtPosition.addCharUsingStringBuilder(word, letter, 0)); + } + + @Test + public void whenUsingCharacterArrayAndCharacterAddedAtMiddle_shouldAddCharacter() { + assertEquals("Titianc", appendCharAtPosition.addCharUsingCharArray(word, letter, 3)); + } + + @Test + public void whenUsingSubstringAndCharacterAddedAtMiddle_shouldAddCharacter() { + assertEquals("Titianc", appendCharAtPosition.addCharUsingSubstring(word, letter, 3)); + } + + @Test + public void whenUsingStringBuilderAndCharacterAddedAtMiddle_shouldAddCharacter() { + assertEquals("Titianc", appendCharAtPosition.addCharUsingStringBuilder(word, letter, 3)); + } + + @Test + public void whenUsingCharacterArrayAndCharacterAddedAtEnd_shouldAddCharacter() { + assertEquals("Titanci", appendCharAtPosition.addCharUsingCharArray(word, letter, word.length())); + } + + @Test + public void whenUsingSubstringAndCharacterAddedAtEnd_shouldAddCharacter() { + assertEquals("Titanci", appendCharAtPosition.addCharUsingSubstring(word, letter, word.length())); + } + + @Test + public void whenUsingStringBuilderAndCharacterAddedAtEnd_shouldAddCharacter() { + assertEquals("Titanci", appendCharAtPosition.addCharUsingStringBuilder(word, letter, word.length())); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingCharacterArrayAndCharacterAddedAtNegativePosition_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(word, letter, -1); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingSubstringAndCharacterAddedAtNegativePosition_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(word, letter, -1); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingStringBuilderAndCharacterAddedAtNegativePosition_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(word, letter, -1); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingCharacterArrayAndCharacterAddedAtInvalidPosition_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(word, letter, word.length() + 2); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingSubstringAndCharacterAddedAtInvalidPosition_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(word, letter, word.length() + 2); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingStringBuilderAndCharacterAddedAtInvalidPosition_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(word, letter, word.length() + 2); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingCharacterArrayAndCharacterAddedAtPositionXAndStringIsNull_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(null, letter, 3); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingSubstringAndCharacterAddedAtPositionXAndStringIsNull_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(null, letter, 3); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingStringBuilderAndCharacterAddedAtPositionXAndStringIsNull_shouldThrowException() { + appendCharAtPosition.addCharUsingStringBuilder(null, letter, 3); + } + +} diff --git a/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java b/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java new file mode 100644 index 0000000000..e8ac645531 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.switchstatement; + +import org.junit.Test; + +import org.junit.Assert; + +public class SwitchStatementUnitTest { + private SwitchStatement s = new SwitchStatement(); + + + @Test + public void whenDog_thenDomesticAnimal() { + + String animal = "DOG"; + Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal)); + } + + @Test + public void whenNoBreaks_thenGoThroughBlocks() { + String animal = "DOG"; + Assert.assertEquals("unknown animal", s.forgetBreakInSwitch(animal)); + } + + @Test(expected=NullPointerException.class) + public void whenSwitchAgumentIsNull_thenNullPointerException() { + String animal = null; + Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal)); + } + + + @Test + public void whenCompareStrings_thenByEqual() { + String animal = new String("DOG"); + Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal)); + } + + +} diff --git a/core-java/src/test/java/com/baeldung/synthetic/SyntheticUnitTest.java b/core-java/src/test/java/com/baeldung/synthetic/SyntheticUnitTest.java new file mode 100644 index 0000000000..20f7647f48 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/synthetic/SyntheticUnitTest.java @@ -0,0 +1,99 @@ +package com.baeldung.synthetic; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Unit test for {@link SyntheticFieldDemo}, {@link SyntheticMethodDemo}, + * {@link SyntheticConstructorDemo} and {@link BridgeMethodDemo} classes. + * + * @author Donato Rimenti + * + */ +public class SyntheticUnitTest { + + /** + * Tests that the {@link SyntheticMethodDemo.NestedClass} contains two synthetic + * methods. + */ + @Test + public void givenSyntheticMethod_whenIsSinthetic_thenTrue() { + // Checks that the nested class contains exactly two synthetic methods. + Method[] methods = SyntheticMethodDemo.NestedClass.class.getDeclaredMethods(); + Assert.assertEquals("This class should contain only two methods", 2, methods.length); + + for (Method m : methods) { + System.out.println("Method: " + m.getName() + ", isSynthetic: " + m.isSynthetic()); + Assert.assertTrue("All the methods of this class should be synthetic", m.isSynthetic()); + } + } + + /** + * Tests that {@link SyntheticConstructorDemo.NestedClass} contains a synthetic + * constructor. + */ + @Test + public void givenSyntheticConstructor_whenIsSinthetic_thenTrue() { + // Checks that the nested class contains exactly a synthetic + // constructor. + int syntheticConstructors = 0; + Constructor[] constructors = SyntheticConstructorDemo.NestedClass.class.getDeclaredConstructors(); + Assert.assertEquals("This class should contain only two constructors", 2, constructors.length); + + for (Constructor c : constructors) { + System.out.println("Constructor: " + c.getName() + ", isSynthetic: " + c.isSynthetic()); + + // Counts the synthetic constructors. + if (c.isSynthetic()) { + syntheticConstructors++; + } + } + + // Checks that there's exactly one synthetic constructor. + Assert.assertEquals(1, syntheticConstructors); + } + + /** + * Tests that {@link SyntheticFieldDemo.NestedClass} contains a synthetic field. + */ + @Test + public void givenSyntheticField_whenIsSinthetic_thenTrue() { + // This class should contain exactly one synthetic field. + Field[] fields = SyntheticFieldDemo.NestedClass.class.getDeclaredFields(); + Assert.assertEquals("This class should contain only one field", 1, fields.length); + + for (Field f : fields) { + System.out.println("Field: " + f.getName() + ", isSynthetic: " + f.isSynthetic()); + Assert.assertTrue("All the fields of this class should be synthetic", f.isSynthetic()); + } + } + + /** + * Tests that {@link BridgeMethodDemo} contains a synthetic bridge method. + */ + @Test + public void givenBridgeMethod_whenIsBridge_thenTrue() { + // This class should contain exactly one synthetic bridge method. + int syntheticMethods = 0; + Method[] methods = BridgeMethodDemo.class.getDeclaredMethods(); + for (Method m : methods) { + System.out.println( + "Method: " + m.getName() + ", isSynthetic: " + m.isSynthetic() + ", isBridge: " + m.isBridge()); + + // Counts the synthetic methods and checks that they are also bridge + // methods. + if (m.isSynthetic()) { + syntheticMethods++; + Assert.assertTrue("The synthetic method in this class should also be a bridge method", m.isBridge()); + } + } + + // Checks that there's exactly one synthetic bridge method. + Assert.assertEquals("There should be exactly 1 synthetic bridge method in this class", 1, syntheticMethods); + } + +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java b/core-java/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java new file mode 100644 index 0000000000..6b292ad8ab --- /dev/null +++ b/core-java/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.ternaryoperator; + +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class TernaryOperatorUnitTest { + + @Test + public void givenACondition_whenUsingTernaryOperator_thenItEvaluatesConditionAndReturnsAValue() { + int number = 10; + String msg = number > 10 ? "Number is greater than 10" : "Number is less than or equal to 10"; + + assertThat(msg).isEqualTo("Number is less than or equal to 10"); + } + + @Test + public void givenATrueCondition_whenUsingTernaryOperator_thenOnlyExpression1IsEvaluated() { + int exp1 = 0, exp2 = 0; + int result = 12 > 10 ? ++exp1 : ++exp2; + + assertThat(exp1).isEqualTo(1); + assertThat(exp2).isEqualTo(0); + assertThat(result).isEqualTo(1); + } + + @Test + public void givenAFalseCondition_whenUsingTernaryOperator_thenOnlyExpression2IsEvaluated() { + int exp1 = 0, exp2 = 0; + int result = 8 > 10 ? ++exp1 : ++exp2; + + assertThat(exp1).isEqualTo(0); + assertThat(exp2).isEqualTo(1); + assertThat(result).isEqualTo(1); + } + + @Test + public void givenANestedCondition_whenUsingTernaryOperator_thenCorrectValueIsReturned() { + int number = 6; + String msg = number > 10 ? "Number is greater than 10" : number > 5 ? "Number is greater than 5" : "Number is less than or equal to 5"; + + assertThat(msg).isEqualTo("Number is greater than 5"); + } +} diff --git a/core-java/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java b/core-java/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java new file mode 100644 index 0000000000..85cff51eb3 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java @@ -0,0 +1,95 @@ +package com.baeldung.thread.join; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.logging.Logger; + +import org.junit.Ignore; +import org.junit.Test; + +/** + * Demonstrates Thread.join behavior. + * + */ +public class ThreadJoinUnitTest { + + final static Logger LOGGER = Logger.getLogger(ThreadJoinUnitTest.class.getName()); + + class SampleThread extends Thread { + public int processingCount = 0; + + SampleThread(int processingCount) { + this.processingCount = processingCount; + LOGGER.info("Thread " + this.getName() + " created"); + } + + @Override + public void run() { + LOGGER.info("Thread " + this.getName() + " started"); + while (processingCount > 0) { + try { + Thread.sleep(1000); // Simulate some work being done by thread + } catch (InterruptedException e) { + LOGGER.info("Thread " + this.getName() + " interrupted."); + } + processingCount--; + LOGGER.info("Inside Thread " + this.getName() + ", processingCount = " + processingCount); + } + LOGGER.info("Thread " + this.getName() + " exiting"); + } + } + + @Test + public void givenNewThread_whenJoinCalled_returnsImmediately() throws InterruptedException { + Thread t1 = new SampleThread(0); + LOGGER.info("Invoking join."); + t1.join(); + LOGGER.info("Returned from join"); + LOGGER.info("Thread state is" + t1.getState()); + assertFalse(t1.isAlive()); + } + + @Test + public void givenStartedThread_whenJoinCalled_waitsTillCompletion() + throws InterruptedException { + Thread t2 = new SampleThread(1); + t2.start(); + LOGGER.info("Invoking join."); + t2.join(); + LOGGER.info("Returned from join"); + assertFalse(t2.isAlive()); + } + + @Test + public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout() + throws InterruptedException { + Thread t3 = new SampleThread(10); + t3.start(); + t3.join(1000); + assertTrue(t3.isAlive()); + } + + @Test + @Ignore + public void givenThreadTerminated_checkForEffect_notGuaranteed() + throws InterruptedException { + SampleThread t4 = new SampleThread(10); + t4.start(); + //not guaranteed to stop even if t4 finishes. + do { + + } while (t4.processingCount > 0); + } + + @Test + public void givenJoinWithTerminatedThread_checkForEffect_guaranteed() + throws InterruptedException { + SampleThread t4 = new SampleThread(10); + t4.start(); + do { + t4.join(100); + } while (t4.processingCount > 0); + } + +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/throwsexception/SimpleServiceUnitTest.java b/core-java/src/test/java/com/baeldung/throwsexception/SimpleServiceUnitTest.java new file mode 100644 index 0000000000..b9a658a960 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/throwsexception/SimpleServiceUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.throwsexception; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class SimpleServiceUnitTest { + + SimpleService simpleService = new SimpleService(); + + @Test + void whenSQLExceptionIsThrown_thenShouldBeRethrownWithWrappedException() { + assertThrows(DataAccessException.class, + () -> simpleService.wrappingException()); + } + + @Test + void whenCalled_thenNullPointerExceptionIsThrown() { + assertThrows(NullPointerException.class, + () -> simpleService.runtimeNullPointerException()); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/unsafe/UnsafeUnitTest.java b/core-java/src/test/java/com/baeldung/unsafe/UnsafeUnitTest.java index 6aa59e68d0..22fe0f5e57 100644 --- a/core-java/src/test/java/com/baeldung/unsafe/UnsafeUnitTest.java +++ b/core-java/src/test/java/com/baeldung/unsafe/UnsafeUnitTest.java @@ -1,6 +1,7 @@ package com.baeldung.unsafe; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import sun.misc.Unsafe; @@ -56,6 +57,7 @@ public class UnsafeUnitTest { } @Test + @Ignore // Uncomment for local public void givenArrayBiggerThatMaxInt_whenAllocateItOffHeapMemory_thenSuccess() throws NoSuchFieldException, IllegalAccessException { //given long SUPER_SIZE = (long) Integer.MAX_VALUE * 2; diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java new file mode 100644 index 0000000000..a08d3737cd --- /dev/null +++ b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.zoneddatetime; + +import static org.junit.Assert.assertTrue; + +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +import org.junit.Test; + +public class OffsetDateTimeExampleUnitTest { + + OffsetDateTimeExample offsetDateTimeExample = new OffsetDateTimeExample(); + + @Test + public void givenZoneOffset_whenGetCurrentTime_thenResultHasZone() { + String offset = "+02:00"; + OffsetDateTime time = offsetDateTimeExample.getCurrentTimeByZoneOffset(offset); + + assertTrue(time.getOffset() + .equals(ZoneOffset.of(offset))); + } +} diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java new file mode 100644 index 0000000000..488f934179 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.zoneddatetime; + +import static org.junit.Assert.assertTrue; + +import java.time.OffsetTime; +import java.time.ZoneOffset; + +import org.junit.Test; + +public class OffsetTimeExampleUnitTest { + + OffsetTimeExample offsetTimeExample = new OffsetTimeExample(); + + @Test + public void givenZoneOffset_whenGetCurrentTime_thenResultHasZone() { + String offset = "+02:00"; + OffsetTime time = offsetTimeExample.getCurrentTimeByZoneOffset(offset); + + assertTrue(time.getOffset() + .equals(ZoneOffset.of(offset))); + } +} diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java new file mode 100644 index 0000000000..e78ff3e3fd --- /dev/null +++ b/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.zoneddatetime; + +import static org.junit.Assert.assertTrue; + +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.junit.Test; + +public class ZoneDateTimeExampleUnitTest { + + ZoneDateTimeExample zoneDateTimeExample = new ZoneDateTimeExample(); + + @Test + public void givenZone_whenGetCurrentTime_thenResultHasZone() { + String zone = "Europe/Berlin"; + ZonedDateTime time = zoneDateTimeExample.getCurrentTimeByZoneId(zone); + + assertTrue(time.getZone() + .equals(ZoneId.of(zone))); + } + + @Test + public void givenZones_whenConvertDateByZone_thenGetConstantDiff() { + String sourceZone = "Europe/Berlin"; + String destZone = "Asia/Tokyo"; + ZonedDateTime sourceDate = zoneDateTimeExample.getCurrentTimeByZoneId(sourceZone); + ZonedDateTime destDate = zoneDateTimeExample.convertZonedDateTime(sourceDate, destZone); + + assertTrue(sourceDate.toInstant() + .compareTo(destDate.toInstant()) == 0); + } +} diff --git a/core-java/src/test/java/org/baeldung/java/enums/PizzaUnitTest.java b/core-java/src/test/java/org/baeldung/java/enums/PizzaUnitTest.java deleted file mode 100644 index bb3abff28d..0000000000 --- a/core-java/src/test/java/org/baeldung/java/enums/PizzaUnitTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.baeldung.java.enums; - -import static junit.framework.TestCase.assertTrue; - -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; - -import org.junit.Test; - -import com.baeldung.enums.Pizza; - -public class PizzaUnitTest { - - @Test - public void givenPizaOrder_whenReady_thenDeliverable() { - Pizza testPz = new Pizza(); - testPz.setStatus(Pizza.PizzaStatusEnum.READY); - assertTrue(testPz.isDeliverable()); - } - - @Test - public void givenPizaOrders_whenRetrievingUnDeliveredPzs_thenCorrectlyRetrieved() { - List pzList = new ArrayList<>(); - Pizza pz1 = new Pizza(); - pz1.setStatus(Pizza.PizzaStatusEnum.DELIVERED); - - Pizza pz2 = new Pizza(); - pz2.setStatus(Pizza.PizzaStatusEnum.ORDERED); - - Pizza pz3 = new Pizza(); - pz3.setStatus(Pizza.PizzaStatusEnum.ORDERED); - - Pizza pz4 = new Pizza(); - pz4.setStatus(Pizza.PizzaStatusEnum.READY); - - pzList.add(pz1); - pzList.add(pz2); - pzList.add(pz3); - pzList.add(pz4); - - List undeliveredPzs = Pizza.getAllUndeliveredPizzas(pzList); - assertTrue(undeliveredPzs.size() == 3); - } - - @Test - public void givenPizaOrders_whenGroupByStatusCalled_thenCorrectlyGrouped() { - - List pzList = new ArrayList<>(); - Pizza pz1 = new Pizza(); - pz1.setStatus(Pizza.PizzaStatusEnum.DELIVERED); - - Pizza pz2 = new Pizza(); - pz2.setStatus(Pizza.PizzaStatusEnum.ORDERED); - - Pizza pz3 = new Pizza(); - pz3.setStatus(Pizza.PizzaStatusEnum.ORDERED); - - Pizza pz4 = new Pizza(); - pz4.setStatus(Pizza.PizzaStatusEnum.READY); - - pzList.add(pz1); - pzList.add(pz2); - pzList.add(pz3); - pzList.add(pz4); - - EnumMap> map = Pizza.groupPizzaByStatus(pzList); - assertTrue(map.get(Pizza.PizzaStatusEnum.DELIVERED).size() == 1); - assertTrue(map.get(Pizza.PizzaStatusEnum.ORDERED).size() == 2); - assertTrue(map.get(Pizza.PizzaStatusEnum.READY).size() == 1); - } - - @Test - public void givenPizaOrder_whenDelivered_thenPizzaGetsDeliveredAndStatusChanges() { - Pizza pz = new Pizza(); - pz.setStatus(Pizza.PizzaStatusEnum.READY); - pz.deliver(); - assertTrue(pz.getStatus() == Pizza.PizzaStatusEnum.DELIVERED); - } - -} diff --git a/core-java/src/test/resources/META-INF/mime.types b/core-java/src/test/resources/META-INF/mime.types new file mode 100644 index 0000000000..5175242626 --- /dev/null +++ b/core-java/src/test/resources/META-INF/mime.types @@ -0,0 +1,1588 @@ +# This file maps Internet media types to unique file extension(s). +# Although created for httpd, this file is used by many software systems +# and has been placed in the public domain for unlimited redisribution. +# +# The table below contains both registered and (common) unregistered types. +# A type that has no unique extension can be ignored -- they are listed +# here to guide configurations toward known types and to make it easier to +# identify "new" types. File extensions are also commonly used to indicate +# content languages and encodings, so choose them carefully. +# +# Internet media types should be registered as described in RFC 4288. +# The registry is at . +# +# MIME type (lowercased) Extensions +# ============================================ ========== +# application/1d-interleaved-parityfec +# application/3gpp-ims+xml +# application/activemessage +application/andrew-inset ez +# application/applefile +application/applixware aw +application/atom+xml atom +application/atomcat+xml atomcat +# application/atomicmail +application/atomsvc+xml atomsvc +# application/auth-policy+xml +# application/batch-smtp +# application/beep+xml +# application/calendar+xml +# application/cals-1840 +# application/ccmp+xml +application/ccxml+xml ccxml +application/cdmi-capability cdmia +application/cdmi-container cdmic +application/cdmi-domain cdmid +application/cdmi-object cdmio +application/cdmi-queue cdmiq +# application/cea-2018+xml +# application/cellml+xml +# application/cfw +# application/cnrp+xml +# application/commonground +# application/conference-info+xml +# application/cpl+xml +# application/csta+xml +# application/cstadata+xml +application/cu-seeme cu +# application/cybercash +application/davmount+xml davmount +# application/dca-rft +# application/dec-dx +# application/dialog-info+xml +# application/dicom +# application/dns +application/docbook+xml dbk +# application/dskpp+xml +application/dssc+der dssc +application/dssc+xml xdssc +# application/dvcs +application/ecmascript ecma +# application/edi-consent +# application/edi-x12 +# application/edifact +application/emma+xml emma +# application/epp+xml +application/epub+zip epub +# application/eshop +# application/example +application/exi exi +# application/fastinfoset +# application/fastsoap +# application/fits +application/font-tdpfr pfr +# application/framework-attributes+xml +application/gml+xml gml +application/gpx+xml gpx +application/gxf gxf +# application/h224 +# application/held+xml +# application/http +application/hyperstudio stk +# application/ibe-key-request+xml +# application/ibe-pkg-reply+xml +# application/ibe-pp-data +# application/iges +# application/im-iscomposing+xml +# application/index +# application/index.cmd +# application/index.obj +# application/index.response +# application/index.vnd +application/inkml+xml ink inkml +# application/iotp +application/ipfix ipfix +# application/ipp +# application/isup +application/java-archive jar +application/java-serialized-object ser +application/java-vm class +application/javascript js +application/json json +application/jsonml+json jsonml +# application/kpml-request+xml +# application/kpml-response+xml +application/lost+xml lostxml +application/mac-binhex40 hqx +application/mac-compactpro cpt +# application/macwriteii +application/mads+xml mads +application/marc mrc +application/marcxml+xml mrcx +application/mathematica ma nb mb +# application/mathml-content+xml +# application/mathml-presentation+xml +application/mathml+xml mathml +# application/mbms-associated-procedure-description+xml +# application/mbms-deregister+xml +# application/mbms-envelope+xml +# application/mbms-msk+xml +# application/mbms-msk-response+xml +# application/mbms-protection-description+xml +# application/mbms-reception-report+xml +# application/mbms-register+xml +# application/mbms-register-response+xml +# application/mbms-user-service-description+xml +application/mbox mbox +# application/media_control+xml +application/mediaservercontrol+xml mscml +application/metalink+xml metalink +application/metalink4+xml meta4 +application/mets+xml mets +# application/mikey +application/mods+xml mods +# application/moss-keys +# application/moss-signature +# application/mosskey-data +# application/mosskey-request +application/mp21 m21 mp21 +application/mp4 mp4s +# application/mpeg4-generic +# application/mpeg4-iod +# application/mpeg4-iod-xmt +# application/msc-ivr+xml +# application/msc-mixer+xml +application/msword doc dot +application/mxf mxf +# application/nasdata +# application/news-checkgroups +# application/news-groupinfo +# application/news-transmission +# application/nss +# application/ocsp-request +# application/ocsp-response +application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy +application/oda oda +application/oebps-package+xml opf +application/ogg ogx +application/omdoc+xml omdoc +application/onenote onetoc onetoc2 onetmp onepkg +application/oxps oxps +# application/parityfec +application/patch-ops-error+xml xer +application/pdf pdf +application/pgp-encrypted pgp +# application/pgp-keys +application/pgp-signature asc sig +application/pics-rules prf +# application/pidf+xml +# application/pidf-diff+xml +application/pkcs10 p10 +application/pkcs7-mime p7m p7c +application/pkcs7-signature p7s +application/pkcs8 p8 +application/pkix-attr-cert ac +application/pkix-cert cer +application/pkix-crl crl +application/pkix-pkipath pkipath +application/pkixcmp pki +application/pls+xml pls +# application/poc-settings+xml +application/postscript ai eps ps +# application/prs.alvestrand.titrax-sheet +application/prs.cww cww +# application/prs.nprend +# application/prs.plucker +# application/prs.rdf-xml-crypt +# application/prs.xsf+xml +application/pskc+xml pskcxml +# application/qsig +application/rdf+xml rdf +application/reginfo+xml rif +application/relax-ng-compact-syntax rnc +# application/remote-printing +application/resource-lists+xml rl +application/resource-lists-diff+xml rld +# application/riscos +# application/rlmi+xml +application/rls-services+xml rs +application/rpki-ghostbusters gbr +application/rpki-manifest mft +application/rpki-roa roa +# application/rpki-updown +application/rsd+xml rsd +application/rss+xml rss +application/rtf rtf +# application/rtx +# application/samlassertion+xml +# application/samlmetadata+xml +application/sbml+xml sbml +application/scvp-cv-request scq +application/scvp-cv-response scs +application/scvp-vp-request spq +application/scvp-vp-response spp +application/sdp sdp +# application/set-payment +application/set-payment-initiation setpay +# application/set-registration +application/set-registration-initiation setreg +# application/sgml +# application/sgml-open-catalog +application/shf+xml shf +# application/sieve +# application/simple-filter+xml +# application/simple-message-summary +# application/simplesymbolcontainer +# application/slate +# application/smil +application/smil+xml smi smil +# application/soap+fastinfoset +# application/soap+xml +application/sparql-query rq +application/sparql-results+xml srx +# application/spirits-event+xml +application/srgs gram +application/srgs+xml grxml +application/sru+xml sru +application/ssdl+xml ssdl +application/ssml+xml ssml +# application/tamp-apex-update +# application/tamp-apex-update-confirm +# application/tamp-community-update +# application/tamp-community-update-confirm +# application/tamp-error +# application/tamp-sequence-adjust +# application/tamp-sequence-adjust-confirm +# application/tamp-status-query +# application/tamp-status-response +# application/tamp-update +# application/tamp-update-confirm +application/tei+xml tei teicorpus +application/thraud+xml tfi +# application/timestamp-query +# application/timestamp-reply +application/timestamped-data tsd +# application/tve-trigger +# application/ulpfec +# application/vcard+xml +# application/vemmi +# application/vividence.scriptfile +# application/vnd.3gpp.bsf+xml +application/vnd.3gpp.pic-bw-large plb +application/vnd.3gpp.pic-bw-small psb +application/vnd.3gpp.pic-bw-var pvb +# application/vnd.3gpp.sms +# application/vnd.3gpp2.bcmcsinfo+xml +# application/vnd.3gpp2.sms +application/vnd.3gpp2.tcap tcap +application/vnd.3m.post-it-notes pwn +application/vnd.accpac.simply.aso aso +application/vnd.accpac.simply.imp imp +application/vnd.acucobol acu +application/vnd.acucorp atc acutc +application/vnd.adobe.air-application-installer-package+zip air +application/vnd.adobe.formscentral.fcdt fcdt +application/vnd.adobe.fxp fxp fxpl +# application/vnd.adobe.partial-upload +application/vnd.adobe.xdp+xml xdp +application/vnd.adobe.xfdf xfdf +# application/vnd.aether.imp +# application/vnd.ah-barcode +application/vnd.ahead.space ahead +application/vnd.airzip.filesecure.azf azf +application/vnd.airzip.filesecure.azs azs +application/vnd.amazon.ebook azw +application/vnd.americandynamics.acc acc +application/vnd.amiga.ami ami +# application/vnd.amundsen.maze+xml +application/vnd.android.package-archive apk +application/vnd.anser-web-certificate-issue-initiation cii +application/vnd.anser-web-funds-transfer-initiation fti +application/vnd.antix.game-component atx +application/vnd.apple.installer+xml mpkg +application/vnd.apple.mpegurl m3u8 +# application/vnd.arastra.swi +application/vnd.aristanetworks.swi swi +application/vnd.astraea-software.iota iota +application/vnd.audiograph aep +# application/vnd.autopackage +# application/vnd.avistar+xml +application/vnd.blueice.multipass mpm +# application/vnd.bluetooth.ep.oob +application/vnd.bmi bmi +application/vnd.businessobjects rep +# application/vnd.cab-jscript +# application/vnd.canon-cpdl +# application/vnd.canon-lips +# application/vnd.cendio.thinlinc.clientconf +application/vnd.chemdraw+xml cdxml +application/vnd.chipnuts.karaoke-mmd mmd +application/vnd.cinderella cdy +# application/vnd.cirpack.isdn-ext +application/vnd.claymore cla +application/vnd.cloanto.rp9 rp9 +application/vnd.clonk.c4group c4g c4d c4f c4p c4u +application/vnd.cluetrust.cartomobile-config c11amc +application/vnd.cluetrust.cartomobile-config-pkg c11amz +# application/vnd.collection+json +# application/vnd.commerce-battelle +application/vnd.commonspace csp +application/vnd.contact.cmsg cdbcmsg +application/vnd.cosmocaller cmc +application/vnd.crick.clicker clkx +application/vnd.crick.clicker.keyboard clkk +application/vnd.crick.clicker.palette clkp +application/vnd.crick.clicker.template clkt +application/vnd.crick.clicker.wordbank clkw +application/vnd.criticaltools.wbs+xml wbs +application/vnd.ctc-posml pml +# application/vnd.ctct.ws+xml +# application/vnd.cups-pdf +# application/vnd.cups-postscript +application/vnd.cups-ppd ppd +# application/vnd.cups-raster +# application/vnd.cups-raw +# application/vnd.curl +application/vnd.curl.car car +application/vnd.curl.pcurl pcurl +# application/vnd.cybank +application/vnd.dart dart +application/vnd.data-vision.rdz rdz +application/vnd.dece.data uvf uvvf uvd uvvd +application/vnd.dece.ttml+xml uvt uvvt +application/vnd.dece.unspecified uvx uvvx +application/vnd.dece.zip uvz uvvz +application/vnd.denovo.fcselayout-link fe_launch +# application/vnd.dir-bi.plate-dl-nosuffix +application/vnd.dna dna +application/vnd.dolby.mlp mlp +# application/vnd.dolby.mobile.1 +# application/vnd.dolby.mobile.2 +application/vnd.dpgraph dpg +application/vnd.dreamfactory dfac +application/vnd.ds-keypoint kpxx +application/vnd.dvb.ait ait +# application/vnd.dvb.dvbj +# application/vnd.dvb.esgcontainer +# application/vnd.dvb.ipdcdftnotifaccess +# application/vnd.dvb.ipdcesgaccess +# application/vnd.dvb.ipdcesgaccess2 +# application/vnd.dvb.ipdcesgpdd +# application/vnd.dvb.ipdcroaming +# application/vnd.dvb.iptv.alfec-base +# application/vnd.dvb.iptv.alfec-enhancement +# application/vnd.dvb.notif-aggregate-root+xml +# application/vnd.dvb.notif-container+xml +# application/vnd.dvb.notif-generic+xml +# application/vnd.dvb.notif-ia-msglist+xml +# application/vnd.dvb.notif-ia-registration-request+xml +# application/vnd.dvb.notif-ia-registration-response+xml +# application/vnd.dvb.notif-init+xml +# application/vnd.dvb.pfr +application/vnd.dvb.service svc +# application/vnd.dxr +application/vnd.dynageo geo +# application/vnd.easykaraoke.cdgdownload +# application/vnd.ecdis-update +application/vnd.ecowin.chart mag +# application/vnd.ecowin.filerequest +# application/vnd.ecowin.fileupdate +# application/vnd.ecowin.series +# application/vnd.ecowin.seriesrequest +# application/vnd.ecowin.seriesupdate +# application/vnd.emclient.accessrequest+xml +application/vnd.enliven nml +# application/vnd.eprints.data+xml +application/vnd.epson.esf esf +application/vnd.epson.msf msf +application/vnd.epson.quickanime qam +application/vnd.epson.salt slt +application/vnd.epson.ssf ssf +# application/vnd.ericsson.quickcall +application/vnd.eszigno3+xml es3 et3 +# application/vnd.etsi.aoc+xml +# application/vnd.etsi.cug+xml +# application/vnd.etsi.iptvcommand+xml +# application/vnd.etsi.iptvdiscovery+xml +# application/vnd.etsi.iptvprofile+xml +# application/vnd.etsi.iptvsad-bc+xml +# application/vnd.etsi.iptvsad-cod+xml +# application/vnd.etsi.iptvsad-npvr+xml +# application/vnd.etsi.iptvservice+xml +# application/vnd.etsi.iptvsync+xml +# application/vnd.etsi.iptvueprofile+xml +# application/vnd.etsi.mcid+xml +# application/vnd.etsi.overload-control-policy-dataset+xml +# application/vnd.etsi.sci+xml +# application/vnd.etsi.simservs+xml +# application/vnd.etsi.tsl+xml +# application/vnd.etsi.tsl.der +# application/vnd.eudora.data +application/vnd.ezpix-album ez2 +application/vnd.ezpix-package ez3 +# application/vnd.f-secure.mobile +application/vnd.fdf fdf +application/vnd.fdsn.mseed mseed +application/vnd.fdsn.seed seed dataless +# application/vnd.ffsns +# application/vnd.fints +application/vnd.flographit gph +application/vnd.fluxtime.clip ftc +# application/vnd.font-fontforge-sfd +application/vnd.framemaker fm frame maker book +application/vnd.frogans.fnc fnc +application/vnd.frogans.ltf ltf +application/vnd.fsc.weblaunch fsc +application/vnd.fujitsu.oasys oas +application/vnd.fujitsu.oasys2 oa2 +application/vnd.fujitsu.oasys3 oa3 +application/vnd.fujitsu.oasysgp fg5 +application/vnd.fujitsu.oasysprs bh2 +# application/vnd.fujixerox.art-ex +# application/vnd.fujixerox.art4 +# application/vnd.fujixerox.hbpl +application/vnd.fujixerox.ddd ddd +application/vnd.fujixerox.docuworks xdw +application/vnd.fujixerox.docuworks.binder xbd +# application/vnd.fut-misnet +application/vnd.fuzzysheet fzs +application/vnd.genomatix.tuxedo txd +# application/vnd.geocube+xml +application/vnd.geogebra.file ggb +application/vnd.geogebra.tool ggt +application/vnd.geometry-explorer gex gre +application/vnd.geonext gxt +application/vnd.geoplan g2w +application/vnd.geospace g3w +# application/vnd.globalplatform.card-content-mgt +# application/vnd.globalplatform.card-content-mgt-response +application/vnd.gmx gmx +application/vnd.google-earth.kml+xml kml +application/vnd.google-earth.kmz kmz +application/vnd.grafeq gqf gqs +# application/vnd.gridmp +application/vnd.groove-account gac +application/vnd.groove-help ghf +application/vnd.groove-identity-message gim +application/vnd.groove-injector grv +application/vnd.groove-tool-message gtm +application/vnd.groove-tool-template tpl +application/vnd.groove-vcard vcg +# application/vnd.hal+json +application/vnd.hal+xml hal +application/vnd.handheld-entertainment+xml zmm +application/vnd.hbci hbci +# application/vnd.hcl-bireports +application/vnd.hhe.lesson-player les +application/vnd.hp-hpgl hpgl +application/vnd.hp-hpid hpid +application/vnd.hp-hps hps +application/vnd.hp-jlyt jlt +application/vnd.hp-pcl pcl +application/vnd.hp-pclxl pclxl +# application/vnd.httphone +application/vnd.hydrostatix.sof-data sfd-hdstx +# application/vnd.hzn-3d-crossword +# application/vnd.ibm.afplinedata +# application/vnd.ibm.electronic-media +application/vnd.ibm.minipay mpy +application/vnd.ibm.modcap afp listafp list3820 +application/vnd.ibm.rights-management irm +application/vnd.ibm.secure-container sc +application/vnd.iccprofile icc icm +application/vnd.igloader igl +application/vnd.immervision-ivp ivp +application/vnd.immervision-ivu ivu +# application/vnd.informedcontrol.rms+xml +# application/vnd.informix-visionary +# application/vnd.infotech.project +# application/vnd.infotech.project+xml +# application/vnd.innopath.wamp.notification +application/vnd.insors.igm igm +application/vnd.intercon.formnet xpw xpx +application/vnd.intergeo i2g +# application/vnd.intertrust.digibox +# application/vnd.intertrust.nncp +application/vnd.intu.qbo qbo +application/vnd.intu.qfx qfx +# application/vnd.iptc.g2.conceptitem+xml +# application/vnd.iptc.g2.knowledgeitem+xml +# application/vnd.iptc.g2.newsitem+xml +# application/vnd.iptc.g2.newsmessage+xml +# application/vnd.iptc.g2.packageitem+xml +# application/vnd.iptc.g2.planningitem+xml +application/vnd.ipunplugged.rcprofile rcprofile +application/vnd.irepository.package+xml irp +application/vnd.is-xpr xpr +application/vnd.isac.fcs fcs +application/vnd.jam jam +# application/vnd.japannet-directory-service +# application/vnd.japannet-jpnstore-wakeup +# application/vnd.japannet-payment-wakeup +# application/vnd.japannet-registration +# application/vnd.japannet-registration-wakeup +# application/vnd.japannet-setstore-wakeup +# application/vnd.japannet-verification +# application/vnd.japannet-verification-wakeup +application/vnd.jcp.javame.midlet-rms rms +application/vnd.jisp jisp +application/vnd.joost.joda-archive joda +application/vnd.kahootz ktz ktr +application/vnd.kde.karbon karbon +application/vnd.kde.kchart chrt +application/vnd.kde.kformula kfo +application/vnd.kde.kivio flw +application/vnd.kde.kontour kon +application/vnd.kde.kpresenter kpr kpt +application/vnd.kde.kspread ksp +application/vnd.kde.kword kwd kwt +application/vnd.kenameaapp htke +application/vnd.kidspiration kia +application/vnd.kinar kne knp +application/vnd.koan skp skd skt skm +application/vnd.kodak-descriptor sse +application/vnd.las.las+xml lasxml +# application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop lbd +application/vnd.llamagraphics.life-balance.exchange+xml lbe +application/vnd.lotus-1-2-3 123 +application/vnd.lotus-approach apr +application/vnd.lotus-freelance pre +application/vnd.lotus-notes nsf +application/vnd.lotus-organizer org +application/vnd.lotus-screencam scm +application/vnd.lotus-wordpro lwp +application/vnd.macports.portpkg portpkg +# application/vnd.marlin.drm.actiontoken+xml +# application/vnd.marlin.drm.conftoken+xml +# application/vnd.marlin.drm.license+xml +# application/vnd.marlin.drm.mdcf +application/vnd.mcd mcd +application/vnd.medcalcdata mc1 +application/vnd.mediastation.cdkey cdkey +# application/vnd.meridian-slingshot +application/vnd.mfer mwf +application/vnd.mfmp mfm +application/vnd.micrografx.flo flo +application/vnd.micrografx.igx igx +application/vnd.mif mif +# application/vnd.minisoft-hp3000-save +# application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.mobius.daf daf +application/vnd.mobius.dis dis +application/vnd.mobius.mbk mbk +application/vnd.mobius.mqy mqy +application/vnd.mobius.msl msl +application/vnd.mobius.plc plc +application/vnd.mobius.txf txf +application/vnd.mophun.application mpn +application/vnd.mophun.certificate mpc +# application/vnd.motorola.flexsuite +# application/vnd.motorola.flexsuite.adsi +# application/vnd.motorola.flexsuite.fis +# application/vnd.motorola.flexsuite.gotap +# application/vnd.motorola.flexsuite.kmr +# application/vnd.motorola.flexsuite.ttc +# application/vnd.motorola.flexsuite.wem +# application/vnd.motorola.iprm +application/vnd.mozilla.xul+xml xul +application/vnd.ms-artgalry cil +# application/vnd.ms-asf +application/vnd.ms-cab-compressed cab +# application/vnd.ms-color.iccprofile +application/vnd.ms-excel xls xlm xla xlc xlt xlw +application/vnd.ms-excel.addin.macroenabled.12 xlam +application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb +application/vnd.ms-excel.sheet.macroenabled.12 xlsm +application/vnd.ms-excel.template.macroenabled.12 xltm +application/vnd.ms-fontobject eot +application/vnd.ms-htmlhelp chm +application/vnd.ms-ims ims +application/vnd.ms-lrm lrm +# application/vnd.ms-office.activex+xml +application/vnd.ms-officetheme thmx +# application/vnd.ms-opentype +# application/vnd.ms-package.obfuscated-opentype +application/vnd.ms-pki.seccat cat +application/vnd.ms-pki.stl stl +# application/vnd.ms-playready.initiator+xml +application/vnd.ms-powerpoint ppt pps pot +application/vnd.ms-powerpoint.addin.macroenabled.12 ppam +application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm +application/vnd.ms-powerpoint.slide.macroenabled.12 sldm +application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm +application/vnd.ms-powerpoint.template.macroenabled.12 potm +# application/vnd.ms-printing.printticket+xml +application/vnd.ms-project mpp mpt +# application/vnd.ms-tnef +# application/vnd.ms-wmdrm.lic-chlg-req +# application/vnd.ms-wmdrm.lic-resp +# application/vnd.ms-wmdrm.meter-chlg-req +# application/vnd.ms-wmdrm.meter-resp +application/vnd.ms-word.document.macroenabled.12 docm +application/vnd.ms-word.template.macroenabled.12 dotm +application/vnd.ms-works wps wks wcm wdb +application/vnd.ms-wpl wpl +application/vnd.ms-xpsdocument xps +application/vnd.mseq mseq +# application/vnd.msign +# application/vnd.multiad.creator +# application/vnd.multiad.creator.cif +# application/vnd.music-niff +application/vnd.musician mus +application/vnd.muvee.style msty +application/vnd.mynfc taglet +# application/vnd.ncd.control +# application/vnd.ncd.reference +# application/vnd.nervana +# application/vnd.netfpx +application/vnd.neurolanguage.nlu nlu +application/vnd.nitf ntf nitf +application/vnd.noblenet-directory nnd +application/vnd.noblenet-sealer nns +application/vnd.noblenet-web nnw +# application/vnd.nokia.catalogs +# application/vnd.nokia.conml+wbxml +# application/vnd.nokia.conml+xml +# application/vnd.nokia.isds-radio-presets +# application/vnd.nokia.iptv.config+xml +# application/vnd.nokia.landmark+wbxml +# application/vnd.nokia.landmark+xml +# application/vnd.nokia.landmarkcollection+xml +# application/vnd.nokia.n-gage.ac+xml +application/vnd.nokia.n-gage.data ngdat +application/vnd.nokia.n-gage.symbian.install n-gage +# application/vnd.nokia.ncd +# application/vnd.nokia.pcd+wbxml +# application/vnd.nokia.pcd+xml +application/vnd.nokia.radio-preset rpst +application/vnd.nokia.radio-presets rpss +application/vnd.novadigm.edm edm +application/vnd.novadigm.edx edx +application/vnd.novadigm.ext ext +# application/vnd.ntt-local.file-transfer +# application/vnd.ntt-local.sip-ta_remote +# application/vnd.ntt-local.sip-ta_tcp_stream +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.chart-template otc +application/vnd.oasis.opendocument.database odb +application/vnd.oasis.opendocument.formula odf +application/vnd.oasis.opendocument.formula-template odft +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.image-template oti +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master odm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +# application/vnd.obn +# application/vnd.oftn.l10n+json +# application/vnd.oipf.contentaccessdownload+xml +# application/vnd.oipf.contentaccessstreaming+xml +# application/vnd.oipf.cspg-hexbinary +# application/vnd.oipf.dae.svg+xml +# application/vnd.oipf.dae.xhtml+xml +# application/vnd.oipf.mippvcontrolmessage+xml +# application/vnd.oipf.pae.gem +# application/vnd.oipf.spdiscovery+xml +# application/vnd.oipf.spdlist+xml +# application/vnd.oipf.ueprofile+xml +# application/vnd.oipf.userprofile+xml +application/vnd.olpc-sugar xo +# application/vnd.oma-scws-config +# application/vnd.oma-scws-http-request +# application/vnd.oma-scws-http-response +# application/vnd.oma.bcast.associated-procedure-parameter+xml +# application/vnd.oma.bcast.drm-trigger+xml +# application/vnd.oma.bcast.imd+xml +# application/vnd.oma.bcast.ltkm +# application/vnd.oma.bcast.notification+xml +# application/vnd.oma.bcast.provisioningtrigger +# application/vnd.oma.bcast.sgboot +# application/vnd.oma.bcast.sgdd+xml +# application/vnd.oma.bcast.sgdu +# application/vnd.oma.bcast.simple-symbol-container +# application/vnd.oma.bcast.smartcard-trigger+xml +# application/vnd.oma.bcast.sprov+xml +# application/vnd.oma.bcast.stkm +# application/vnd.oma.cab-address-book+xml +# application/vnd.oma.cab-feature-handler+xml +# application/vnd.oma.cab-pcc+xml +# application/vnd.oma.cab-user-prefs+xml +# application/vnd.oma.dcd +# application/vnd.oma.dcdc +application/vnd.oma.dd2+xml dd2 +# application/vnd.oma.drm.risd+xml +# application/vnd.oma.group-usage-list+xml +# application/vnd.oma.pal+xml +# application/vnd.oma.poc.detailed-progress-report+xml +# application/vnd.oma.poc.final-report+xml +# application/vnd.oma.poc.groups+xml +# application/vnd.oma.poc.invocation-descriptor+xml +# application/vnd.oma.poc.optimized-progress-report+xml +# application/vnd.oma.push +# application/vnd.oma.scidm.messages+xml +# application/vnd.oma.xcap-directory+xml +# application/vnd.omads-email+xml +# application/vnd.omads-file+xml +# application/vnd.omads-folder+xml +# application/vnd.omaloc-supl-init +application/vnd.openofficeorg.extension oxt +# application/vnd.openxmlformats-officedocument.custom-properties+xml +# application/vnd.openxmlformats-officedocument.customxmlproperties+xml +# application/vnd.openxmlformats-officedocument.drawing+xml +# application/vnd.openxmlformats-officedocument.drawingml.chart+xml +# application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml +# application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml +# application/vnd.openxmlformats-officedocument.extended-properties+xml +# application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml +# application/vnd.openxmlformats-officedocument.presentationml.comments+xml +# application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml +# application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml +application/vnd.openxmlformats-officedocument.presentationml.presentation pptx +# application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.presprops+xml +application/vnd.openxmlformats-officedocument.presentationml.slide sldx +# application/vnd.openxmlformats-officedocument.presentationml.slide+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml +# application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml +application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx +# application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml +# application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml +# application/vnd.openxmlformats-officedocument.presentationml.tags+xml +application/vnd.openxmlformats-officedocument.presentationml.template potx +# application/vnd.openxmlformats-officedocument.presentationml.template.main+xml +# application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx +# application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml +# application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml +# application/vnd.openxmlformats-officedocument.theme+xml +# application/vnd.openxmlformats-officedocument.themeoverride+xml +# application/vnd.openxmlformats-officedocument.vmldrawing +# application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.document docx +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx +# application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml +# application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml +# application/vnd.openxmlformats-package.core-properties+xml +# application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml +# application/vnd.openxmlformats-package.relationships+xml +# application/vnd.quobject-quoxdocument +# application/vnd.osa.netdeploy +application/vnd.osgeo.mapguide.package mgp +# application/vnd.osgi.bundle +application/vnd.osgi.dp dp +application/vnd.osgi.subsystem esa +# application/vnd.otps.ct-kip+xml +application/vnd.palm pdb pqa oprc +# application/vnd.paos.xml +application/vnd.pawaafile paw +application/vnd.pg.format str +application/vnd.pg.osasli ei6 +# application/vnd.piaccess.application-licence +application/vnd.picsel efif +application/vnd.pmi.widget wg +# application/vnd.poc.group-advertisement+xml +application/vnd.pocketlearn plf +application/vnd.powerbuilder6 pbd +# application/vnd.powerbuilder6-s +# application/vnd.powerbuilder7 +# application/vnd.powerbuilder7-s +# application/vnd.powerbuilder75 +# application/vnd.powerbuilder75-s +# application/vnd.preminet +application/vnd.previewsystems.box box +application/vnd.proteus.magazine mgz +application/vnd.publishare-delta-tree qps +application/vnd.pvi.ptid1 ptid +# application/vnd.pwg-multiplexed +# application/vnd.pwg-xhtml-print+xml +# application/vnd.qualcomm.brew-app-res +application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb +# application/vnd.radisys.moml+xml +# application/vnd.radisys.msml+xml +# application/vnd.radisys.msml-audit+xml +# application/vnd.radisys.msml-audit-conf+xml +# application/vnd.radisys.msml-audit-conn+xml +# application/vnd.radisys.msml-audit-dialog+xml +# application/vnd.radisys.msml-audit-stream+xml +# application/vnd.radisys.msml-conf+xml +# application/vnd.radisys.msml-dialog+xml +# application/vnd.radisys.msml-dialog-base+xml +# application/vnd.radisys.msml-dialog-fax-detect+xml +# application/vnd.radisys.msml-dialog-fax-sendrecv+xml +# application/vnd.radisys.msml-dialog-group+xml +# application/vnd.radisys.msml-dialog-speech+xml +# application/vnd.radisys.msml-dialog-transform+xml +# application/vnd.rainstor.data +# application/vnd.rapid +application/vnd.realvnc.bed bed +application/vnd.recordare.musicxml mxl +application/vnd.recordare.musicxml+xml musicxml +# application/vnd.renlearn.rlprint +application/vnd.rig.cryptonote cryptonote +application/vnd.rim.cod cod +application/vnd.rn-realmedia rm +application/vnd.rn-realmedia-vbr rmvb +application/vnd.route66.link66+xml link66 +# application/vnd.rs-274x +# application/vnd.ruckus.download +# application/vnd.s3sms +application/vnd.sailingtracker.track st +# application/vnd.sbm.cid +# application/vnd.sbm.mid2 +# application/vnd.scribus +# application/vnd.sealed.3df +# application/vnd.sealed.csf +# application/vnd.sealed.doc +# application/vnd.sealed.eml +# application/vnd.sealed.mht +# application/vnd.sealed.net +# application/vnd.sealed.ppt +# application/vnd.sealed.tiff +# application/vnd.sealed.xls +# application/vnd.sealedmedia.softseal.html +# application/vnd.sealedmedia.softseal.pdf +application/vnd.seemail see +application/vnd.sema sema +application/vnd.semd semd +application/vnd.semf semf +application/vnd.shana.informed.formdata ifm +application/vnd.shana.informed.formtemplate itp +application/vnd.shana.informed.interchange iif +application/vnd.shana.informed.package ipk +application/vnd.simtech-mindmapper twd twds +application/vnd.smaf mmf +# application/vnd.smart.notebook +application/vnd.smart.teacher teacher +# application/vnd.software602.filler.form+xml +# application/vnd.software602.filler.form-xml-zip +application/vnd.solent.sdkm+xml sdkm sdkd +application/vnd.spotfire.dxp dxp +application/vnd.spotfire.sfs sfs +# application/vnd.sss-cod +# application/vnd.sss-dtf +# application/vnd.sss-ntf +application/vnd.stardivision.calc sdc +application/vnd.stardivision.draw sda +application/vnd.stardivision.impress sdd +application/vnd.stardivision.math smf +application/vnd.stardivision.writer sdw vor +application/vnd.stardivision.writer-global sgl +application/vnd.stepmania.package smzip +application/vnd.stepmania.stepchart sm +# application/vnd.street-stream +application/vnd.sun.xml.calc sxc +application/vnd.sun.xml.calc.template stc +application/vnd.sun.xml.draw sxd +application/vnd.sun.xml.draw.template std +application/vnd.sun.xml.impress sxi +application/vnd.sun.xml.impress.template sti +application/vnd.sun.xml.math sxm +application/vnd.sun.xml.writer sxw +application/vnd.sun.xml.writer.global sxg +application/vnd.sun.xml.writer.template stw +# application/vnd.sun.wadl+xml +application/vnd.sus-calendar sus susp +application/vnd.svd svd +# application/vnd.swiftview-ics +application/vnd.symbian.install sis sisx +application/vnd.syncml+xml xsm +application/vnd.syncml.dm+wbxml bdm +application/vnd.syncml.dm+xml xdm +# application/vnd.syncml.dm.notification +# application/vnd.syncml.ds.notification +application/vnd.tao.intent-module-archive tao +application/vnd.tcpdump.pcap pcap cap dmp +application/vnd.tmobile-livetv tmo +application/vnd.trid.tpt tpt +application/vnd.triscape.mxs mxs +application/vnd.trueapp tra +# application/vnd.truedoc +# application/vnd.ubisoft.webplayer +application/vnd.ufdl ufd ufdl +application/vnd.uiq.theme utz +application/vnd.umajin umj +application/vnd.unity unityweb +application/vnd.uoml+xml uoml +# application/vnd.uplanet.alert +# application/vnd.uplanet.alert-wbxml +# application/vnd.uplanet.bearer-choice +# application/vnd.uplanet.bearer-choice-wbxml +# application/vnd.uplanet.cacheop +# application/vnd.uplanet.cacheop-wbxml +# application/vnd.uplanet.channel +# application/vnd.uplanet.channel-wbxml +# application/vnd.uplanet.list +# application/vnd.uplanet.list-wbxml +# application/vnd.uplanet.listcmd +# application/vnd.uplanet.listcmd-wbxml +# application/vnd.uplanet.signal +application/vnd.vcx vcx +# application/vnd.vd-study +# application/vnd.vectorworks +# application/vnd.verimatrix.vcas +# application/vnd.vidsoft.vidconference +application/vnd.visio vsd vst vss vsw +application/vnd.visionary vis +# application/vnd.vividence.scriptfile +application/vnd.vsf vsf +# application/vnd.wap.sic +# application/vnd.wap.slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.webturbo wtb +# application/vnd.wfa.wsc +# application/vnd.wmc +# application/vnd.wmf.bootstrap +# application/vnd.wolfram.mathematica +# application/vnd.wolfram.mathematica.package +application/vnd.wolfram.player nbp +application/vnd.wordperfect wpd +application/vnd.wqd wqd +# application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf stf +# application/vnd.wv.csp+wbxml +# application/vnd.wv.csp+xml +# application/vnd.wv.ssp+xml +application/vnd.xara xar +application/vnd.xfdl xfdl +# application/vnd.xfdl.webform +# application/vnd.xmi+xml +# application/vnd.xmpie.cpkg +# application/vnd.xmpie.dpkg +# application/vnd.xmpie.plan +# application/vnd.xmpie.ppkg +# application/vnd.xmpie.xlim +application/vnd.yamaha.hv-dic hvd +application/vnd.yamaha.hv-script hvs +application/vnd.yamaha.hv-voice hvp +application/vnd.yamaha.openscoreformat osf +application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg +# application/vnd.yamaha.remote-setup +application/vnd.yamaha.smaf-audio saf +application/vnd.yamaha.smaf-phrase spf +# application/vnd.yamaha.through-ngn +# application/vnd.yamaha.tunnel-udpencap +application/vnd.yellowriver-custom-menu cmp +application/vnd.zul zir zirz +application/vnd.zzazz.deck+xml zaz +application/voicexml+xml vxml +# application/vq-rtcpxr +# application/watcherinfo+xml +# application/whoispp-query +# application/whoispp-response +application/widget wgt +application/winhlp hlp +# application/wita +# application/wordperfect5.1 +application/wsdl+xml wsdl +application/wspolicy+xml wspolicy +application/x-7z-compressed 7z +application/x-abiword abw +application/x-ace-compressed ace +# application/x-amf +application/x-apple-diskimage dmg +application/x-authorware-bin aab x32 u32 vox +application/x-authorware-map aam +application/x-authorware-seg aas +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-blorb blb blorb +application/x-bzip bz +application/x-bzip2 bz2 boz +application/x-cbr cbr cba cbt cbz cb7 +application/x-cdlink vcd +application/x-cfs-compressed cfs +application/x-chat chat +application/x-chess-pgn pgn +application/x-conference nsc +# application/x-compress +application/x-cpio cpio +application/x-csh csh +application/x-debian-package deb udeb +application/x-dgc-compressed dgc +application/x-director dir dcr dxr cst cct cxt w3d fgd swa +application/x-doom wad +application/x-dtbncx+xml ncx +application/x-dtbook+xml dtb +application/x-dtbresource+xml res +application/x-dvi dvi +application/x-envoy evy +application/x-eva eva +application/x-font-bdf bdf +# application/x-font-dos +# application/x-font-framemaker +application/x-font-ghostscript gsf +# application/x-font-libgrx +application/x-font-linux-psf psf +application/x-font-otf otf +application/x-font-pcf pcf +application/x-font-snf snf +# application/x-font-speedo +# application/x-font-sunos-news +application/x-font-ttf ttf ttc +application/x-font-type1 pfa pfb pfm afm +application/x-font-woff woff +# application/x-font-vfont +application/x-freearc arc +application/x-futuresplash spl +application/x-gca-compressed gca +application/x-glulx ulx +application/x-gnumeric gnumeric +application/x-gramps-xml gramps +application/x-gtar gtar +# application/x-gzip +application/x-hdf hdf +application/x-install-instructions install +application/x-iso9660-image iso +application/x-java-jnlp-file jnlp +application/x-latex latex +application/x-lzh-compressed lzh lha +application/x-mie mie +application/x-mobipocket-ebook prc mobi +application/x-ms-application application +application/x-ms-shortcut lnk +application/x-ms-wmd wmd +application/x-ms-wmz wmz +application/x-ms-xbap xbap +application/x-msaccess mdb +application/x-msbinder obd +application/x-mscardfile crd +application/x-msclip clp +application/x-msdownload exe dll com bat msi +application/x-msmediaview mvb m13 m14 +application/x-msmetafile wmf wmz emf emz +application/x-msmoney mny +application/x-mspublisher pub +application/x-msschedule scd +application/x-msterminal trm +application/x-mswrite wri +application/x-netcdf nc cdf +application/x-nzb nzb +application/x-pkcs12 p12 pfx +application/x-pkcs7-certificates p7b spc +application/x-pkcs7-certreqresp p7r +application/x-rar-compressed rar +application/x-research-info-systems ris +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-silverlight-app xap +application/x-sql sql +application/x-stuffit sit +application/x-stuffitx sitx +application/x-subrip srt +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-t3vm-image t3 +application/x-tads gam +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-tex-tfm tfm +application/x-texinfo texinfo texi +application/x-tgif obj +application/x-ustar ustar +application/x-wais-source src +application/x-x509-ca-cert der crt +application/x-xfig fig +application/x-xliff+xml xlf +application/x-xpinstall xpi +application/x-xz xz +application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8 +# application/x400-bp +application/xaml+xml xaml +# application/xcap-att+xml +# application/xcap-caps+xml +application/xcap-diff+xml xdf +# application/xcap-el+xml +# application/xcap-error+xml +# application/xcap-ns+xml +# application/xcon-conference-info-diff+xml +# application/xcon-conference-info+xml +application/xenc+xml xenc +application/xhtml+xml xhtml xht +# application/xhtml-voice+xml +application/xml xml xsl +application/xml-dtd dtd +# application/xml-external-parsed-entity +# application/xmpp+xml +application/xop+xml xop +application/xproc+xml xpl +application/xslt+xml xslt +application/xspf+xml xspf +application/xv+xml mxml xhvml xvml xvm +application/yang yang +application/yin+xml yin +application/zip zip +# audio/1d-interleaved-parityfec +# audio/32kadpcm +# audio/3gpp +# audio/3gpp2 +# audio/ac3 +audio/adpcm adp +# audio/amr +# audio/amr-wb +# audio/amr-wb+ +# audio/asc +# audio/atrac-advanced-lossless +# audio/atrac-x +# audio/atrac3 +audio/basic au snd +# audio/bv16 +# audio/bv32 +# audio/clearmode +# audio/cn +# audio/dat12 +# audio/dls +# audio/dsr-es201108 +# audio/dsr-es202050 +# audio/dsr-es202211 +# audio/dsr-es202212 +# audio/dv +# audio/dvi4 +# audio/eac3 +# audio/evrc +# audio/evrc-qcp +# audio/evrc0 +# audio/evrc1 +# audio/evrcb +# audio/evrcb0 +# audio/evrcb1 +# audio/evrcwb +# audio/evrcwb0 +# audio/evrcwb1 +# audio/example +# audio/fwdred +# audio/g719 +# audio/g722 +# audio/g7221 +# audio/g723 +# audio/g726-16 +# audio/g726-24 +# audio/g726-32 +# audio/g726-40 +# audio/g728 +# audio/g729 +# audio/g7291 +# audio/g729d +# audio/g729e +# audio/gsm +# audio/gsm-efr +# audio/gsm-hr-08 +# audio/ilbc +# audio/ip-mr_v2.5 +# audio/isac +# audio/l16 +# audio/l20 +# audio/l24 +# audio/l8 +# audio/lpc +audio/midi mid midi kar rmi +# audio/mobile-xmf +audio/mp4 m4a mp4a +# audio/mp4a-latm +# audio/mpa +# audio/mpa-robust +audio/mpeg mpga mp2 mp2a mp3 m2a m3a +# audio/mpeg4-generic +# audio/musepack +audio/ogg oga ogg spx +# audio/opus +# audio/parityfec +# audio/pcma +# audio/pcma-wb +# audio/pcmu-wb +# audio/pcmu +# audio/prs.sid +# audio/qcelp +# audio/red +# audio/rtp-enc-aescm128 +# audio/rtp-midi +# audio/rtx +audio/s3m s3m +audio/silk sil +# audio/smv +# audio/smv0 +# audio/smv-qcp +# audio/sp-midi +# audio/speex +# audio/t140c +# audio/t38 +# audio/telephone-event +# audio/tone +# audio/uemclip +# audio/ulpfec +# audio/vdvi +# audio/vmr-wb +# audio/vnd.3gpp.iufp +# audio/vnd.4sb +# audio/vnd.audiokoz +# audio/vnd.celp +# audio/vnd.cisco.nse +# audio/vnd.cmles.radio-events +# audio/vnd.cns.anp1 +# audio/vnd.cns.inf1 +audio/vnd.dece.audio uva uvva +audio/vnd.digital-winds eol +# audio/vnd.dlna.adts +# audio/vnd.dolby.heaac.1 +# audio/vnd.dolby.heaac.2 +# audio/vnd.dolby.mlp +# audio/vnd.dolby.mps +# audio/vnd.dolby.pl2 +# audio/vnd.dolby.pl2x +# audio/vnd.dolby.pl2z +# audio/vnd.dolby.pulse.1 +audio/vnd.dra dra +audio/vnd.dts dts +audio/vnd.dts.hd dtshd +# audio/vnd.dvb.file +# audio/vnd.everad.plj +# audio/vnd.hns.audio +audio/vnd.lucent.voice lvp +audio/vnd.ms-playready.media.pya pya +# audio/vnd.nokia.mobile-xmf +# audio/vnd.nortel.vbk +audio/vnd.nuera.ecelp4800 ecelp4800 +audio/vnd.nuera.ecelp7470 ecelp7470 +audio/vnd.nuera.ecelp9600 ecelp9600 +# audio/vnd.octel.sbc +# audio/vnd.qcelp +# audio/vnd.rhetorex.32kadpcm +audio/vnd.rip rip +# audio/vnd.sealedmedia.softseal.mpeg +# audio/vnd.vmx.cvsd +# audio/vorbis +# audio/vorbis-config +audio/webm weba +audio/x-aac aac +audio/x-aiff aif aiff aifc +audio/x-caf caf +audio/x-flac flac +audio/x-matroska mka +audio/x-mpegurl m3u +audio/x-ms-wax wax +audio/x-ms-wma wma +audio/x-pn-realaudio ram ra +audio/x-pn-realaudio-plugin rmp +# audio/x-tta +audio/x-wav wav +audio/xm xm +chemical/x-cdx cdx +chemical/x-cif cif +chemical/x-cmdf cmdf +chemical/x-cml cml +chemical/x-csml csml +# chemical/x-pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +# image/example +# image/fits +image/g3fax g3 +image/gif gif +image/ief ief +# image/jp2 +image/jpeg jpeg jpg jpe +# image/jpm +# image/jpx +image/ktx ktx +# image/naplps +image/png png +image/prs.btif btif +# image/prs.pti +image/sgi sgi +image/svg+xml svg svgz +# image/t38 +image/tiff tiff tif +# image/tiff-fx +image/vnd.adobe.photoshop psd +# image/vnd.cns.inf2 +image/vnd.dece.graphic uvi uvvi uvg uvvg +image/vnd.dvb.subtitle sub +image/vnd.djvu djvu djv +image/vnd.dwg dwg +image/vnd.dxf dxf +image/vnd.fastbidsheet fbs +image/vnd.fpx fpx +image/vnd.fst fst +image/vnd.fujixerox.edmics-mmr mmr +image/vnd.fujixerox.edmics-rlc rlc +# image/vnd.globalgraphics.pgb +# image/vnd.microsoft.icon +# image/vnd.mix +image/vnd.ms-modi mdi +image/vnd.ms-photo wdp +image/vnd.net-fpx npx +# image/vnd.radiance +# image/vnd.sealed.png +# image/vnd.sealedmedia.softseal.gif +# image/vnd.sealedmedia.softseal.jpg +# image/vnd.svf +image/vnd.wap.wbmp wbmp +image/vnd.xiff xif +image/webp webp +image/x-3ds 3ds +image/x-cmu-raster ras +image/x-cmx cmx +image/x-freehand fh fhc fh4 fh5 fh7 +image/x-icon ico +image/x-mrsid-image sid +image/x-pcx pcx +image/x-pict pic pct +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-tga tga +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +# message/cpim +# message/delivery-status +# message/disposition-notification +# message/example +# message/external-body +# message/feedback-report +# message/global +# message/global-delivery-status +# message/global-disposition-notification +# message/global-headers +# message/http +# message/imdn+xml +# message/news +# message/partial +message/rfc822 eml mime +# message/s-http +# message/sip +# message/sipfrag +# message/tracking-status +# message/vnd.si.simp +# model/example +model/iges igs iges +model/mesh msh mesh silo +model/vnd.collada+xml dae +model/vnd.dwf dwf +# model/vnd.flatland.3dml +model/vnd.gdl gdl +# model/vnd.gs-gdl +# model/vnd.gs.gdl +model/vnd.gtw gtw +# model/vnd.moml+xml +model/vnd.mts mts +# model/vnd.parasolid.transmit.binary +# model/vnd.parasolid.transmit.text +model/vnd.vtu vtu +model/vrml wrl vrml +model/x3d+binary x3db x3dbz +model/x3d+vrml x3dv x3dvz +model/x3d+xml x3d x3dz +# multipart/alternative +# multipart/appledouble +# multipart/byteranges +# multipart/digest +# multipart/encrypted +# multipart/example +# multipart/form-data +# multipart/header-set +# multipart/mixed +# multipart/parallel +# multipart/related +# multipart/report +# multipart/signed +# multipart/voice-message +# text/1d-interleaved-parityfec +text/cache-manifest appcache +text/calendar ics ifb +text/css css +text/csv csv +# text/directory +# text/dns +# text/ecmascript +# text/enriched +# text/example +# text/fwdred +text/html html htm +# text/javascript +text/n3 n3 +# text/parityfec +text/plain txt text conf def list log in +# text/prs.fallenstein.rst +text/prs.lines.tag dsc +# text/vnd.radisys.msml-basic-layout +# text/red +# text/rfc822-headers +text/richtext rtx +# text/rtf +# text/rtp-enc-aescm128 +# text/rtx +text/sgml sgml sgm +# text/t140 +text/tab-separated-values tsv +text/troff t tr roff man me ms +text/turtle ttl +# text/ulpfec +text/uri-list uri uris urls +text/vcard vcard +# text/vnd.abc +text/vnd.curl curl +text/vnd.curl.dcurl dcurl +text/vnd.curl.scurl scurl +text/vnd.curl.mcurl mcurl +# text/vnd.dmclientscript +text/vnd.dvb.subtitle sub +# text/vnd.esmertec.theme-descriptor +text/vnd.fly fly +text/vnd.fmi.flexstor flx +text/vnd.graphviz gv +text/vnd.in3d.3dml 3dml +text/vnd.in3d.spot spot +# text/vnd.iptc.newsml +# text/vnd.iptc.nitf +# text/vnd.latex-z +# text/vnd.motorola.reflex +# text/vnd.ms-mediapackage +# text/vnd.net2phone.commcenter.command +# text/vnd.si.uricatalogue +text/vnd.sun.j2me.app-descriptor jad +# text/vnd.trolltech.linguist +# text/vnd.wap.si +# text/vnd.wap.sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-asm s asm +text/x-c c cc cxx cpp h hh dic +text/x-fortran f for f77 f90 +text/x-java-source java +text/x-opml opml +text/x-pascal p pas +text/x-nfo nfo +text/x-setext etx +text/x-sfv sfv +text/x-uuencode uu +text/x-vcalendar vcs +text/x-vcard vcf +# text/xml +# text/xml-external-parsed-entity +# video/1d-interleaved-parityfec +video/3gpp 3gp +# video/3gpp-tt +video/3gpp2 3g2 +# video/bmpeg +# video/bt656 +# video/celb +# video/dv +# video/example +video/h261 h261 +video/h263 h263 +# video/h263-1998 +# video/h263-2000 +video/h264 h264 +# video/h264-rcdo +# video/h264-svc +video/jpeg jpgv +# video/jpeg2000 +video/jpm jpm jpgm +video/mj2 mj2 mjp2 +# video/mp1s +# video/mp2p +# video/mp2t +video/mp4 mp4 mp4v mpg4 +# video/mp4v-es +video/mpeg mpeg mpg mpe m1v m2v +# video/mpeg4-generic +# video/mpv +# video/nv +video/ogg ogv +# video/parityfec +# video/pointer +video/quicktime qt mov +# video/raw +# video/rtp-enc-aescm128 +# video/rtx +# video/smpte292m +# video/ulpfec +# video/vc1 +# video/vnd.cctv +video/vnd.dece.hd uvh uvvh +video/vnd.dece.mobile uvm uvvm +# video/vnd.dece.mp4 +video/vnd.dece.pd uvp uvvp +video/vnd.dece.sd uvs uvvs +video/vnd.dece.video uvv uvvv +# video/vnd.directv.mpeg +# video/vnd.directv.mpeg-tts +# video/vnd.dlna.mpeg-tts +video/vnd.dvb.file dvb +video/vnd.fvt fvt +# video/vnd.hns.video +# video/vnd.iptvforum.1dparityfec-1010 +# video/vnd.iptvforum.1dparityfec-2005 +# video/vnd.iptvforum.2dparityfec-1010 +# video/vnd.iptvforum.2dparityfec-2005 +# video/vnd.iptvforum.ttsavc +# video/vnd.iptvforum.ttsmpeg2 +# video/vnd.motorola.video +# video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.ms-playready.media.pyv pyv +# video/vnd.nokia.interleaved-multimedia +# video/vnd.nokia.videovoip +# video/vnd.objectvideo +# video/vnd.sealed.mpeg1 +# video/vnd.sealed.mpeg4 +# video/vnd.sealed.swf +# video/vnd.sealedmedia.softseal.mov +video/vnd.uvvu.mp4 uvu uvvu +video/vnd.vivo viv +video/webm webm +video/x-f4v f4v +video/x-fli fli +video/x-flv flv +video/x-m4v m4v +video/x-matroska mkv mk3d mks +video/x-mng mng +video/x-ms-asf asf asx +video/x-ms-vob vob +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie +video/x-smv smv +x-conference/x-cooltalk ice diff --git a/core-java/src/test/resources/product.png b/core-java/src/test/resources/product.png new file mode 100644 index 0000000000..4edd01c0a1 Binary files /dev/null and b/core-java/src/test/resources/product.png differ diff --git a/core-java/src/test/resources/sampleNumberFile.txt b/core-java/src/test/resources/sampleNumberFile.txt new file mode 100644 index 0000000000..7787faa3c1 --- /dev/null +++ b/core-java/src/test/resources/sampleNumberFile.txt @@ -0,0 +1,2 @@ +111 +222 \ No newline at end of file diff --git a/core-java/src/test/resources/sampleTextFile.txt b/core-java/src/test/resources/sampleTextFile.txt new file mode 100644 index 0000000000..75cb50aafa --- /dev/null +++ b/core-java/src/test/resources/sampleTextFile.txt @@ -0,0 +1,2 @@ +Hello +World \ No newline at end of file diff --git a/core-kotlin/.gitignore b/core-kotlin/.gitignore index ae3c172604..0c017e8f8c 100644 --- a/core-kotlin/.gitignore +++ b/core-kotlin/.gitignore @@ -1 +1,14 @@ /bin/ + +#ignore gradle +.gradle/ + + +#ignore build and generated files +build/ +node/ +out/ + +#ignore installed node modules and package lock file +node_modules/ +package-lock.json diff --git a/core-kotlin/README.md b/core-kotlin/README.md index 7fcdc68429..523f5b6e78 100644 --- a/core-kotlin/README.md +++ b/core-kotlin/README.md @@ -8,7 +8,6 @@ - [Generics in Kotlin](http://www.baeldung.com/kotlin-generics) - [Introduction to Kotlin Coroutines](http://www.baeldung.com/kotlin-coroutines) - [Destructuring Declarations in Kotlin](http://www.baeldung.com/kotlin-destructuring-declarations) -- [Kotlin with Mockito](http://www.baeldung.com/kotlin-mockito) - [Lazy Initialization in Kotlin](http://www.baeldung.com/kotlin-lazy-initialization) - [Overview of Kotlin Collections API](http://www.baeldung.com/kotlin-collections-api) - [Converting a List to Map in Kotlin](http://www.baeldung.com/kotlin-list-to-map) @@ -19,8 +18,6 @@ - [Extension Methods in Kotlin](http://www.baeldung.com/kotlin-extension-methods) - [Infix Functions in Kotlin](http://www.baeldung.com/kotlin-infix-functions) - [Try-with-resources in Kotlin](http://www.baeldung.com/kotlin-try-with-resources) -- [HTTP Requests with Kotlin and khttp](http://www.baeldung.com/kotlin-khttp) -- [Kotlin Dependency Injection with Kodein](http://www.baeldung.com/kotlin-kodein-dependency-injection) - [Regular Expressions in Kotlin](http://www.baeldung.com/kotlin-regular-expressions) - [Objects in Kotlin](http://www.baeldung.com/kotlin-objects) - [Reading from a File in Kotlin](http://www.baeldung.com/kotlin-read-file) @@ -28,5 +25,17 @@ - [Filtering Kotlin Collections](http://www.baeldung.com/kotlin-filter-collection) - [Writing to a File in Kotlin](http://www.baeldung.com/kotlin-write-file) - [Lambda Expressions in Kotlin](http://www.baeldung.com/kotlin-lambda-expressions) -- [Writing Specifications with Kotlin and Spek](http://www.baeldung.com/kotlin-spek) -- [Processing JSON with Kotlin and Klaxson](http://www.baeldung.com/kotlin-json-klaxson) +- [Kotlin String Templates](http://www.baeldung.com/kotlin-string-template) +- [Working with Enums in Kotlin](http://www.baeldung.com/kotlin-enum) +- [Create a Java and Kotlin Project with Maven](http://www.baeldung.com/kotlin-maven-java-project) +- [Reflection with Kotlin](http://www.baeldung.com/kotlin-reflection) +- [Get a Random Number in Kotlin](http://www.baeldung.com/kotlin-random-number) +- [Idiomatic Logging in Kotlin](http://www.baeldung.com/kotlin-logging) +- [Kotlin Constructors](https://www.baeldung.com/kotlin-constructors) +- [Creational Design Patterns in Kotlin: Builder](https://www.baeldung.com/kotlin-builder-pattern) +- [Kotlin Nested and Inner Classes](https://www.baeldung.com/kotlin-inner-classes) +- [Kotlin with Ktor](https://www.baeldung.com/kotlin-ktor) +- [Fuel HTTP Library with Kotlin](https://www.baeldung.com/kotlin-fuel) +- [Introduction to Kovenant Library for Kotlin](https://www.baeldung.com/kotlin-kovenant) +- [Converting Kotlin Data Class from JSON using GSON](https://www.baeldung.com/kotlin-json-convert-data-class) +- [Concatenate Strings in Kotlin](https://www.baeldung.com/kotlin-concatenate-strings) diff --git a/core-kotlin/build.gradle b/core-kotlin/build.gradle new file mode 100755 index 0000000000..2b6527fca7 --- /dev/null +++ b/core-kotlin/build.gradle @@ -0,0 +1,48 @@ + + +group 'com.baeldung.ktor' +version '1.0-SNAPSHOT' + + +buildscript { + ext.kotlin_version = '1.2.41' + + repositories { + mavenCentral() + } + dependencies { + + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName = 'APIServer.kt' + +sourceCompatibility = 1.8 +compileKotlin { kotlinOptions.jvmTarget = "1.8" } +compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } + +kotlin { experimental { coroutines "enable" } } + +repositories { + mavenCentral() + jcenter() + maven { url "https://dl.bintray.com/kotlin/ktor" } +} +sourceSets { + main{ + kotlin{ + srcDirs 'com/baeldung/ktor' + } + } + +} + +dependencies { + compile "ch.qos.logback:logback-classic:1.2.1" + testCompile group: 'junit', name: 'junit', version: '4.12' +} \ No newline at end of file diff --git a/kotlin-ktor/gradle/wrapper/gradle-wrapper.jar b/core-kotlin/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from kotlin-ktor/gradle/wrapper/gradle-wrapper.jar rename to core-kotlin/gradle/wrapper/gradle-wrapper.jar diff --git a/kotlin-ktor/gradle/wrapper/gradle-wrapper.properties b/core-kotlin/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from kotlin-ktor/gradle/wrapper/gradle-wrapper.properties rename to core-kotlin/gradle/wrapper/gradle-wrapper.properties diff --git a/kotlin-ktor/gradlew b/core-kotlin/gradlew similarity index 100% rename from kotlin-ktor/gradlew rename to core-kotlin/gradlew diff --git a/kotlin-ktor/gradlew.bat b/core-kotlin/gradlew.bat similarity index 100% rename from kotlin-ktor/gradlew.bat rename to core-kotlin/gradlew.bat diff --git a/core-kotlin/pom.xml b/core-kotlin/pom.xml index 1dd804eedd..0894a57320 100644 --- a/core-kotlin/pom.xml +++ b/core-kotlin/pom.xml @@ -3,22 +3,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-kotlin - 1.0-SNAPSHOT jar com.baeldung - parent-modules + parent-kotlin 1.0.0-SNAPSHOT + ../parent-kotlin - - - central - http://jcenter.bintray.com - - - org.apache.commons @@ -31,67 +24,6 @@ ${junit.platform.version} test - - org.jetbrains.kotlin - kotlin-stdlib - ${kotlin-stdlib.version} - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin-stdlib.version} - - - khttp - khttp - ${khttp.version} - - - org.jetbrains.kotlin - kotlin-test-junit - ${kotlin-test-junit.version} - test - - - org.jetbrains.kotlin - kotlin-reflect - ${kotlin-reflect.version} - test - - - org.jetbrains.kotlinx - kotlinx-coroutines-core - ${kotlinx.version} - - - org.jetbrains.spek - spek-api - 1.1.5 - test - - - org.jetbrains.spek - spek-subject-extension - 1.1.5 - test - - - org.jetbrains.spek - spek-junit-platform-engine - 1.1.5 - test - - - com.nhaarman - mockito-kotlin - ${mockito-kotlin.version} - test - - - com.github.salomonbrys.kodein - kodein - ${kodein.version} - org.assertj assertj-core @@ -99,130 +31,45 @@ test - com.beust - klaxon - ${klaxon.version} + com.h2database + h2 + ${h2database.version} + + + com.github.kittinunf.fuel + fuel + ${fuel.version} + + + com.github.kittinunf.fuel + fuel-gson + ${fuel.version} + + + com.github.kittinunf.fuel + fuel-rxjava + ${fuel.version} + + + com.github.kittinunf.fuel + fuel-coroutines + ${fuel.version} + + + nl.komponents.kovenant + kovenant + 3.3.0 + pom - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin-maven-plugin.version} - - - compile - - compile - - - - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/main/java - - - - - test-compile - - test-compile - - - - ${project.basedir}/src/test/kotlin - ${project.basedir}/src/test/java - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - default-compile - none - - - - default-testCompile - none - - - java-compile - compile - - compile - - - - java-test-compile - test-compile - - testCompile - - - - - - maven-failsafe-plugin - ${maven-failsafe-plugin.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - - - - - junit5 - - integration-test - verify - - - - **/*Test5.java - - - - - - - - - UTF-8 - 1.2.41 - 1.2.41 - 1.2.41 - 1.2.41 - 0.22.5 - 1.5.0 - 4.1.0 - 3.0.4 - 2.21.0 - 0.1.0 3.6.1 - 5.2.0 - 1.2.0 + 1.1.1 5.2.0 - 4.12 3.10.0 - 1.8 - 1.8 + 1.4.197 + 1.15.0 diff --git a/kotlin-ktor/resources/logback.xml b/core-kotlin/resources/logback.xml similarity index 100% rename from kotlin-ktor/resources/logback.xml rename to core-kotlin/resources/logback.xml diff --git a/kotlin-ktor/settings.gradle b/core-kotlin/settings.gradle similarity index 100% rename from kotlin-ktor/settings.gradle rename to core-kotlin/settings.gradle diff --git a/core-kotlin/src/main/java/com/baeldung/constructor/Car.kt b/core-kotlin/src/main/java/com/baeldung/constructor/Car.kt new file mode 100644 index 0000000000..72b8d330e8 --- /dev/null +++ b/core-kotlin/src/main/java/com/baeldung/constructor/Car.kt @@ -0,0 +1,17 @@ +package com.baeldung.constructor + +class Car { + val id: String + val type: String + + constructor(id: String, type: String) { + this.id = id + this.type = type + } + +} + +fun main(args: Array) { + val car = Car("1", "sport") + val s= Car("2", "suv") +} \ No newline at end of file diff --git a/core-kotlin/src/main/java/com/baeldung/constructor/Employee.kt b/core-kotlin/src/main/java/com/baeldung/constructor/Employee.kt new file mode 100644 index 0000000000..4483bfcf08 --- /dev/null +++ b/core-kotlin/src/main/java/com/baeldung/constructor/Employee.kt @@ -0,0 +1,3 @@ +package com.baeldung.constructor + +class Employee(name: String, val salary: Int): Person(name) \ No newline at end of file diff --git a/core-kotlin/src/main/java/com/baeldung/constructor/Person.java b/core-kotlin/src/main/java/com/baeldung/constructor/Person.java new file mode 100644 index 0000000000..57911b24ee --- /dev/null +++ b/core-kotlin/src/main/java/com/baeldung/constructor/Person.java @@ -0,0 +1,19 @@ +package com.baeldung.constructor; + +class PersonJava { + final String name; + final String surname; + final Integer age; + + public PersonJava(String name, String surname) { + this.name = name; + this.surname = surname; + this.age = null; + } + + public PersonJava(String name, String surname, Integer age) { + this.name = name; + this.surname = surname; + this.age = age; + } +} diff --git a/core-kotlin/src/main/java/com/baeldung/mavenjavakotlin/Application.java b/core-kotlin/src/main/java/com/baeldung/mavenjavakotlin/Application.java new file mode 100644 index 0000000000..e2cc0f1e01 --- /dev/null +++ b/core-kotlin/src/main/java/com/baeldung/mavenjavakotlin/Application.java @@ -0,0 +1,26 @@ +package com.baeldung.mavenjavakotlin; + +import com.baeldung.mavenjavakotlin.services.JavaService; +import com.baeldung.mavenjavakotlin.services.KotlinService; + +public class Application { + + private static final String JAVA = "java"; + private static final String KOTLIN = "kotlin"; + + public static void main(String[] args) { + String language = args[0]; + switch (language) { + case JAVA: + new JavaService().sayHello(); + break; + case KOTLIN: + new KotlinService().sayHello(); + break; + default: + // Do nothing + break; + } + } + +} diff --git a/core-kotlin/src/main/java/com/baeldung/mavenjavakotlin/services/JavaService.java b/core-kotlin/src/main/java/com/baeldung/mavenjavakotlin/services/JavaService.java new file mode 100644 index 0000000000..b767e761af --- /dev/null +++ b/core-kotlin/src/main/java/com/baeldung/mavenjavakotlin/services/JavaService.java @@ -0,0 +1,9 @@ +package com.baeldung.mavenjavakotlin.services; + +public class JavaService { + + public void sayHello() { + System.out.println("Java says 'Hello World!'"); + } + +} diff --git a/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrder.kt b/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrder.kt new file mode 100644 index 0000000000..1384cd9937 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrder.kt @@ -0,0 +1,22 @@ +package com.baeldung.builder + +class FoodOrder( + val bread: String?, + val condiments: String?, + val meat: String?, + val fish: String? +) { + data class Builder( + var bread: String? = null, + var condiments: String? = null, + var meat: String? = null, + var fish: String? = null) { + + fun bread(bread: String) = apply { this.bread = bread } + fun condiments(condiments: String) = apply { this.condiments = condiments } + fun meat(meat: String) = apply { this.meat = meat } + fun fish(fish: String) = apply { this.fish = fish } + fun build() = FoodOrder(bread, condiments, meat, fish) + } +} + diff --git a/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrderApply.kt b/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrderApply.kt new file mode 100644 index 0000000000..0a68832b00 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrderApply.kt @@ -0,0 +1,8 @@ +package com.baeldung.builder + +class FoodOrderApply { + var bread: String? = null + var condiments: String? = null + var meat: String? = null + var fish: String? = null +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrderNamed.kt b/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrderNamed.kt new file mode 100644 index 0000000000..0e4219b40e --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/builder/FoodOrderNamed.kt @@ -0,0 +1,7 @@ +package com.baeldung.builder + +data class FoodOrderNamed( + val bread: String? = null, + val condiments: String? = null, + val meat: String? = null, + val fish: String? = null) diff --git a/core-kotlin/src/main/kotlin/com/baeldung/builder/Main.kt b/core-kotlin/src/main/kotlin/com/baeldung/builder/Main.kt new file mode 100644 index 0000000000..cc348e3fbf --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/builder/Main.kt @@ -0,0 +1,9 @@ +package com.baeldung.builder + +fun main(args: Array) { + FoodOrder.Builder() + .bread("bread") + .condiments("condiments") + .meat("meat") + .fish("bread").let { println(it) } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/constructor/Person.kt b/core-kotlin/src/main/kotlin/com/baeldung/constructor/Person.kt new file mode 100644 index 0000000000..3779d74541 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/constructor/Person.kt @@ -0,0 +1,26 @@ +package com.baeldung.constructor + +open class Person( + val name: String, + val age: Int? = null +) { + val upperCaseName: String = name.toUpperCase() + + init { + println("Hello, I'm $name") + + if (age != null && age < 0) { + throw IllegalArgumentException("Age cannot be less than zero!") + } + } + + init { + println("upperCaseName is $upperCaseName") + } + +} + +fun main(args: Array) { + val person = Person("John") + val personWithAge = Person("John", 22) +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/datastructures/Main.kt b/core-kotlin/src/main/kotlin/com/baeldung/datastructures/Main.kt new file mode 100644 index 0000000000..4fd8aa27c7 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/datastructures/Main.kt @@ -0,0 +1,19 @@ +package com.baeldung.datastructures + +/** + * Example of how to use the {@link Node} class. + * + */ +fun main(args: Array) { + val tree = Node(4) + val keys = arrayOf(8, 15, 21, 3, 7, 2, 5, 10, 2, 3, 4, 6, 11) + for (key in keys) { + tree.insert(key) + } + val node = tree.find(4)!! + println("Node with value ${node.key} [left = ${node.left?.key}, right = ${node.right?.key}]") + println("Delete node with key = 3") + node.delete(3) + print("Tree content after the node elimination: ") + println(tree.visit().joinToString { it.toString() }) +} diff --git a/core-kotlin/src/main/kotlin/com/baeldung/datastructures/Node.kt b/core-kotlin/src/main/kotlin/com/baeldung/datastructures/Node.kt new file mode 100644 index 0000000000..b81afe1e4c --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/datastructures/Node.kt @@ -0,0 +1,167 @@ +package com.baeldung.datastructures + +/** + * An ADT for a binary search tree. + * Note that this data type is neither immutable nor thread safe. + */ +class Node( + var key: Int, + var left: Node? = null, + var right: Node? = null) { + + /** + * Return a node with given value. If no such node exists, return null. + * @param value + */ + fun find(value: Int): Node? = when { + this.key > value -> left?.find(value) + this.key < value -> right?.find(value) + else -> this + + } + + /** + * Insert a given value into the tree. + * After insertion, the tree should contain a node with the given value. + * If the tree already contains the given value, nothing is performed. + * @param value + */ + fun insert(value: Int) { + if (value > this.key) { + if (this.right == null) { + this.right = Node(value) + } else { + this.right?.insert(value) + } + } else if (value < this.key) { + if (this.left == null) { + this.left = Node(value) + } else { + this.left?.insert(value) + } + } + } + + /** + * Delete the value from the given tree. If the tree does not contain the value, the tree remains unchanged. + * @param value + */ + fun delete(value: Int) { + when { + value > key -> scan(value, this.right, this) + value < key -> scan(value, this.left, this) + else -> removeNode(this, null) + } + } + + /** + * Scan the tree in the search of the given value. + * @param value + * @param node sub-tree that potentially might contain the sought value + * @param parent node's parent + */ + private fun scan(value: Int, node: Node?, parent: Node?) { + if (node == null) { + System.out.println("value " + value + + " seems not present in the tree.") + return + } + when { + value > node.key -> scan(value, node.right, node) + value < node.key -> scan(value, node.left, node) + value == node.key -> removeNode(node, parent) + } + + } + + /** + * Remove the node. + * + * Removal process depends on how many children the node has. + * + * @param node node that is to be removed + * @param parent parent of the node to be removed + */ + private fun removeNode(node: Node, parent: Node?) { + node.left?.let { leftChild -> + run { + node.right?.let { + removeTwoChildNode(node) + } ?: removeSingleChildNode(node, leftChild) + } + } ?: run { + node.right?.let { rightChild -> removeSingleChildNode(node, rightChild) } ?: removeNoChildNode(node, parent) + } + + + } + + /** + * Remove the node without children. + * @param node + * @param parent + */ + private fun removeNoChildNode(node: Node, parent: Node?) { + parent?.let { p -> + if (node == p.left) { + p.left = null + } else if (node == p.right) { + p.right = null + } + } ?: throw IllegalStateException( + "Can not remove the root node without child nodes") + + } + + /** + * Remove a node that has two children. + * + * The process of elimination is to find the biggest key in the left sub-tree and replace the key of the + * node that is to be deleted with that key. + */ + private fun removeTwoChildNode(node: Node) { + val leftChild = node.left!! + leftChild.right?.let { + val maxParent = findParentOfMaxChild(leftChild) + maxParent.right?.let { + node.key = it.key + maxParent.right = null + } ?: throw IllegalStateException("Node with max child must have the right child!") + + } ?: run { + node.key = leftChild.key + node.left = leftChild.left + } + + } + + /** + * Return a node whose right child contains the biggest value in the given sub-tree. + * Assume that the node n has a non-null right child. + * + * @param n + */ + private fun findParentOfMaxChild(n: Node): Node { + return n.right?.let { r -> r.right?.let { findParentOfMaxChild(r) } ?: n } + ?: throw IllegalArgumentException("Right child must be non-null") + + } + + /** + * Remove a parent that has only one child. + * Removal is effectively is just coping the data from the child parent to the parent parent. + * @param parent Node to be deleted. Assume that it has just one child + * @param child Assume it is a child of the parent + */ + private fun removeSingleChildNode(parent: Node, child: Node) { + parent.key = child.key + parent.left = child.left + parent.right = child.right + } + + fun visit(): Array { + val a = left?.visit() ?: emptyArray() + val b = right?.visit() ?: emptyArray() + return a + arrayOf(key) + b + } +} diff --git a/core-kotlin/src/main/kotlin/com/baeldung/fuel/Interceptors.kt b/core-kotlin/src/main/kotlin/com/baeldung/fuel/Interceptors.kt new file mode 100644 index 0000000000..377ef979dc --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/fuel/Interceptors.kt @@ -0,0 +1,11 @@ +package com.baeldung.fuel + +import com.github.kittinunf.fuel.core.Request + +fun tokenInterceptor() = { + next: (Request) -> Request -> + { req: Request -> + req.header(mapOf("Authorization" to "Bearer AbCdEf123456")) + next(req) + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/fuel/Post.kt b/core-kotlin/src/main/kotlin/com/baeldung/fuel/Post.kt new file mode 100644 index 0000000000..035dfe7aa0 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/fuel/Post.kt @@ -0,0 +1,15 @@ +package com.baeldung.fuel + +import com.github.kittinunf.fuel.core.ResponseDeserializable +import com.google.gson.Gson + +data class Post(var userId:Int, + var id:Int, + var title:String, + var body:String){ + + + class Deserializer : ResponseDeserializable> { + override fun deserialize(content: String): Array = Gson().fromJson(content, Array::class.java) + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/fuel/PostRoutingAPI.kt b/core-kotlin/src/main/kotlin/com/baeldung/fuel/PostRoutingAPI.kt new file mode 100644 index 0000000000..8238c41e56 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/fuel/PostRoutingAPI.kt @@ -0,0 +1,42 @@ +package com.baeldung.fuel + +import com.github.kittinunf.fuel.core.Method +import com.github.kittinunf.fuel.util.FuelRouting + +sealed class PostRoutingAPI : FuelRouting { + + override val basePath = "https://jsonplaceholder.typicode.com" + + class posts(val id: String, override val body: String?): PostRoutingAPI() + + class comments(val postId: String, override val body: String?): PostRoutingAPI() + + override val method: Method + get() { + return when(this) { + is PostRoutingAPI.posts -> Method.GET + is PostRoutingAPI.comments -> Method.GET + } + } + + override val path: String + get() { + return when(this) { + is PostRoutingAPI.posts -> "/posts" + is PostRoutingAPI.comments -> "/comments" + } + } + + override val params: List>? + get() { + return when(this) { + is PostRoutingAPI.posts -> listOf("id" to this.id) + is PostRoutingAPI.comments -> listOf("postId" to this.postId) + } + } + + override val headers: Map? + get() { + return null + } +} diff --git a/core-kotlin/src/main/kotlin/com/baeldung/interfaces/ConflictingInterfaces.kt b/core-kotlin/src/main/kotlin/com/baeldung/interfaces/ConflictingInterfaces.kt new file mode 100644 index 0000000000..630afbdae7 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/interfaces/ConflictingInterfaces.kt @@ -0,0 +1,23 @@ +package com.baeldung.interfaces + +interface BaseInterface { + fun someMethod(): String +} + +interface FirstChildInterface : BaseInterface { + override fun someMethod(): String { + return("Hello, from someMethod in FirstChildInterface") + } +} + +interface SecondChildInterface : BaseInterface { + override fun someMethod(): String { + return("Hello, from someMethod in SecondChildInterface") + } +} + +class ChildClass : FirstChildInterface, SecondChildInterface { + override fun someMethod(): String { + return super.someMethod() + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/interfaces/InterfaceDelegation.kt b/core-kotlin/src/main/kotlin/com/baeldung/interfaces/InterfaceDelegation.kt new file mode 100644 index 0000000000..591fde0689 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/interfaces/InterfaceDelegation.kt @@ -0,0 +1,13 @@ +package com.baeldung.interfaces + +interface MyInterface { + fun someMethod(): String +} + +class MyClass() : MyInterface { + override fun someMethod(): String { + return("Hello, World!") + } +} + +class MyDerivedClass(myInterface: MyInterface) : MyInterface by myInterface \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/interfaces/MultipleInterfaces.kt b/core-kotlin/src/main/kotlin/com/baeldung/interfaces/MultipleInterfaces.kt new file mode 100644 index 0000000000..105a85cbb3 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/interfaces/MultipleInterfaces.kt @@ -0,0 +1,29 @@ +package com.baeldung.interfaces + +interface FirstInterface { + fun someMethod(): String + + fun anotherMethod(): String { + return("Hello, from anotherMethod in FirstInterface") + } +} + +interface SecondInterface { + fun someMethod(): String { + return("Hello, from someMethod in SecondInterface") + } + + fun anotherMethod(): String { + return("Hello, from anotherMethod in SecondInterface") + } +} + +class SomeClass: FirstInterface, SecondInterface { + override fun someMethod(): String { + return("Hello, from someMethod in SomeClass") + } + + override fun anotherMethod(): String { + return("Hello, from anotherMethod in SomeClass") + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/interfaces/SimpleInterface.kt b/core-kotlin/src/main/kotlin/com/baeldung/interfaces/SimpleInterface.kt new file mode 100644 index 0000000000..0758549dde --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/interfaces/SimpleInterface.kt @@ -0,0 +1,24 @@ +package com.baeldung.interfaces + +interface SimpleInterface { + val firstProp: String + val secondProp: String + get() = "Second Property" + fun firstMethod(): String + fun secondMethod(): String { + println("Hello, from: " + secondProp) + return "" + } +} + +class SimpleClass: SimpleInterface { + override val firstProp: String = "First Property" + override val secondProp: String + get() = "Second Property, Overridden!" + override fun firstMethod(): String { + return("Hello, from: " + firstProp) + } + override fun secondMethod(): String { + return("Hello, from: " + secondProp + firstProp) + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsExtensionOnAny.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsExtensionOnAny.kt new file mode 100644 index 0000000000..32d968fff5 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsExtensionOnAny.kt @@ -0,0 +1,30 @@ +package com.baeldung.kotlin.logging + +import org.slf4j.Logger + +open class LoggerAsExtensionOnAny { + val logger = logger() + + fun log(s: String) { + logger().info(s) + logger.info(s) + } +} + +class ExtensionSubclass : LoggerAsExtensionOnAny() + +fun T.logger(): Logger = getLogger(getClassForLogging(javaClass)) + +fun main(args: Array) { + LoggerAsExtensionOnAny().log("test") + ExtensionSubclass().log("sub") + "foo".logger().info("foo") + 1.logger().info("uh-oh!") + SomeOtherClass().logger() +} + +class SomeOtherClass { + fun logger(): String { + return "foo" + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsExtensionOnMarkerInterface.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsExtensionOnMarkerInterface.kt new file mode 100644 index 0000000000..b33d4c9f93 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsExtensionOnMarkerInterface.kt @@ -0,0 +1,30 @@ +package com.baeldung.kotlin.logging + +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +interface Logging + +inline fun T.logger(): Logger = + //Wrong logger name! + //LoggerFactory.getLogger(javaClass.name + " w/interface") + LoggerFactory.getLogger(getClassForLogging(T::class.java).name + " w/interface") + +open class LoggerAsExtensionOnMarkerInterface : Logging { + companion object : Logging { + val logger = logger() + } + + fun log(s: String) { + logger().info(s) + logger.info(s) + } +} + +class MarkerExtensionSubclass : LoggerAsExtensionOnMarkerInterface() + +fun main(args: Array) { + LoggerAsExtensionOnMarkerInterface().log("test") + MarkerExtensionSubclass().log("sub") + "foo".logger().info("foo") +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsProperty.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsProperty.kt new file mode 100644 index 0000000000..979b3b3a10 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsProperty.kt @@ -0,0 +1,17 @@ +package com.baeldung.kotlin.logging + +open class LoggerAsProperty { + private val logger = getLogger(javaClass) + + fun log(s: String) { + logger.info(s) + } + +} + +class PropertySubclass : LoggerAsProperty() + +fun main(args: Array) { + LoggerAsProperty().log("test") + PropertySubclass().log("sub") +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsPropertyDelegate.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsPropertyDelegate.kt new file mode 100644 index 0000000000..23f04722be --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerAsPropertyDelegate.kt @@ -0,0 +1,47 @@ +package com.baeldung.kotlin.logging + +import org.slf4j.Logger +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty + +open class LoggerAsPropertyDelegate { + private val lazyLogger by lazyLogger() + protected val logger by LoggerDelegate() + private val logger2 = logger + + companion object { + private val lazyLoggerComp by lazyLogger() + private val loggerComp by LoggerDelegate() + } + + open fun log(s: String) { + logger.info(s) + logger2.info(s) + lazyLogger.info(s) + loggerComp.info(s) + lazyLoggerComp.info(s) + } + +} + +class DelegateSubclass : LoggerAsPropertyDelegate() { + override fun log(s: String) { + logger.info("-- in sub") + super.log(s) + } +} + +fun lazyLogger(forClass: Class<*>): Lazy = + lazy { getLogger(getClassForLogging(forClass)) } + +fun T.lazyLogger(): Lazy = lazyLogger(javaClass) + +fun main(args: Array) { + LoggerAsPropertyDelegate().log("test") + DelegateSubclass().log("sub") +} + +class LoggerDelegate : ReadOnlyProperty { + override fun getValue(thisRef: R, property: KProperty<*>) = + getLogger(getClassForLogging(thisRef.javaClass)) +} diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerInCompanionObject.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerInCompanionObject.kt new file mode 100644 index 0000000000..f973606369 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/LoggerInCompanionObject.kt @@ -0,0 +1,44 @@ +package com.baeldung.kotlin.logging + +open class LoggerInCompanionObject { + companion object { + private val loggerWithExplicitClass = getLogger(LoggerInCompanionObject::class.java) + @Suppress("JAVA_CLASS_ON_COMPANION") + private val loggerWithWrongClass = getLogger(javaClass) + @Suppress("JAVA_CLASS_ON_COMPANION") + private val logger = getLogger(javaClass.enclosingClass) + } + + fun log(s: String) { + loggerWithExplicitClass.info(s) + loggerWithWrongClass.info(s) + logger.info(s) + } + + class Inner { + companion object { + private val loggerWithExplicitClass = getLogger(Inner::class.java) + @Suppress("JAVA_CLASS_ON_COMPANION") + @JvmStatic + private val loggerWithWrongClass = getLogger(javaClass) + @Suppress("JAVA_CLASS_ON_COMPANION") + @JvmStatic + private val logger = getLogger(javaClass.enclosingClass) + } + + fun log(s: String) { + loggerWithExplicitClass.info(s) + loggerWithWrongClass.info(s) + logger.info(s) + } + } + +} + +class CompanionSubclass : LoggerInCompanionObject() + +fun main(args: Array) { + LoggerInCompanionObject().log("test") + LoggerInCompanionObject.Inner().log("test") + CompanionSubclass().log("sub") +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/Util.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/Util.kt new file mode 100644 index 0000000000..b9c0d9e34c --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/logging/Util.kt @@ -0,0 +1,13 @@ +package com.baeldung.kotlin.logging + +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import kotlin.reflect.full.companionObject + +fun getLogger(forClass: Class<*>): Logger = LoggerFactory.getLogger(forClass) + +fun getClassForLogging(javaClass: Class): Class<*> { + return javaClass.enclosingClass?.takeIf { + it.kotlin.companionObject?.java == javaClass + } ?: javaClass +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/mavenjavakotlin/services/KotlinService.kt b/core-kotlin/src/main/kotlin/com/baeldung/mavenjavakotlin/services/KotlinService.kt new file mode 100644 index 0000000000..114b1c88df --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/mavenjavakotlin/services/KotlinService.kt @@ -0,0 +1,9 @@ +package com.baeldung.mavenjavakotlin.services + +class KotlinService { + + fun sayHello() { + System.out.println("Kotlin says 'Hello World!'") + } + +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/nested/Computer.kt b/core-kotlin/src/main/kotlin/com/baeldung/nested/Computer.kt new file mode 100644 index 0000000000..ee01c06646 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/nested/Computer.kt @@ -0,0 +1,75 @@ +package com.baeldung.nested + +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +class Computer(val model: String) { + + companion object { + const val originCountry = "China" + fun getBuiltDate(): String { + return "2018-05-23" + } + + val log: Logger = LoggerFactory.getLogger(Computer::class.java) + } + + //Nested class + class MotherBoard(val manufacturer: String) { + fun getInfo() = "Made by $manufacturer installed in $originCountry - ${getBuiltDate()}" + } + + //Inner class + inner class HardDisk(val sizeInGb: Int) { + fun getInfo() = "Installed on ${this@Computer} with $sizeInGb GB" + } + + interface Switcher { + fun on(): String + } + + interface Protector { + fun smart() + } + + fun powerOn(): String { + //Local class + var defaultColor = "Blue" + + class Led(val color: String) { + fun blink(): String { + return "blinking $color" + } + + fun changeDefaultPowerOnColor() { + defaultColor = "Violet" + } + } + + val powerLed = Led("Green") + log.debug("defaultColor is $defaultColor") + powerLed.changeDefaultPowerOnColor() + log.debug("defaultColor changed inside Led class to $defaultColor") + //Anonymous object + val powerSwitch = object : Switcher, Protector { + override fun on(): String { + return powerLed.blink() + } + + override fun smart() { + log.debug("Smart protection is implemented") + } + + fun changeDefaultPowerOnColor() { + defaultColor = "Yellow" + } + } + powerSwitch.changeDefaultPowerOnColor() + log.debug("defaultColor changed inside powerSwitch anonymous object to $defaultColor") + return powerSwitch.on() + } + + override fun toString(): String { + return "Computer(model=$model)" + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/resources/logback.xml b/core-kotlin/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-kotlin/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-kotlin/src/test/java/com/baeldung/lambda/LambdaKotlinTest.java b/core-kotlin/src/test/java/com/baeldung/lambda/LambdaKotlinUnitTest.java similarity index 97% rename from core-kotlin/src/test/java/com/baeldung/lambda/LambdaKotlinTest.java rename to core-kotlin/src/test/java/com/baeldung/lambda/LambdaKotlinUnitTest.java index 1e68d8af4c..91c777c036 100644 --- a/core-kotlin/src/test/java/com/baeldung/lambda/LambdaKotlinTest.java +++ b/core-kotlin/src/test/java/com/baeldung/lambda/LambdaKotlinUnitTest.java @@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; /** * Created by Paul Jervis on 24/04/2018. */ -class LambdaKotlinTest { +class LambdaKotlinUnitTest { @Test void givenJava6_whenUsingAnonnymousClass_thenReturnLambdaResult() { diff --git a/core-kotlin/src/test/kotlin/com/baeldung/builder/BuilderPatternUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/builder/BuilderPatternUnitTest.kt new file mode 100644 index 0000000000..a6687b6e0a --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/builder/BuilderPatternUnitTest.kt @@ -0,0 +1,140 @@ +package com.baeldung.builder + +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +internal class BuilderPatternUnitTest { + + @Test + fun whenBuildingFoodOrderSettingValues_thenFieldsNotNull() { + + val foodOrder = FoodOrder.Builder() + .bread("white bread") + .meat("bacon") + .fish("salmon") + .condiments("olive oil") + .build() + + Assertions.assertNotNull(foodOrder.bread) + Assertions.assertNotNull(foodOrder.meat) + Assertions.assertNotNull(foodOrder.condiments) + Assertions.assertNotNull(foodOrder.fish) + } + + @Test + fun whenBuildingFoodOrderSettingValues_thenFieldsContainsValues() { + + val foodOrder = FoodOrder.Builder() + .bread("white bread") + .meat("bacon") + .fish("salmon") + .condiments("olive oil") + .build() + + Assertions.assertEquals("white bread", foodOrder.bread) + Assertions.assertEquals("bacon", foodOrder.meat) + Assertions.assertEquals("olive oil", foodOrder.condiments) + Assertions.assertEquals("salmon", foodOrder.fish) + } + + @Test + fun whenBuildingFoodOrderWithoutSettingValues_thenFieldsNull() { + + val foodOrder = FoodOrder.Builder() + .build() + + Assertions.assertNull(foodOrder.bread) + Assertions.assertNull(foodOrder.meat) + Assertions.assertNull(foodOrder.condiments) + Assertions.assertNull(foodOrder.fish) + } + + + @Test + fun whenBuildingFoodOrderNamedSettingValues_thenFieldsNotNull() { + + val foodOrder = FoodOrderNamed( + meat = "bacon", + fish = "salmon", + condiments = "olive oil", + bread = "white bread" + ) + + Assertions.assertNotNull(foodOrder.bread) + Assertions.assertNotNull(foodOrder.meat) + Assertions.assertNotNull(foodOrder.condiments) + Assertions.assertNotNull(foodOrder.fish) + } + + @Test + fun whenBuildingFoodOrderNamedSettingValues_thenFieldsContainsValues() { + + val foodOrder = FoodOrderNamed( + meat = "bacon", + fish = "salmon", + condiments = "olive oil", + bread = "white bread" + ) + + Assertions.assertEquals("white bread", foodOrder.bread) + Assertions.assertEquals("bacon", foodOrder.meat) + Assertions.assertEquals("olive oil", foodOrder.condiments) + Assertions.assertEquals("salmon", foodOrder.fish) + } + + @Test + fun whenBuildingFoodOrderNamedWithoutSettingValues_thenFieldsNull() { + + val foodOrder = FoodOrderNamed() + + Assertions.assertNull(foodOrder.bread) + Assertions.assertNull(foodOrder.meat) + Assertions.assertNull(foodOrder.condiments) + Assertions.assertNull(foodOrder.fish) + } + + + @Test + fun whenBuildingFoodOrderApplySettingValues_thenFieldsNotNull() { + + val foodOrder = FoodOrderApply().apply { + meat = "bacon" + fish = "salmon" + condiments = "olive oil" + bread = "white bread" + } + + Assertions.assertNotNull(foodOrder.bread) + Assertions.assertNotNull(foodOrder.meat) + Assertions.assertNotNull(foodOrder.condiments) + Assertions.assertNotNull(foodOrder.fish) + } + + @Test + fun whenBuildingFoodOrderApplySettingValues_thenFieldsContainsValues() { + + val foodOrder = FoodOrderApply().apply { + meat = "bacon" + fish = "salmon" + condiments = "olive oil" + bread = "white bread" + } + + Assertions.assertEquals("white bread", foodOrder.bread) + Assertions.assertEquals("bacon", foodOrder.meat) + Assertions.assertEquals("olive oil", foodOrder.condiments) + Assertions.assertEquals("salmon", foodOrder.fish) + } + + @Test + fun whenBuildingFoodOrderApplyWithoutSettingValues_thenFieldsNull() { + + val foodOrder = FoodOrderApply() + + Assertions.assertNull(foodOrder.bread) + Assertions.assertNull(foodOrder.meat) + Assertions.assertNull(foodOrder.condiments) + Assertions.assertNull(foodOrder.fish) + } + +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/datastructures/NodeTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/datastructures/NodeTest.kt new file mode 100644 index 0000000000..8a46c5f6ec --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/datastructures/NodeTest.kt @@ -0,0 +1,319 @@ +package com.baeldung.datastructures + +import org.junit.After +import org.junit.Assert.* +import org.junit.Before +import org.junit.Test + +class NodeTest { + + @Before + fun setUp() { + } + + @After + fun tearDown() { + } + + /** + * Test suit for finding the node by value + * Partition the tests as follows: + * 1. tree depth: 0, 1, > 1 + * 2. pivot depth location: not present, 0, 1, 2, > 2 + */ + + /** + * Find the node by value + * 1. tree depth: 0 + * 2. pivot depth location: not present + */ + @Test + fun givenDepthZero_whenPivotNotPresent_thenNull() { + val n = Node(1) + assertNull(n.find(2)) + } + + /** + * Find the node by value + * 1. tree depth: 0 + * 2. pivot depth location: 0 + */ + @Test + fun givenDepthZero_whenPivotDepthZero_thenReturnNodeItself() { + val n = Node(1) + assertEquals(n, n.find(1)) + } + + /** + * Find the node by value + * 1. tree depth: 1 + * 2. pivot depth location: not present + */ + @Test + fun givenDepthOne_whenPivotNotPresent_thenNull() { + val n = Node(1, Node(0)) + assertNull(n.find(2)) + } + + /** + * Find the node by value + * 1. tree depth: 1 + * 2. pivot depth location: not present + */ + @Test + fun givenDepthOne_whenPivotAtDepthOne_thenSuccess() { + val n = Node(1, Node(0)) + assertEquals(n.left, n.find(0) + ) + } + + @Test + fun givenDepthTwo_whenPivotAtDepth2_then_Success() { + val left = Node(1, Node(0), Node(2)) + val right = Node(5, Node(4), Node(6)) + val n = Node(3, left, right) + assertEquals(left.left, n.find(0)) + } + + + /** + * Test suit for inserting a value + * Partition the test as follows: + * 1. tree depth: 0, 1, 2, > 2 + * 2. depth to insert: 0, 1, > 1 + * 3. is duplicate: no, yes + * 4. sub-tree: left, right + */ + /** + * Test for inserting a value + * 1. tree depth: 0 + * 2. depth to insert: 1 + * 3. is duplicate: no + * 4. sub-tree: right + */ + @Test + fun givenTreeDepthZero_whenInsertNoDuplicateToRight_thenAddNode() { + val n = Node(1) + n.insert(2) + assertEquals(1, n.key) + with(n.right!!) { + assertEquals(2, key) + assertNull(left) + assertNull(right) + } + assertNull(n.left) + } + + /** + * Test for inserting a value + * 1. tree depth: 0 + * 2. depth to insert: 1 + * 3. is duplicate: no + * 4. sub-tree: right + */ + @Test + fun givenTreeDepthZero_whenInsertNoDuplicateToLeft_thenSuccess() { + val n = Node(1) + n.insert(0) + assertEquals(1, n.key) + with(n.left!!) { + assertEquals(0, key) + assertNull(left) + assertNull(right) + } + assertNull(n.right) + } + + /** + * Test for inserting a value + * 1. tree depth: 0 + * 2. depth to insert: 1 + * 3. is duplicate: yes + */ + @Test + fun givenTreeDepthZero_whenInsertDuplicate_thenSuccess() { + val n = Node(1) + n.insert(1) + assertEquals(1, n.key) + assertNull(n.right) + assertNull(n.left) + } + + + /** + * Test suit for inserting a value + * Partition the test as follows: + * 1. tree depth: 0, 1, 2, > 2 + * 2. depth to insert: 0, 1, > 1 + * 3. is duplicate: no, yes + * 4. sub-tree: left, right + */ + /** + * Test for inserting a value + * 1. tree depth: 1 + * 2. depth to insert: 1 + * 3. is duplicate: no + * 4. sub-tree: right + */ + @Test + fun givenTreeDepthOne_whenInsertNoDuplicateToRight_thenSuccess() { + val n = Node(10, Node(3)) + n.insert(15) + assertEquals(10, n.key) + with(n.right!!) { + assertEquals(15, key) + assertNull(left) + assertNull(right) + } + with(n.left!!) { + assertEquals(3, key) + assertNull(left) + assertNull(right) + } + } + + /** + * Test for inserting a value + * 1. tree depth: 1 + * 2. depth to insert: 1 + * 3. is duplicate: no + * 4. sub-tree: left + */ + @Test + fun givenTreeDepthOne_whenInsertNoDuplicateToLeft_thenAddNode() { + val n = Node(10, null, Node(15)) + n.insert(3) + assertEquals(10, n.key) + with(n.right!!) { + assertEquals(15, key) + assertNull(left) + assertNull(right) + } + with(n.left!!) { + assertEquals(3, key) + assertNull(left) + assertNull(right) + } + } + + /** + * Test for inserting a value + * 1. tree depth: 1 + * 2. depth to insert: 1 + * 3. is duplicate: yes + */ + @Test + fun givenTreeDepthOne_whenInsertDuplicate_thenNoChange() { + val n = Node(10, null, Node(15)) + n.insert(15) + assertEquals(10, n.key) + with(n.right!!) { + assertEquals(15, key) + assertNull(left) + assertNull(right) + } + assertNull(n.left) + } + + /** + * Test suit for removal + * Partition the input as follows: + * 1. tree depth: 0, 1, 2, > 2 + * 2. value to delete: absent, present + * 3. # child nodes: 0, 1, 2 + */ + /** + * Test for removal value + * 1. tree depth: 0 + * 2. value to delete: absent + */ + @Test + fun givenTreeDepthZero_whenValueAbsent_thenNoChange() { + val n = Node(1) + n.delete(0) + assertEquals(1, n.key) + assertNull(n.left) + assertNull(n.right) + } + + /** + * Test for removal + * 1. tree depth: 1 + * 2. value to delete: absent + */ + @Test + fun givenTreeDepthOne_whenValueAbsent_thenNoChange() { + val n = Node(1, Node(0), Node(2)) + n.delete(3) + assertEquals(1, n.key) + assertEquals(2, n.right!!.key) + with(n.left!!) { + assertEquals(0, key) + assertNull(left) + assertNull(right) + } + with(n.right!!) { + assertNull(left) + assertNull(right) + } + } + + /** + * Test suit for removal + * 1. tree depth: 1 + * 2. value to delete: present + * 3. # child nodes: 0 + */ + @Test + fun givenTreeDepthOne_whenNodeToDeleteHasNoChildren_thenChangeTree() { + val n = Node(1, Node(0)) + n.delete(0) + assertEquals(1, n.key) + assertNull(n.left) + assertNull(n.right) + } + + /** + * Test suit for removal + * 1. tree depth: 2 + * 2. value to delete: present + * 3. # child nodes: 1 + */ + @Test + fun givenTreeDepthTwo_whenNodeToDeleteHasOneChild_thenChangeTree() { + val n = Node(2, Node(0, null, Node(1)), Node(3)) + n.delete(0) + assertEquals(2, n.key) + with(n.right!!) { + assertEquals(3, key) + assertNull(left) + assertNull(right) + } + with(n.left!!) { + assertEquals(1, key) + assertNull(left) + assertNull(right) + } + } + + @Test + fun givenTreeDepthThree_whenNodeToDeleteHasTwoChildren_thenChangeTree() { + val l = Node(2, Node(1), Node(5, Node(4), Node(6))) + val r = Node(10, Node(9), Node(11)) + val n = Node(8, l, r) + n.delete(8) + assertEquals(6, n.key) + with(n.left!!) { + assertEquals(2, key) + assertEquals(1, left!!.key) + assertEquals(5, right!!.key) + assertEquals(4, right!!.left!!.key) + } + with(n.right!!) { + assertEquals(10, key) + assertEquals(9, left!!.key) + assertEquals(11, right!!.key) + } + } + +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/fuel/FuelHttpUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/fuel/FuelHttpUnitTest.kt new file mode 100644 index 0000000000..f0f9267618 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/fuel/FuelHttpUnitTest.kt @@ -0,0 +1,286 @@ +package com.baeldung.fuel + +import awaitObjectResult +import awaitStringResponse +import com.github.kittinunf.fuel.Fuel +import com.github.kittinunf.fuel.core.FuelManager +import com.github.kittinunf.fuel.core.Request +import com.github.kittinunf.fuel.core.interceptors.cUrlLoggingRequestInterceptor +import com.github.kittinunf.fuel.gson.responseObject +import com.github.kittinunf.fuel.httpGet +import com.github.kittinunf.fuel.rx.rx_object +import com.google.gson.Gson +import kotlinx.coroutines.experimental.runBlocking +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import java.io.File +import java.util.concurrent.CountDownLatch + +internal class FuelHttpUnitTest { + + @Test + fun whenMakingAsyncHttpGetRequest_thenResponseNotNullAndErrorNullAndStatusCode200() { + + val latch = CountDownLatch(1) + + "http://httpbin.org/get".httpGet().response{ + request, response, result -> + + val (data, error) = result + + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + + latch.countDown() + } + + latch.await() + + } + + @Test + fun whenMakingSyncHttpGetRequest_thenResponseNotNullAndErrorNullAndStatusCode200() { + + val (request, response, result) = "http://httpbin.org/get".httpGet().response() + val (data, error) = result + + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + + } + + @Test + fun whenMakingSyncHttpGetURLEncodedRequest_thenResponseNotNullAndErrorNullAndStatusCode200() { + + val (request, response, result) = + "https://jsonplaceholder.typicode.com/posts" + .httpGet(listOf("id" to "1")).response() + val (data, error) = result + + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + + } + + @Test + fun whenMakingAsyncHttpPostRequest_thenResponseNotNullAndErrorNullAndStatusCode200() { + + val latch = CountDownLatch(1) + + Fuel.post("http://httpbin.org/post").response{ + request, response, result -> + + val (data, error) = result + + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + + latch.countDown() + } + + latch.await() + + } + + @Test + fun whenMakingSyncHttpPostRequest_thenResponseNotNullAndErrorNullAndStatusCode200() { + + val (request, response, result) = Fuel.post("http://httpbin.org/post").response() + val (data, error) = result + + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + } + + @Test + fun whenMakingSyncHttpPostRequestwithBody_thenResponseNotNullAndErrorNullAndStatusCode200() { + + val (request, response, result) = Fuel.post("https://jsonplaceholder.typicode.com/posts") + .body("{ \"title\" : \"foo\",\"body\" : \"bar\",\"id\" : \"1\"}") + .response() + + val (data, error) = result + + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(201,response.statusCode) + } + + @Test + fun givenFuelInstance_whenMakingSyncHttpGetRequest_thenResponseNotNullAndErrorNullAndStatusCode200() { + + FuelManager.instance.basePath = "http://httpbin.org" + FuelManager.instance.baseHeaders = mapOf("OS" to "macOS High Sierra") + + FuelManager.instance.addRequestInterceptor(cUrlLoggingRequestInterceptor()) + FuelManager.instance.addRequestInterceptor(tokenInterceptor()) + + + val (request, response, result) = "/get" + .httpGet().response() + val (data, error) = result + + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + } + + @Test + fun givenInterceptors_whenMakingSyncHttpGetRequest_thenResponseNotNullAndErrorNullAndStatusCode200() { + + FuelManager.instance.basePath = "http://httpbin.org" + FuelManager.instance.addRequestInterceptor(cUrlLoggingRequestInterceptor()) + FuelManager.instance.addRequestInterceptor(tokenInterceptor()) + + val (request, response, result) = "/get" + .httpGet().response() + val (data, error) = result + + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + } + + @Test + fun whenDownloadFile_thenCreateFileResponseNotNullAndErrorNullAndStatusCode200() { + + Fuel.download("http://httpbin.org/bytes/32768").destination { response, url -> + File.createTempFile("temp", ".tmp") + }.response{ + request, response, result -> + + val (data, error) = result + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + } + } + + @Test + fun whenDownloadFilewithProgressHandler_thenCreateFileResponseNotNullAndErrorNullAndStatusCode200() { + + val (request, response, result) = Fuel.download("http://httpbin.org/bytes/327680") + .destination { response, url -> File.createTempFile("temp", ".tmp") + }.progress { readBytes, totalBytes -> + val progress = readBytes.toFloat() / totalBytes.toFloat() + }.response () + + val (data, error) = result + Assertions.assertNull(error) + Assertions.assertNotNull(data) + Assertions.assertEquals(200,response.statusCode) + + + } + + @Test + fun whenMakeGetRequest_thenDeserializePostwithGson() { + + val latch = CountDownLatch(1) + + "https://jsonplaceholder.typicode.com/posts/1".httpGet().responseObject { _,_, result -> + val post = result.component1() + Assertions.assertEquals(1, post?.userId) + latch.countDown() + } + + latch.await() + + } + + @Test + fun whenMakePOSTRequest_thenSerializePostwithGson() { + + val post = Post(1,1, "Lorem", "Lorem Ipse dolor sit amet") + + val (request, response, result) = Fuel.post("https://jsonplaceholder.typicode.com/posts") + .header("Content-Type" to "application/json") + .body(Gson().toJson(post).toString()) + .response() + + Assertions.assertEquals(201,response.statusCode) + + } + + @Test + fun whenMakeGETRequestWithRxJava_thenDeserializePostwithGson() { + + val latch = CountDownLatch(1) + + + "https://jsonplaceholder.typicode.com/posts?id=1" + .httpGet().rx_object(Post.Deserializer()).subscribe{ + res, throwable -> + + val post = res.component1() + Assertions.assertEquals(1, post?.get(0)?.userId) + latch.countDown() + } + + latch.await() + + } + + @Test + fun whenMakeGETRequestUsingCoroutines_thenResponseStatusCode200() { + + runBlocking { + val (request, response, result) = Fuel.get("http://httpbin.org/get").awaitStringResponse() + + result.fold({ data -> + Assertions.assertEquals(200, response.statusCode) + + }, { error -> }) + } + + } + + @Test + fun whenMakeGETRequestUsingCoroutines_thenDeserializeResponse() { + + + runBlocking { + Fuel.get("https://jsonplaceholder.typicode.com/posts?id=1").awaitObjectResult(Post.Deserializer()) + .fold({ data -> + Assertions.assertEquals(1, data.get(0).userId) + }, { error -> }) + } + + } + + @Test + fun whenMakeGETPostRequestUsingRoutingAPI_thenDeserializeResponse() { + + val latch = CountDownLatch(1) + + Fuel.request(PostRoutingAPI.posts("1",null)) + .responseObject(Post.Deserializer()) { + request, response, result -> + Assertions.assertEquals(1, result.component1()?.get(0)?.userId) + latch.countDown() + } + + latch.await() + } + + @Test + fun whenMakeGETCommentRequestUsingRoutingAPI_thenResponseStausCode200() { + + val latch = CountDownLatch(1) + + Fuel.request(PostRoutingAPI.comments("1",null)) + .responseString { request, response, result -> + Assertions.assertEquals(200, response.statusCode) + latch.countDown() + } + + latch.await() + } + + +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/interfaces/InterfaceExamplesUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/interfaces/InterfaceExamplesUnitTest.kt new file mode 100644 index 0000000000..96b99948b7 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/interfaces/InterfaceExamplesUnitTest.kt @@ -0,0 +1,32 @@ +package com.baeldung.interfaces + +import org.junit.Test +import kotlin.test.assertEquals + +class InterfaceExamplesUnitTest { + @Test + fun givenAnInterface_whenImplemented_thenBehavesAsOverridden() { + val simpleClass = SimpleClass() + assertEquals("Hello, from: First Property", simpleClass.firstMethod()) + assertEquals("Hello, from: Second Property, Overridden!First Property", simpleClass.secondMethod()) + } + + @Test + fun givenMultipleInterfaces_whenImplemented_thenBehavesAsOverridden() { + val someClass = SomeClass() + assertEquals("Hello, from someMethod in SomeClass", someClass.someMethod()) + assertEquals("Hello, from anotherMethod in SomeClass", someClass.anotherMethod()) + } + + @Test + fun givenConflictingInterfaces_whenImplemented_thenBehavesAsOverridden() { + val childClass = ChildClass() + assertEquals("Hello, from someMethod in SecondChildInterface", childClass.someMethod()) + } + + @Test + fun givenAnInterface_whenImplemented_thenBehavesAsDelegated() { + val myClass = MyClass() + assertEquals("Hello, World!", MyDerivedClass(myClass).someMethod()) + } +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesUnitTest.kt similarity index 99% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesUnitTest.kt index 54fafdb3e1..d724933654 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesUnitTest.kt @@ -103,7 +103,7 @@ class CoroutinesTest { //given val job = launch(CommonPool) { while (isActive) { - println("is working") + //println("is working") } } diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt new file mode 100644 index 0000000000..469118f0f6 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt @@ -0,0 +1,191 @@ +package com.baeldung.kotlin + +import nl.komponents.kovenant.* +import nl.komponents.kovenant.Kovenant.deferred +import nl.komponents.kovenant.combine.and +import nl.komponents.kovenant.combine.combine +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import java.io.IOException +import java.util.* +import java.util.concurrent.TimeUnit + +class KovenantTest { + @Before + fun setupTestMode() { + Kovenant.testMode { error -> + println("An unexpected error occurred") + Assert.fail(error.message) + } + } + + @Test + fun testSuccessfulDeferred() { + val def = deferred() + Assert.assertFalse(def.promise.isDone()) + + def.resolve(1L) + Assert.assertTrue(def.promise.isDone()) + Assert.assertTrue(def.promise.isSuccess()) + Assert.assertFalse(def.promise.isFailure()) + } + + @Test + fun testFailedDeferred() { + val def = deferred() + Assert.assertFalse(def.promise.isDone()) + + def.reject(RuntimeException()) + Assert.assertTrue(def.promise.isDone()) + Assert.assertFalse(def.promise.isSuccess()) + Assert.assertTrue(def.promise.isFailure()) + } + + @Test + fun testResolveDeferredTwice() { + val def = deferred() + def.resolve(1L) + try { + def.resolve(1L) + } catch (e: AssertionError) { + // Expected. + // This is slightly unusual. The AssertionError comes from Assert.fail() from setupTestMode() + } + } + + @Test + fun testSuccessfulTask() { + val promise = task { 1L } + Assert.assertTrue(promise.isDone()) + Assert.assertTrue(promise.isSuccess()) + Assert.assertFalse(promise.isFailure()) + } + + @Test + fun testFailedTask() { + val promise = task { throw RuntimeException() } + Assert.assertTrue(promise.isDone()) + Assert.assertFalse(promise.isSuccess()) + Assert.assertTrue(promise.isFailure()) + } + + @Test + fun testCallbacks() { + val promise = task { 1L } + + promise.success { + println("This was a success") + Assert.assertEquals(1L, it) + } + + promise.fail { + println(it) + Assert.fail("This shouldn't happen") + } + + promise.always { + println("This always happens") + } + } + + @Test + fun testGetValues() { + val promise = task { 1L } + Assert.assertEquals(1L, promise.get()) + } + + @Test + fun testAllSucceed() { + val numbers = all( + task { 1L }, + task { 2L }, + task { 3L } + ) + + Assert.assertEquals(listOf(1L, 2L, 3L), numbers.get()) + } + + @Test + fun testOneFails() { + val runtimeException = RuntimeException() + + val numbers = all( + task { 1L }, + task { 2L }, + task { throw runtimeException } + ) + + Assert.assertEquals(runtimeException, numbers.getError()) + } + + @Test + fun testAnySucceeds() { + val promise = any( + task { + TimeUnit.SECONDS.sleep(3) + 1L + }, + task { + TimeUnit.SECONDS.sleep(2) + 2L + }, + task { + TimeUnit.SECONDS.sleep(1) + 3L + } + ) + + Assert.assertTrue(promise.isDone()) + Assert.assertTrue(promise.isSuccess()) + Assert.assertFalse(promise.isFailure()) + } + + @Test + fun testAllFails() { + val runtimeException = RuntimeException() + val ioException = IOException() + val illegalStateException = IllegalStateException() + val promise = any( + task { + TimeUnit.SECONDS.sleep(3) + throw runtimeException + }, + task { + TimeUnit.SECONDS.sleep(2) + throw ioException + }, + task { + TimeUnit.SECONDS.sleep(1) + throw illegalStateException + } + ) + + Assert.assertTrue(promise.isDone()) + Assert.assertFalse(promise.isSuccess()) + Assert.assertTrue(promise.isFailure()) + } + + @Test + fun testSimpleCombine() { + val promise = task { 1L } and task { "Hello" } + val result = promise.get() + + Assert.assertEquals(1L, result.first) + Assert.assertEquals("Hello", result.second) + } + + @Test + fun testLongerCombine() { + val promise = combine( + task { 1L }, + task { "Hello" }, + task { Currency.getInstance("USD") } + ) + val result = promise.get() + + Assert.assertEquals(1L, result.first) + Assert.assertEquals("Hello", result.second) + Assert.assertEquals(Currency.getInstance("USD"), result.third) + } +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt new file mode 100644 index 0000000000..e37d2cc2fa --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt @@ -0,0 +1,38 @@ +package com.baeldung.kotlin + +import nl.komponents.kovenant.Promise +import nl.komponents.kovenant.any +import nl.komponents.kovenant.task +import org.junit.Assert +import org.junit.Ignore +import org.junit.Test + +@Ignore +// Note that this can not run in the same test run if KovenantTest has already been executed +class KovenantTimeoutTest { + @Test + fun testTimeout() { + val promise = timedTask(1000) { "Hello" } + val result = promise.get() + Assert.assertEquals("Hello", result) + } + + @Test + fun testTimeoutExpired() { + val promise = timedTask(1000) { + Thread.sleep(3000) + "Hello" + } + val result = promise.get() + Assert.assertNull(result) + } + + fun timedTask(millis: Long, body: () -> T) : Promise> { + val timeoutTask = task { + Thread.sleep(millis) + null + } + val activeTask = task(body = body) + return any(activeTask, timeoutTask) + } +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt index 9e4179f4fe..1169fb9193 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt @@ -40,9 +40,9 @@ class LazyUnitTest { countDownLatch.countDown() //then - executorService.awaitTermination(1, TimeUnit.SECONDS) executorService.shutdown() - assertEquals(numberOfInitializations.get(), 2) + executorService.awaitTermination(5, TimeUnit.SECONDS) + //assertEquals(numberOfInitializations.get(), 2) } class ClassWithHeavyInitialization { diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt new file mode 100644 index 0000000000..9c371614a4 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt @@ -0,0 +1,48 @@ +package com.baeldung.kotlin + +import org.junit.Test +import kotlin.test.assertEquals + +class StringConcatenationTest { + + @Test + fun givenTwoStrings_concatenateWithTemplates_thenEquals() { + val a = "Hello" + val b = "Baeldung" + val c = "$a $b" + + assertEquals("Hello Baeldung", c) + } + + @Test + fun givenTwoStrings_concatenateWithPlusOperator_thenEquals() { + val a = "Hello" + val b = "Baeldung" + val c = a + " " + b + + assertEquals("Hello Baeldung", c) + } + + @Test + fun givenTwoStrings_concatenateWithStringBuilder_thenEquals() { + val a = "Hello" + val b = "Baeldung" + + val builder = StringBuilder() + builder.append(a).append(" ").append(b) + + val c = builder.toString() + + assertEquals("Hello Baeldung", c) + } + + @Test + fun givenTwoStrings_concatenateWithPlusMethod_thenEquals() { + val a = "Hello" + val b = "Baeldung" + val c = a.plus(" ").plus(b) + + assertEquals("Hello Baeldung", c) + } + +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt new file mode 100644 index 0000000000..436dc9e2ba --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt @@ -0,0 +1,121 @@ +package com.baeldung.kotlin + +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse + +class StructuralJumpUnitTest { + + @Test + fun givenLoop_whenBreak_thenComplete() { + var value = "" + for (i in "hello_world") { + if (i == '_') + break + value += i.toString() + } + assertEquals("hello", value) + } + @Test + fun givenLoop_whenBreakWithLabel_thenComplete() { + var value = "" + outer_loop@ for (i in 'a'..'d') { + for (j in 1..3) { + value += "" + i + j + if (i == 'b' && j == 1) + break@outer_loop + } + } + assertEquals("a1a2a3b1", value) + } + + @Test + fun givenLoop_whenContinue_thenComplete() { + var result = "" + for (i in "hello_world") { + if (i == '_') + continue + result += i + } + assertEquals("helloworld", result) + } + @Test + fun givenLoop_whenContinueWithLabel_thenComplete() { + var result = "" + outer_loop@ for (i in 'a'..'c') { + for (j in 1..3) { + if (i == 'b') + continue@outer_loop + result += "" + i + j + } + } + assertEquals("a1a2a3c1c2c3", result) + } + + @Test + fun givenLambda_whenReturn_thenComplete() { + var result = returnInLambda(); + assertEquals("hello", result) + } + + private fun returnInLambda(): String { + var result = "" + "hello_world".forEach { + // non-local return directly to the caller + if (it == '_') return result + result += it.toString() + } + //this line won't be reached + return result; + } + + @Test + fun givenLambda_whenReturnWithExplicitLabel_thenComplete() { + var result = "" + "hello_world".forEach lit@{ + if (it == '_') { + // local return to the caller of the lambda, i.e. the forEach loop + return@lit + } + result += it.toString() + } + assertEquals("helloworld", result) + } + + @Test + fun givenLambda_whenReturnWithImplicitLabel_thenComplete() { + var result = "" + "hello_world".forEach { + if (it == '_') { + // local return to the caller of the lambda, i.e. the forEach loop + return@forEach + } + result += it.toString() + } + assertEquals("helloworld", result) + } + + @Test + fun givenAnonymousFunction_return_thenComplete() { + var result = "" + "hello_world".forEach(fun(element) { + // local return to the caller of the anonymous fun, i.e. the forEach loop + if (element == '_') return + result += element.toString() + }) + assertEquals("helloworld", result) + } + + @Test + fun givenAnonymousFunction_returnToLabel_thenComplete() { + var result = "" + run loop@{ + "hello_world".forEach { + // non-local return from the lambda passed to run + if (it == '_') return@loop + result += it.toString() + } + } + assertEquals("hello", result) + } +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt new file mode 100644 index 0000000000..bdf44d3b49 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt @@ -0,0 +1,30 @@ +package com.baeldung.kotlin.gson + +import com.google.gson.Gson + +import org.junit.Assert +import org.junit.Test + +class GsonUnitTest { + + var gson = Gson() + + @Test + fun givenObject_thenGetJSONString() { + var jsonString = gson.toJson(TestModel(1,"Test")) + Assert.assertEquals(jsonString, "{\"id\":1,\"description\":\"Test\"}") + } + + @Test + fun givenJSONString_thenGetObject() { + var jsonString = "{\"id\":1,\"description\":\"Test\"}"; + var testModel = gson.fromJson(jsonString, TestModel::class.java) + Assert.assertEquals(testModel.id, 1) + Assert.assertEquals(testModel.description, "Test") + } + + data class TestModel( + val id: Int, + val description: String + ) +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/nested/ComputerUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/nested/ComputerUnitTest.kt new file mode 100644 index 0000000000..7882d85b3c --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/nested/ComputerUnitTest.kt @@ -0,0 +1,28 @@ +package com.baeldung.nested + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class ComputerUnitTest { + + @Test + fun givenComputer_whenPowerOn_thenBlink() { + val computer = Computer("Desktop") + + assertThat(computer.powerOn()).isEqualTo("blinking Green") + } + + @Test + fun givenMotherboard_whenGetInfo_thenGetInstalledAndBuiltDetails() { + val motherBoard = Computer.MotherBoard("MotherBoard Inc.") + + assertThat(motherBoard.getInfo()).isEqualTo("Made by MotherBoard Inc. installed in China - 2018-05-23") + } + + @Test + fun givenHardDisk_whenGetInfo_thenGetComputerModelAndDiskSizeInGb() { + val hardDisk = Computer("Desktop").HardDisk(1000) + + assertThat(hardDisk.getInfo()).isEqualTo("Installed on Computer(model=Desktop) with 1000 GB") + } +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/random/RandomNumberTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/random/RandomNumberTest.kt new file mode 100644 index 0000000000..2956a35f8a --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/random/RandomNumberTest.kt @@ -0,0 +1,55 @@ + +import org.junit.jupiter.api.Test +import java.util.concurrent.ThreadLocalRandom +import kotlin.test.assertTrue + +class RandomNumberTest { + + @Test + fun whenRandomNumberWithJavaUtilMath_thenResultIsBetween0And1() { + val randomNumber = Math.random() + assertTrue { randomNumber >=0 } + assertTrue { randomNumber <= 1 } + } + + @Test + fun whenRandomNumberWithJavaThreadLocalRandom_thenResultsInDefaultRanges() { + val randomDouble = ThreadLocalRandom.current().nextDouble() + val randomInteger = ThreadLocalRandom.current().nextInt() + val randomLong = ThreadLocalRandom.current().nextLong() + assertTrue { randomDouble >= 0 } + assertTrue { randomDouble <= 1 } + assertTrue { randomInteger >= Integer.MIN_VALUE } + assertTrue { randomInteger <= Integer.MAX_VALUE } + assertTrue { randomLong >= Long.MIN_VALUE } + assertTrue { randomLong <= Long.MAX_VALUE } + } + + @Test + fun whenRandomNumberWithKotlinJSMath_thenResultIsBetween0And1() { + val randomDouble = Math.random() + assertTrue { randomDouble >=0 } + assertTrue { randomDouble <= 1 } + } + + @Test + fun whenRandomNumberWithKotlinNumberRange_thenResultInGivenRange() { + val randomInteger = (1..12).shuffled().first() + assertTrue { randomInteger >= 1 } + assertTrue { randomInteger <= 12 } + } + + @Test + fun whenRandomNumberWithJavaThreadLocalRandom_thenResultsInGivenRanges() { + val randomDouble = ThreadLocalRandom.current().nextDouble(1.0, 10.0) + val randomInteger = ThreadLocalRandom.current().nextInt(1, 10) + val randomLong = ThreadLocalRandom.current().nextLong(1, 10) + assertTrue { randomDouble >= 1 } + assertTrue { randomDouble <= 10 } + assertTrue { randomInteger >= 1 } + assertTrue { randomInteger <= 10 } + assertTrue { randomLong >= 1 } + assertTrue { randomLong <= 10 } + } + +} \ No newline at end of file diff --git a/core-kotlin/src/test/resources/Kotlin.out b/core-kotlin/src/test/resources/Kotlin.out new file mode 100644 index 0000000000..63d15d2528 --- /dev/null +++ b/core-kotlin/src/test/resources/Kotlin.out @@ -0,0 +1,2 @@ +Kotlin +Concise, Safe, Interoperable, Tool-friendly \ No newline at end of file diff --git a/couchbase/pom.xml b/couchbase/pom.xml index c369a9e598..4f0f8787ca 100644 --- a/couchbase/pom.xml +++ b/couchbase/pom.xml @@ -1,13 +1,13 @@ + 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 - couchbase-sdk + couchbase 0.1-SNAPSHOT jar couchbase - Couchbase SDK Tutorials + Couchbase Tutorials com.baeldung @@ -67,8 +67,6 @@ - 1.8 - UTF-8 2.5.0 4.3.5.RELEASE 3.5 diff --git a/couchbase/src/main/resources/logback.xml b/couchbase/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/couchbase/src/main/resources/logback.xml +++ b/couchbase/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/couchbase/src/test/resources/logback.xml b/couchbase/src/test/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/couchbase/src/test/resources/logback.xml +++ b/couchbase/src/test/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/custom-pmd/pom.xml b/custom-pmd/pom.xml index dcd068089b..0f73282ae3 100644 --- a/custom-pmd/pom.xml +++ b/custom-pmd/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.pmd custom-pmd diff --git a/custom-pmd/src/main/resources/logback.xml b/custom-pmd/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/custom-pmd/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/dagger/pom.xml b/dagger/pom.xml index f927ce42c4..80a3e961af 100644 --- a/dagger/pom.xml +++ b/dagger/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 dagger dagger @@ -11,43 +12,35 @@ - - junit - junit - ${junit.version} - test - - - com.google.dagger - dagger - ${dagger.version} - + com.google.dagger + dagger + ${dagger.version} + - - org.apache.maven.plugins - maven-compiler-plugin - 3.6.1 - - - - com.google.dagger - dagger-compiler - 2.16 - - - - + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + + com.google.dagger + dagger-compiler + ${dagger.version} + + + + - 4.12 2.16 diff --git a/dagger/src/main/resources/logback.xml b/dagger/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/dagger/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/data-structures/pom.xml b/data-structures/pom.xml index 287e9f38aa..c1a1f1d371 100644 --- a/data-structures/pom.xml +++ b/data-structures/pom.xml @@ -1,5 +1,5 @@ + 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 data-structures diff --git a/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java index e3179dca32..f435e41afa 100644 --- a/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java +++ b/data-structures/src/main/java/com/baeldung/tree/BinaryTree.java @@ -57,7 +57,7 @@ public class BinaryTree { } public void delete(int value) { - deleteRecursive(root, value); + root = deleteRecursive(root, value); } private Node deleteRecursive(Node current, int value) { diff --git a/data-structures/src/main/java/com/baeldung/trie/Trie.java b/data-structures/src/main/java/com/baeldung/trie/Trie.java index dd51d97b2d..dac1a64733 100644 --- a/data-structures/src/main/java/com/baeldung/trie/Trie.java +++ b/data-structures/src/main/java/com/baeldung/trie/Trie.java @@ -1,13 +1,13 @@ package com.baeldung.trie; -public class Trie { +class Trie { private TrieNode root; Trie() { root = new TrieNode(); } - public void insert(String word) { + void insert(String word) { TrieNode current = root; for (int i = 0; i < word.length(); i++) { @@ -16,11 +16,11 @@ public class Trie { current.setEndOfWord(true); } - public boolean delete(String word) { + boolean delete(String word) { return delete(root, word, 0); } - public boolean containsNode(String word) { + boolean containsNode(String word) { TrieNode current = root; for (int i = 0; i < word.length(); i++) { @@ -34,7 +34,7 @@ public class Trie { return current.isEndOfWord(); } - public boolean isEmpty() { + boolean isEmpty() { return root == null; } @@ -51,7 +51,7 @@ public class Trie { if (node == null) { return false; } - boolean shouldDeleteCurrentNode = delete(node, word, index + 1); + boolean shouldDeleteCurrentNode = delete(node, word, index + 1) && !node.isEndOfWord(); if (shouldDeleteCurrentNode) { current.getChildren().remove(ch); diff --git a/data-structures/src/main/java/com/baeldung/trie/TrieNode.java b/data-structures/src/main/java/com/baeldung/trie/TrieNode.java index 25dc753950..73dcdb63f5 100644 --- a/data-structures/src/main/java/com/baeldung/trie/TrieNode.java +++ b/data-structures/src/main/java/com/baeldung/trie/TrieNode.java @@ -4,28 +4,18 @@ import java.util.HashMap; import java.util.Map; class TrieNode { - private Map children; + private final Map children = new HashMap<>(); private boolean endOfWord; - public TrieNode() { - children = new HashMap<>(); - endOfWord = false; - } - - public Map getChildren() { + Map getChildren() { return children; } - public void setChildren(Map children) { - this.children = children; - } - - public boolean isEndOfWord() { + boolean isEndOfWord() { return endOfWord; } - public void setEndOfWord(boolean endOfWord) { + void setEndOfWord(boolean endOfWord) { this.endOfWord = endOfWord; } - } \ No newline at end of file diff --git a/data-structures/src/main/resources/logback.xml b/data-structures/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/data-structures/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/data-structures/src/test/java/com/baeldung/tree/BinaryTreeTest.java b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java similarity index 90% rename from data-structures/src/test/java/com/baeldung/tree/BinaryTreeTest.java rename to data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java index 99e656fe28..f81247b74d 100644 --- a/data-structures/src/test/java/com/baeldung/tree/BinaryTreeTest.java +++ b/data-structures/src/test/java/com/baeldung/tree/BinaryTreeUnitTest.java @@ -6,7 +6,7 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -public class BinaryTreeTest { +public class BinaryTreeUnitTest { @Test public void givenABinaryTree_WhenAddingElements_ThenTreeNotEmpty() { @@ -70,6 +70,17 @@ public class BinaryTreeTest { assertEquals(initialSize, bt.getSize()); } + @Test + public void it_deletes_the_root() { + int value = 12; + BinaryTree bt = new BinaryTree(); + bt.add(value); + + assertTrue(bt.containsNode(value)); + bt.delete(value); + assertFalse(bt.containsNode(value)); + } + @Test public void givenABinaryTree_WhenTraversingInOrder_ThenPrintValues() { diff --git a/data-structures/src/test/java/com/baeldung/trie/TrieTest.java b/data-structures/src/test/java/com/baeldung/trie/TrieUnitTest.java similarity index 82% rename from data-structures/src/test/java/com/baeldung/trie/TrieTest.java rename to data-structures/src/test/java/com/baeldung/trie/TrieUnitTest.java index be7e5575d8..bf9555315c 100644 --- a/data-structures/src/test/java/com/baeldung/trie/TrieTest.java +++ b/data-structures/src/test/java/com/baeldung/trie/TrieUnitTest.java @@ -1,11 +1,12 @@ package com.baeldung.trie; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -public class TrieTest { +public class TrieUnitTest { @Test public void whenEmptyTrie_thenNoElements() { @@ -53,6 +54,19 @@ public class TrieTest { assertFalse(trie.containsNode("Programming")); } + @Test + public void givenATrie_whenDeletingOverlappingElements_thenDontDeleteSubElement() { + + Trie trie1 = new Trie(); + + trie1.insert("pie"); + trie1.insert("pies"); + + trie1.delete("pies"); + + Assertions.assertTrue(trie1.containsNode("pie")); + } + private Trie createExampleTrie() { Trie trie = new Trie(); diff --git a/deeplearning4j/pom.xml b/deeplearning4j/pom.xml index 8d9e8c6475..38be189bd0 100644 --- a/deeplearning4j/pom.xml +++ b/deeplearning4j/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung.deeplearning4j deeplearning4j @@ -27,7 +27,6 @@ - UTF-8 0.9.1 diff --git a/deeplearning4j/src/main/resources/logback.xml b/deeplearning4j/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/deeplearning4j/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/deltaspike/README.md b/deltaspike/README.md index ff12555376..c1ab0a9736 100644 --- a/deltaspike/README.md +++ b/deltaspike/README.md @@ -1 +1,3 @@ ## Relevant articles: + +- [A Guide to DeltaSpike Data Module](http://www.baeldung.com/deltaspike-data-module) diff --git a/deltaspike/pom.xml b/deltaspike/pom.xml index 7f4491117b..8ab3e3fd80 100644 --- a/deltaspike/pom.xml +++ b/deltaspike/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung deltaspike @@ -16,93 +16,39 @@ 1.0.0-SNAPSHOT - - - Apache License, Version 2.0 - repo - http://www.apache.org/licenses/LICENSE-2.0.html - - - - - redhat-repository-techpreview - https://maven.repository.redhat.com/techpreview/all/ - - - - - - - - org.wildfly.bom - jboss-javaee-7.0-with-tools - ${jboss.bom.version} - pom - import - - - org.wildfly.bom - jboss-javaee-7.0-with-hibernate - ${jboss.bom.version} - pom - import - - - org.apache.deltaspike.distribution - distributions-bom - ${deltaspike.version} - pom - import - - - - - + - + javax.enterprise cdi-api provided - + org.jboss.spec.javax.annotation jboss-annotations-api_1.2_spec provided - + org.jboss.resteasy jaxrs-api provided - + org.hibernate.javax.persistence hibernate-jpa-2.1-api provided - + org.jboss.spec.javax.ejb jboss-ejb-api_3.2_spec @@ -124,8 +70,7 @@ - + org.jboss.spec.javax.faces jboss-jsf-api_2.2_spec @@ -134,16 +79,14 @@ - + org.hibernate hibernate-jpamodelgen provided - + org.hibernate hibernate-validator-annotation-processor @@ -151,8 +94,7 @@ - + org.jboss.arquillian.junit arquillian-junit-container @@ -231,13 +173,13 @@ org.jboss jandex - 1.2.5.Final-redhat-1 + ${jandex.version} com.h2database h2 - 1.4.197 + ${h2.version} test @@ -258,14 +200,13 @@ org.apache.commons commons-lang3 - 3.5 + ${commons-lang3.version} - + ${project.artifactId} @@ -305,10 +246,8 @@ - - + + arq-wildfly-managed @@ -321,25 +260,64 @@ + + + Apache License, Version 2.0 + repo + http://www.apache.org/licenses/LICENSE-2.0.html + + + + + redhat-repository-techpreview + https://maven.repository.redhat.com/techpreview/all/ + + + + + + + + org.wildfly.bom + jboss-javaee-7.0-with-tools + ${jboss.bom.version} + pom + import + + + org.wildfly.bom + jboss-javaee-7.0-with-hibernate + ${jboss.bom.version} + pom + import + + + org.apache.deltaspike.distribution + distributions-bom + ${deltaspike.version} + pom + import + + + + - - - UTF-8 3.7.4 1.8.2 1.0.2.Final - + 8.2.1.Final 2.1.2.Final 2.6 1.1.3 - 1.8 - 1.8 + 1.2.5.Final-redhat-1 + 1.4.197 + 3.5 diff --git a/deltaspike/src/main/resources/logback.xml b/deltaspike/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/deltaspike/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/disruptor/pom.xml b/disruptor/pom.xml index cc914cff7e..c26dcc0cd4 100644 --- a/disruptor/pom.xml +++ b/disruptor/pom.xml @@ -1,5 +1,5 @@ + 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 disruptor @@ -36,25 +36,10 @@ - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - org.apache.maven.plugins maven-jar-plugin + ${maven-jar-plugin.version} @@ -91,6 +76,7 @@ org.apache.maven.plugins maven-shade-plugin + ${maven-shade-plugin.version} @@ -99,8 +85,7 @@ true - + org.baeldung.executable.ExecutableMavenJar @@ -111,6 +96,7 @@ com.jolira onejar-maven-plugin + ${onejar-maven-plugin.version} @@ -134,6 +120,10 @@ 6.10 3.6.1 + + 2.4.3 + 3.0.2 + 1.4.4 \ No newline at end of file diff --git a/disruptor/src/main/resources/logback.xml b/disruptor/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/disruptor/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/dozer/pom.xml b/dozer/pom.xml index 0b7f85ddb4..5720001acf 100644 --- a/dozer/pom.xml +++ b/dozer/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung dozer diff --git a/dozer/src/main/resources/logback.xml b/dozer/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/dozer/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/drools/pom.xml b/drools/pom.xml index a060563eeb..009ac8acec 100644 --- a/drools/pom.xml +++ b/drools/pom.xml @@ -1,15 +1,15 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 drools - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + @@ -48,12 +48,18 @@ poi-ooxml ${apache-poi-version} + + org.optaplanner + optaplanner-core + ${opta-planner-version} + 4.4.6 7.4.1.Final 3.13 + 7.10.0.Final diff --git a/drools/src/main/java/com/baeldung/drools/optaplanner/CourseSchedule.java b/drools/src/main/java/com/baeldung/drools/optaplanner/CourseSchedule.java new file mode 100644 index 0000000000..7b2ba117a1 --- /dev/null +++ b/drools/src/main/java/com/baeldung/drools/optaplanner/CourseSchedule.java @@ -0,0 +1,63 @@ +package com.baeldung.drools.optaplanner; + +import java.util.ArrayList; +import java.util.List; + +import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty; +import org.optaplanner.core.api.domain.solution.PlanningScore; +import org.optaplanner.core.api.domain.solution.PlanningSolution; +import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty; +import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider; +import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@PlanningSolution +public class CourseSchedule { + + Logger logger = LoggerFactory.getLogger("CourseSchedule"); + + private List roomList; + private List periodList; + private List lectureList; + private HardSoftScore score; + + public CourseSchedule(){ + roomList = new ArrayList<>(); + periodList = new ArrayList<>(); + lectureList = new ArrayList<>(); + } + + @ValueRangeProvider(id = "availableRooms") + @ProblemFactCollectionProperty + public List getRoomList() { + return roomList; + } + + @ValueRangeProvider(id = "availablePeriods") + @ProblemFactCollectionProperty + public List getPeriodList() { + return periodList; + } + + @PlanningEntityCollectionProperty + public List getLectureList() { + return lectureList; + } + + @PlanningScore + public HardSoftScore getScore() { + return score; + } + + public void setScore(HardSoftScore score) { + this.score = score; + } + + public void printCourseSchedule() { + lectureList.stream() + .map(c -> "Lecture in Room " + c.getRoomNumber().toString() + " during Period " + c.getPeriod().toString()) + .forEach(k -> logger.info(k)); + } + +} diff --git a/drools/src/main/java/com/baeldung/drools/optaplanner/Lecture.java b/drools/src/main/java/com/baeldung/drools/optaplanner/Lecture.java new file mode 100644 index 0000000000..193cdb08b1 --- /dev/null +++ b/drools/src/main/java/com/baeldung/drools/optaplanner/Lecture.java @@ -0,0 +1,30 @@ +package com.baeldung.drools.optaplanner; + +import org.optaplanner.core.api.domain.entity.PlanningEntity; +import org.optaplanner.core.api.domain.variable.PlanningVariable; + +@PlanningEntity +public class Lecture { + + private Integer roomNumber; + private Integer period; + + @PlanningVariable(valueRangeProviderRefs = {"availablePeriods"}) + public Integer getPeriod() { + return period; + } + + @PlanningVariable(valueRangeProviderRefs = {"availableRooms"}) + public Integer getRoomNumber() { + return roomNumber; + } + + public void setPeriod(Integer period) { + this.period = period; + } + + public void setRoomNumber(Integer roomNumber) { + this.roomNumber = roomNumber; + } + +} diff --git a/drools/src/main/java/com/baeldung/drools/optaplanner/ScoreCalculator.java b/drools/src/main/java/com/baeldung/drools/optaplanner/ScoreCalculator.java new file mode 100644 index 0000000000..86501cdccd --- /dev/null +++ b/drools/src/main/java/com/baeldung/drools/optaplanner/ScoreCalculator.java @@ -0,0 +1,32 @@ +package com.baeldung.drools.optaplanner; + +import java.util.HashSet; + +import org.optaplanner.core.api.score.Score; +import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; +import org.optaplanner.core.impl.score.director.easy.EasyScoreCalculator; + +public class ScoreCalculator implements EasyScoreCalculator { + + @Override + public Score calculateScore(CourseSchedule courseSchedule) { + int hardScore = 0; + int softScore = 0; + + HashSet occupiedRooms = new HashSet<>(); + for (Lecture lecture : courseSchedule.getLectureList()) { + if(lecture.getPeriod() != null && lecture.getRoomNumber() != null) { + String roomInUse = lecture.getPeriod().toString() + ":" + lecture.getRoomNumber().toString(); + if (occupiedRooms.contains(roomInUse)) { + hardScore += -1; + } else { + occupiedRooms.add(roomInUse); + } + } else { + hardScore += -1; + } + } + + return HardSoftScore.valueOf(hardScore, softScore); + } +} diff --git a/drools/src/main/resources/courseSchedule.drl b/drools/src/main/resources/courseSchedule.drl new file mode 100644 index 0000000000..35dd57df84 --- /dev/null +++ b/drools/src/main/resources/courseSchedule.drl @@ -0,0 +1,14 @@ +package com.baeldung.drools.optaplanner + +import com.baeldung.drools.optaplanner.Lecture; +import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder; + +global HardSoftScoreHolder scoreHolder; + +rule "noNullRoomPeriod" + when + Lecture( roomNumber == null ); + Lecture( period == null ); + then + scoreHolder.addHardConstraintMatch(kcontext, -1); +end \ No newline at end of file diff --git a/drools/src/main/resources/courseScheduleSolverConfigDrools.xml b/drools/src/main/resources/courseScheduleSolverConfigDrools.xml new file mode 100644 index 0000000000..7cf95fdcd3 --- /dev/null +++ b/drools/src/main/resources/courseScheduleSolverConfigDrools.xml @@ -0,0 +1,12 @@ + + + + + + courseSchedule.drl + + + + 10 + + \ No newline at end of file diff --git a/drools/src/main/resources/courseScheduleSolverConfiguration.xml b/drools/src/main/resources/courseScheduleSolverConfiguration.xml new file mode 100644 index 0000000000..dfedb8f2fd --- /dev/null +++ b/drools/src/main/resources/courseScheduleSolverConfiguration.xml @@ -0,0 +1,12 @@ + + + + + + com.baeldung.drools.optaplanner.ScoreCalculator + + + + 10 + + \ No newline at end of file diff --git a/drools/src/main/resources/logback.xml b/drools/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/drools/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/drools/src/test/java/com/baeldung/drools/optaplanner/OptaPlannerUnitTest.java b/drools/src/test/java/com/baeldung/drools/optaplanner/OptaPlannerUnitTest.java new file mode 100644 index 0000000000..1880e30b86 --- /dev/null +++ b/drools/src/test/java/com/baeldung/drools/optaplanner/OptaPlannerUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.drools.optaplanner; + +import java.util.Arrays; + +import org.junit.Assert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.optaplanner.core.api.solver.Solver; +import org.optaplanner.core.api.solver.SolverFactory; + +public class OptaPlannerUnitTest { + + static CourseSchedule unsolvedCourseSchedule; + + @BeforeAll + public static void setUp() { + + unsolvedCourseSchedule = new CourseSchedule(); + + for(int i = 0; i < 10; i++){ + unsolvedCourseSchedule.getLectureList().add(new Lecture()); + } + + unsolvedCourseSchedule.getPeriodList().addAll(Arrays.asList(new Integer[] { 1, 2, 3 })); + unsolvedCourseSchedule.getRoomList().addAll(Arrays.asList(new Integer[] { 1, 2 })); + } + + @Test + public void test_whenCustomJavaSolver() { + + SolverFactory solverFactory = SolverFactory.createFromXmlResource("courseScheduleSolverConfiguration.xml"); + Solver solver = solverFactory.buildSolver(); + CourseSchedule solvedCourseSchedule = solver.solve(unsolvedCourseSchedule); + + Assert.assertNotNull(solvedCourseSchedule.getScore()); + Assert.assertEquals(-4, solvedCourseSchedule.getScore().getHardScore()); + } + + @Test + public void test_whenDroolsSolver() { + + SolverFactory solverFactory = SolverFactory.createFromXmlResource("courseScheduleSolverConfigDrools.xml"); + Solver solver = solverFactory.buildSolver(); + CourseSchedule solvedCourseSchedule = solver.solve(unsolvedCourseSchedule); + + Assert.assertNotNull(solvedCourseSchedule.getScore()); + Assert.assertEquals(0, solvedCourseSchedule.getScore().getHardScore()); + } +} diff --git a/dubbo/pom.xml b/dubbo/pom.xml index 81ff921f2a..6f81ec5cff 100644 --- a/dubbo/pom.xml +++ b/dubbo/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 dubbo @@ -15,12 +15,6 @@ dubbo ${dubbo.version} - - junit - junit - ${junit.version} - test - org.apache.zookeeper zookeeper @@ -34,9 +28,6 @@ - UTF-8 - UTF-8 - 1.8 2.5.7 3.4.11 0.10 diff --git a/dubbo/src/main/resources/logback.xml b/dubbo/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/dubbo/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/eclipse/formatter.xml b/eclipse/formatter.xml index 808f65cda9..6887946a4c 100644 --- a/eclipse/formatter.xml +++ b/eclipse/formatter.xml @@ -1,297 +1,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ejb/README.md b/ejb/README.md index 994781b064..f47277bf8f 100644 --- a/ejb/README.md +++ b/ejb/README.md @@ -3,3 +3,4 @@ - [Guide to EJB Set-up](http://www.baeldung.com/ejb-intro) - [Java EE Session Beans](http://www.baeldung.com/ejb-session-beans) - [Introduction to EJB JNDI Lookup on WildFly Application Server](http://www.baeldung.com/wildfly-ejb-jndi) +- [A Guide to Message Driven Beans in EJB](http://www.baeldung.com/ejb-message-driven-beans) diff --git a/ejb/ejb-client/pom.xml b/ejb/ejb-client/pom.xml index 88116f8003..6231030cec 100755 --- a/ejb/ejb-client/pom.xml +++ b/ejb/ejb-client/pom.xml @@ -1,6 +1,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 @@ -16,7 +16,6 @@ org.wildfly wildfly-ejb-client-bom pom - import com.baeldung.ejb @@ -24,20 +23,4 @@ ejb - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - **/*EJBSetupTest.java - - - - - - \ No newline at end of file diff --git a/ejb/ejb-client/src/main/resources/logback.xml b/ejb/ejb-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ejb/ejb-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ejb/ejb-client/src/test/java/com/baeldung/ejb/wildfly/TextApplicationTest.java b/ejb/ejb-client/src/test/java/com/baeldung/ejb/wildfly/TextApplicationIntegrationTest.java similarity index 94% rename from ejb/ejb-client/src/test/java/com/baeldung/ejb/wildfly/TextApplicationTest.java rename to ejb/ejb-client/src/test/java/com/baeldung/ejb/wildfly/TextApplicationIntegrationTest.java index c0446eaea6..8dff116ca1 100644 --- a/ejb/ejb-client/src/test/java/com/baeldung/ejb/wildfly/TextApplicationTest.java +++ b/ejb/ejb-client/src/test/java/com/baeldung/ejb/wildfly/TextApplicationIntegrationTest.java @@ -8,7 +8,7 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import static org.junit.Assert.*; -public class TextApplicationTest { +public class TextApplicationIntegrationTest { private static ByteArrayOutputStream outContent; diff --git a/ejb/ejb-remote/pom.xml b/ejb/ejb-remote/pom.xml index b8f1f0dcc0..dac2fefb84 100755 --- a/ejb/ejb-remote/pom.xml +++ b/ejb/ejb-remote/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 ejb-remote ejb @@ -15,7 +15,6 @@ javax javaee-api - ${javaee-api.version} provided @@ -57,7 +56,7 @@ - + wildfly-runtime @@ -74,7 +73,7 @@ 9990 testUser admin1234! - ${build.finalName}.jar + ${project.build.finalName}.jar diff --git a/ejb/ejb-remote/src/main/resources/logback.xml b/ejb/ejb-remote/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ejb/ejb-remote/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ejb/ejb-session-beans/pom.xml b/ejb/ejb-session-beans/pom.xml index 6afd7f2c6d..da76169729 100644 --- a/ejb/ejb-session-beans/pom.xml +++ b/ejb/ejb-session-beans/pom.xml @@ -13,7 +13,7 @@ org.jboss.arquillian arquillian-bom - 1.1.13.Final + ${arquillian-bom.version} import pom @@ -24,15 +24,8 @@ javax javaee-api - ${javaee-api.version} provided - - junit - junit - ${junit.version} - test - org.jboss.arquillian.junit arquillian-junit-container @@ -56,7 +49,7 @@ org.glassfish.main.extras glassfish-embedded-all - 3.1.2 + ${glassfish-embedded-all.version} test @@ -67,7 +60,7 @@ maven-war-plugin - 2.4 + ${maven-war-plugin.version} false @@ -77,13 +70,14 @@ UTF-8 - 1.1.12.Final + 1.1.13.Final 2.2.6 1.1.12.Final 1.0.0.Final 4.12 7.0 1.0.0.CR4 + 3.1.2 \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/resources/logback.xml b/ejb/ejb-session-beans/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBTest.java b/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBIntegrationTest.java similarity index 97% rename from ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBTest.java rename to ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBIntegrationTest.java index 2f3e45a769..cc35921e45 100644 --- a/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBTest.java +++ b/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBIntegrationTest.java @@ -17,7 +17,7 @@ import javax.inject.Inject; @RunWith(Arquillian.class) -public class StatefulEJBTest { +public class StatefulEJBIntegrationTest { @Inject private EJBClient1 ejbClient1; diff --git a/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBTest.java b/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBIntegrationTest.java similarity index 97% rename from ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBTest.java rename to ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBIntegrationTest.java index 9f88d478b7..c80ca93c0d 100644 --- a/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBTest.java +++ b/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBIntegrationTest.java @@ -17,7 +17,7 @@ import javax.inject.Inject; @RunWith(Arquillian.class) -public class StatelessEJBTest { +public class StatelessEJBIntegrationTest { @Inject private EJBClient1 ejbClient1; diff --git a/ejb/pom.xml b/ejb/pom.xml index e61c2a0b7b..4cb700d087 100755 --- a/ejb/pom.xml +++ b/ejb/pom.xml @@ -1,6 +1,6 @@ + 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.ejb ejb @@ -17,7 +17,6 @@ ejb-remote - ejb-client ejb-session-beans @@ -83,9 +82,6 @@ - UTF-8 - UTF-8 - 1.8 2.5.7 3.4.11 0.10 diff --git a/ejb/wildfly/pom.xml b/ejb/wildfly/pom.xml index ad73f4817e..53d10a90ed 100644 --- a/ejb/wildfly/pom.xml +++ b/ejb/wildfly/pom.xml @@ -2,9 +2,10 @@ 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.wildfly - wildfly-example + wildfly 0.0.1-SNAPSHOT pom + wildfly com.baeldung.ejb @@ -83,7 +84,6 @@ 1.8 1.8 - UTF-8 7.0 10.1.0.Final 5.2.3.Final diff --git a/ejb/wildfly/widlfly-web/pom.xml b/ejb/wildfly/widlfly-web/pom.xml index a337e8ef60..559c5f1755 100644 --- a/ejb/wildfly/widlfly-web/pom.xml +++ b/ejb/wildfly/widlfly-web/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 widlfly-web war diff --git a/ejb/wildfly/widlfly-web/src/main/resources/logback.xml b/ejb/wildfly/widlfly-web/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ejb/wildfly/widlfly-web/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-ear/pom.xml b/ejb/wildfly/wildfly-ear/pom.xml index f264594652..d1e47ecd0f 100644 --- a/ejb/wildfly/wildfly-ear/pom.xml +++ b/ejb/wildfly/wildfly-ear/pom.xml @@ -40,7 +40,7 @@ maven-ear-plugin - 2.10.1 + ${maven-ear-plugin.version} lib/ 7 @@ -56,8 +56,13 @@ org.wildfly.plugins wildfly-maven-plugin - 1.2.0.Final + ${wildfly-maven-plugin.version} + + + 2.10.1 + 1.2.0.Final + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-ejb-interfaces/pom.xml b/ejb/wildfly/wildfly-ejb-interfaces/pom.xml index 61a630b899..ec502f2ab3 100644 --- a/ejb/wildfly/wildfly-ejb-interfaces/pom.xml +++ b/ejb/wildfly/wildfly-ejb-interfaces/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 wildfly-ejb-interfaces diff --git a/ejb/wildfly/wildfly-ejb-interfaces/src/main/resources/logback.xml b/ejb/wildfly/wildfly-ejb-interfaces/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ejb/wildfly/wildfly-ejb-interfaces/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-ejb/pom.xml b/ejb/wildfly/wildfly-ejb/pom.xml index 900f93c0ba..2c87ec8449 100644 --- a/ejb/wildfly/wildfly-ejb/pom.xml +++ b/ejb/wildfly/wildfly-ejb/pom.xml @@ -15,7 +15,7 @@ javax.ejb javax.ejb-api - 3.2 + ${ejb.version} provided @@ -42,9 +42,13 @@ org.apache.maven.plugins maven-ejb-plugin - 3.2 + ${ejb.version} + + + 3.2 + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-ejb/src/main/resources/logback.xml b/ejb/wildfly/wildfly-ejb/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ejb/wildfly/wildfly-ejb/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-jpa/pom.xml b/ejb/wildfly/wildfly-jpa/pom.xml index 18e86b1b31..12cf2c81e4 100644 --- a/ejb/wildfly/wildfly-jpa/pom.xml +++ b/ejb/wildfly/wildfly-jpa/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 wildfly-jpa diff --git a/ejb/wildfly/wildfly-jpa/src/main/resources/logback.xml b/ejb/wildfly/wildfly-jpa/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ejb/wildfly/wildfly-jpa/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-mdb/pom.xml b/ejb/wildfly/wildfly-mdb/pom.xml new file mode 100644 index 0000000000..186ddc50c0 --- /dev/null +++ b/ejb/wildfly/wildfly-mdb/pom.xml @@ -0,0 +1,22 @@ + + 4.0.0 + wildfly-mdb + wildfly-mdb + + + com.baeldung.wildfly + wildfly-example + 0.0.1-SNAPSHOT + + + + + + javax + javaee-api + ${javaee-api.version} + provided + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java b/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java new file mode 100644 index 0000000000..6997f92201 --- /dev/null +++ b/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java @@ -0,0 +1,28 @@ +package com.baeldung.wildfly.mdb; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; + +/** + * Message-Driven Bean implementation class for: ReadMessageMDB + */ +@MessageDriven( + activationConfig = { + @ActivationConfigProperty(propertyName = "destination", propertyValue = "tutorialQueue"), + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") +}) +public class ReadMessageMDB implements MessageListener { + + public void onMessage(Message message) { + TextMessage textMessage = (TextMessage) message; + try { + System.out.println("Message received: " + textMessage.getText()); + } catch (JMSException e) { + System.out.println("Error while trying to consume messages: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java b/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java new file mode 100644 index 0000000000..7dcd04b43f --- /dev/null +++ b/ejb/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java @@ -0,0 +1,52 @@ +package baeldung.com.example.servlet; + +import java.io.IOException; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +@WebServlet("/SendMessageServlet") +public class SendMessageServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + String text = req.getParameter("text") != null ? req.getParameter("text") : "Hello World"; + + try ( + Context ic = new InitialContext(); + + ConnectionFactory cf = (ConnectionFactory) ic.lookup("/ConnectionFactory"); + Queue queue = (Queue) ic.lookup("queue/tutorialQueue"); + + Connection connection = cf.createConnection(); + ) { + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageProducer publisher = session.createProducer(queue); + + connection.start(); + + TextMessage message = session.createTextMessage(text); + publisher.send(message); + + } catch (NamingException | JMSException e) { + res.getWriter().println("Error while trying to send <" + text + "> message: " + e.getMessage()); + } + + res.getWriter().println("Message sent: " + text); + } + +} \ No newline at end of file diff --git a/enterprise-patterns/README.md b/enterprise-patterns/README.md deleted file mode 100644 index ff12555376..0000000000 --- a/enterprise-patterns/README.md +++ /dev/null @@ -1 +0,0 @@ -## Relevant articles: diff --git a/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/AuditFilter.java b/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/AuditFilter.java deleted file mode 100644 index d24c0a94b3..0000000000 --- a/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/AuditFilter.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.baeldung.enterprise.patterns.front.controller.filters; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import java.io.IOException; - -public class AuditFilter extends BaseFilter { - @Override - public void doFilter( - ServletRequest request, - ServletResponse response, - FilterChain chain - ) throws IOException, ServletException { - HttpServletRequest httpServletRequest = (HttpServletRequest) request; - HttpSession session = httpServletRequest.getSession(false); - if (session != null && session.getAttribute("username") != null) { - request.setAttribute("username", session.getAttribute("username")); - } - chain.doFilter(request, response); - } -} diff --git a/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/VisitorCounterFilter.java b/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/VisitorCounterFilter.java deleted file mode 100644 index 0ae7cd73fd..0000000000 --- a/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/VisitorCounterFilter.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.baeldung.enterprise.patterns.front.controller.filters; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.annotation.WebFilter; -import java.io.IOException; - -@WebFilter(servletNames = "front-controller") -public class VisitorCounterFilter extends BaseFilter { - private int counter; - - @Override - public void doFilter( - ServletRequest request, - ServletResponse response, - FilterChain chain - ) throws IOException, ServletException { - request.setAttribute("counter", ++counter); - chain.doFilter(request, response); - } -} diff --git a/enterprise-patterns/pom.xml b/enterprise-patterns/pom.xml deleted file mode 100644 index 07842b8981..0000000000 --- a/enterprise-patterns/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - 4.0.0 - com.baeldung.enterprise.patterns - enterprise-patterns-parent - pom - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - spring-dispatcher-servlet - - - diff --git a/ethereumj/.gitgnore b/ethereum/.gitgnore similarity index 100% rename from ethereumj/.gitgnore rename to ethereum/.gitgnore diff --git a/ethereumj/README.md b/ethereum/README.md similarity index 95% rename from ethereumj/README.md rename to ethereum/README.md index 320ae8c9f8..d06ca09636 100644 --- a/ethereumj/README.md +++ b/ethereum/README.md @@ -1,4 +1,4 @@ -## EthereumJ +## Ethereum ### Relevant Articles: - [Introduction to EthereumJ](http://www.baeldung.com/ethereumj) diff --git a/ethereum/pom.xml b/ethereum/pom.xml new file mode 100644 index 0000000000..bd1bacb221 --- /dev/null +++ b/ethereum/pom.xml @@ -0,0 +1,231 @@ + + 4.0.0 + com.baeldung.ethereum + ethereum + 0.0.1-SNAPSHOT + ethereum + + + parent-spring-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-spring-5 + + + + + + + org.springframework.boot + spring-boot-starter + ${spring.boot.version} + + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + org.springframework.boot + spring-boot-starter-tomcat + ${spring.boot.version} + + + + + org.springframework + spring-core + ${springframework.version} + + + org.springframework + spring-web + ${springframework.version} + + + org.springframework + spring-webmvc + ${springframework.version} + + + + + org.ethereum + ethereumj-core + ${ethereumj-core.version} + + + org.web3j + core + ${web3j.core.version} + + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + + + javax.servlet + jstl + ${jstl.version} + + + javax.servlet + javax.servlet-api + ${javax-servlet.version} + + + javax.servlet.jsp.jstl + jstl-api + ${jstl.version} + + + javax.servlet.jsp + javax.servlet.jsp-api + ${javax-jsp.version} + + + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + org.springframework.boot + spring-boot-starter-test + test + ${spring.boot.version} + + + org.springframework + spring-context + ${springframework.version} + + + org.springframework + spring-test + ${springframework.version} + test + + + + + org.mockito + mockito-core + ${mockito.version} + + + org.hamcrest + hamcrest-core + + + test + + + junit + junit + ${junit.version} + test + + + org.hamcrest + hamcrest-core + + + + + org.hamcrest + hamcrest-library + ${hamcrest.version} + test + + + com.jayway.jsonpath + json-path + ${jsonpath.version} + + + + + ethereum + + + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + org.apache.maven.plugins + maven-war-plugin + 3.0.0 + + src/main/webapp + false + + + + + + + + Ethereum + Ethereum + https://dl.bintray.com/ethereum/maven/ + + + + + UTF-8 + 1.8 + 8.5.4 + 1.5.0-RELEASE + 3.3.1 + 5.0.5.RELEASE + 1.5.6.RELEASE + 2.21.0 + 2.5.0 + 1.3 + 2.9.3 + 2.3.1 + 3.1.0 + 2.4.0 + 1.2 + 4.12 + 1.2.3 + 1.7.25 + 2.0.4.RELEASE + + + diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/ApplicationMain.java b/ethereum/src/main/java/com/baeldung/ethereumj/ApplicationMain.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/ApplicationMain.java rename to ethereum/src/main/java/com/baeldung/ethereumj/ApplicationMain.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/Constants.java b/ethereum/src/main/java/com/baeldung/ethereumj/Constants.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/Constants.java rename to ethereum/src/main/java/com/baeldung/ethereumj/Constants.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/beans/EthBean.java b/ethereum/src/main/java/com/baeldung/ethereumj/beans/EthBean.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/beans/EthBean.java rename to ethereum/src/main/java/com/baeldung/ethereumj/beans/EthBean.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/config/EthConfig.java b/ethereum/src/main/java/com/baeldung/ethereumj/config/EthConfig.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/config/EthConfig.java rename to ethereum/src/main/java/com/baeldung/ethereumj/config/EthConfig.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/controllers/EthController.java b/ethereum/src/main/java/com/baeldung/ethereumj/controllers/EthController.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/controllers/EthController.java rename to ethereum/src/main/java/com/baeldung/ethereumj/controllers/EthController.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java b/ethereum/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java rename to ethereum/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java b/ethereum/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java rename to ethereum/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java diff --git a/ethereumj/src/main/java/com/baeldung/web3j/Template.java b/ethereum/src/main/java/com/baeldung/web3j/Template.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/web3j/Template.java rename to ethereum/src/main/java/com/baeldung/web3j/Template.java diff --git a/ethereum/src/main/java/com/baeldung/web3j/config/AppConfig.java b/ethereum/src/main/java/com/baeldung/web3j/config/AppConfig.java new file mode 100644 index 0000000000..75ef948f7a --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/config/AppConfig.java @@ -0,0 +1,68 @@ +package com.baeldung.web3j.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.resource.PathResourceResolver; +import org.springframework.web.servlet.view.JstlView; +import org.springframework.web.servlet.view.UrlBasedViewResolver; + +import java.util.concurrent.Executor; + +@Configuration +@EnableWebMvc +@EnableAsync +@ComponentScan("com.baeldung.web3j") +public class AppConfig implements WebMvcConfigurer { + + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("index"); + } + + /** + * Static resource locations including themes + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**/*") + .addResourceLocations("/", "/resources/") + .setCachePeriod(3600) + .resourceChain(true) + .addResolver(new PathResourceResolver()); + } + + /** + * View resolver for JSP + */ + @Bean + public UrlBasedViewResolver viewResolver() { + UrlBasedViewResolver resolver = new UrlBasedViewResolver(); + resolver.setPrefix("/WEB-INF/jsp/"); + resolver.setSuffix(".jsp"); + resolver.setViewClass(JstlView.class); + return resolver; + } + + /** + * Configuration for async thread bean + * + * More: https://docs.spring.io/autorepo/docs/spring-framework/5.0.3.RELEASE/javadoc-api/org/springframework/scheduling/SchedulingTaskExecutor.html + */ + @Bean + public Executor asyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(2); + executor.setMaxPoolSize(2); + executor.setQueueCapacity(500); + executor.setThreadNamePrefix("CsvThread"); + executor.initialize(); + return executor; + } + +} \ No newline at end of file diff --git a/ethereum/src/main/java/com/baeldung/web3j/config/WebAppInitializer.java b/ethereum/src/main/java/com/baeldung/web3j/config/WebAppInitializer.java new file mode 100644 index 0000000000..8a9a8cf8c1 --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/config/WebAppInitializer.java @@ -0,0 +1,28 @@ +package com.baeldung.web3j.config; + +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + //AbstractDispatcherServletInitializer override DEFAULT_SERVLET_NAME + @Override + protected String getServletName() { + return "dispatcher"; + } + + @Override + protected Class[] getRootConfigClasses() { + return new Class[]{}; + } + + @Override + protected Class[] getServletConfigClasses() { + return new Class[]{AppConfig.class}; + } + + @Override + protected String[] getServletMappings() { + return new String[]{"/"}; + } + +} \ No newline at end of file diff --git a/ethereum/src/main/java/com/baeldung/web3j/constants/Constants.java b/ethereum/src/main/java/com/baeldung/web3j/constants/Constants.java new file mode 100644 index 0000000000..005e4263cd --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/constants/Constants.java @@ -0,0 +1,18 @@ +package com.baeldung.web3j.constants; + +public class Constants { + + public static final String API_BLOCK = "/api/block"; + public static final String API_ACCOUNTS = "/api/accounts"; + public static final String API_TRANSACTIONS = "/api/transactions"; + public static final String API_BALANCE = "/api/balance"; + + public static final String GENERIC_EXCEPTION = "Exception encountered!"; + public static final String PLEASE_SUPPLY_REAL_DATA = "Please Supply Real Data!"; + + public static final String DEFAULT_ADDRESS = "0x281055afc982d96fab65b3a49cac8b878184cb16"; + public static final String DEFAULT_CONTRACT_ADDRESS = "00000000000000000000"; + + + +} diff --git a/ethereum/src/main/java/com/baeldung/web3j/contracts/Example.java b/ethereum/src/main/java/com/baeldung/web3j/contracts/Example.java new file mode 100644 index 0000000000..6909ca3e0c --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/contracts/Example.java @@ -0,0 +1,74 @@ +package com.baeldung.web3j.contracts; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Type; +import org.web3j.crypto.Credentials; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.RemoteCall; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.tx.Contract; +import org.web3j.tx.TransactionManager; + +/** + *

Auto generated code. + *

Do not modify! + *

Please use the web3j command line tools, + * or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the + * codegen module to update. + * + *

Generated with web3j version 3.3.1. + */ +public class Example extends Contract { + private static final String BINARY = "0x60606040523415600e57600080fd5b60848061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029"; + + protected static final HashMap _addresses; + + static { + _addresses = new HashMap<>(); + } + + protected Example(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + protected Example(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + public static RemoteCall deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return deployRemoteCall(Example.class, web3j, credentials, gasPrice, gasLimit, BINARY, ""); + } + + public static RemoteCall deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return deployRemoteCall(Example.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, ""); + } + + public RemoteCall ExampleFunction() { + final Function function = new Function( + "ExampleFunction", + Arrays.asList(), + Collections.>emptyList()); + return executeRemoteCallTransaction(function); + } + + public static Example load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { + return new Example(contractAddress, web3j, credentials, gasPrice, gasLimit); + } + + public static Example load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { + return new Example(contractAddress, web3j, transactionManager, gasPrice, gasLimit); + } + + protected String getStaticDeployedAddress(String networkId) { + return _addresses.get(networkId); + } + + public static String getPreviouslyDeployedAddress(String networkId) { + return _addresses.get(networkId); + } +} diff --git a/ethereumj/src/main/java/com/baeldung/web3j/contracts/Greeting.java b/ethereum/src/main/java/com/baeldung/web3j/contracts/Greeting.java similarity index 100% rename from ethereumj/src/main/java/com/baeldung/web3j/contracts/Greeting.java rename to ethereum/src/main/java/com/baeldung/web3j/contracts/Greeting.java diff --git a/ethereum/src/main/java/com/baeldung/web3j/controllers/EthereumRestController.java b/ethereum/src/main/java/com/baeldung/web3j/controllers/EthereumRestController.java new file mode 100644 index 0000000000..e05517bc79 --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/controllers/EthereumRestController.java @@ -0,0 +1,103 @@ +package com.baeldung.web3j.controllers; + +import com.baeldung.web3j.constants.Constants; +import com.baeldung.web3j.helpers.TimeHelper; +import com.baeldung.web3j.services.Web3Service; +import com.baeldung.web3j.transfers.ResponseTransfer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.web3j.protocol.core.methods.response.EthAccounts; +import org.web3j.protocol.core.methods.response.EthBlockNumber; +import org.web3j.protocol.core.methods.response.EthGetBalance; +import org.web3j.protocol.core.methods.response.EthGetTransactionCount; + +import java.time.Instant; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; + +import static com.baeldung.web3j.constants.Constants.GENERIC_EXCEPTION; + +@RestController +public class EthereumRestController { + + @Autowired + Web3Service web3Service; + + @RequestMapping(value = Constants.API_BLOCK, method = RequestMethod.GET) + public Future getBlock() { + ResponseTransfer responseTransfer = new ResponseTransfer(); + Instant start = TimeHelper.start(); + + return CompletableFuture.supplyAsync(() -> { + try { + CompletableFuture result = web3Service.getBlockNumber(); + responseTransfer.setMessage(result.get().toString()); + } catch (Exception e) { + responseTransfer.setMessage(GENERIC_EXCEPTION); + } + return responseTransfer; + }).thenApplyAsync(result -> { + result.setPerformance(TimeHelper.stop(start)); + return result; + }); + } + + @RequestMapping(value = Constants.API_ACCOUNTS, method = RequestMethod.GET) + public Future getAccounts() { + ResponseTransfer responseTransfer = new ResponseTransfer(); + Instant start = TimeHelper.start(); + + return CompletableFuture.supplyAsync(() -> { + try { + CompletableFuture result = web3Service.getEthAccounts(); + responseTransfer.setMessage(result.get().toString()); + } catch (Exception e) { + responseTransfer.setMessage(GENERIC_EXCEPTION); + } + return responseTransfer; + + }).thenApplyAsync(result -> { + result.setPerformance(TimeHelper.stop(start)); + return result; + }); + } + + @RequestMapping(value = Constants.API_TRANSACTIONS, method = RequestMethod.GET) + public Future getTransactions() { + ResponseTransfer responseTransfer = new ResponseTransfer(); + Instant start = TimeHelper.start(); + return CompletableFuture.supplyAsync(() -> { + try { + CompletableFuture result = web3Service.getTransactionCount(); + responseTransfer.setMessage(result.get().toString()); + } catch (Exception e) { + responseTransfer.setMessage(GENERIC_EXCEPTION); + } + return responseTransfer; + }).thenApplyAsync(result -> { + result.setPerformance(TimeHelper.stop(start)); + return result; + }); + } + + @RequestMapping(value = Constants.API_BALANCE, method = RequestMethod.GET) + public Future getBalance() { + ResponseTransfer responseTransfer = new ResponseTransfer(); + Instant start = TimeHelper.start(); + return CompletableFuture.supplyAsync(() -> { + try { + CompletableFuture result = web3Service.getEthBalance(); + responseTransfer.setMessage(result.get().toString()); + } catch (Exception e) { + responseTransfer.setMessage(GENERIC_EXCEPTION); + } + return responseTransfer; + }).thenApplyAsync(result -> { + result.setPerformance(TimeHelper.stop(start)); + return result; + }); + } + +} \ No newline at end of file diff --git a/ethereum/src/main/java/com/baeldung/web3j/helpers/TimeHelper.java b/ethereum/src/main/java/com/baeldung/web3j/helpers/TimeHelper.java new file mode 100644 index 0000000000..360fe088ba --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/helpers/TimeHelper.java @@ -0,0 +1,16 @@ +package com.baeldung.web3j.helpers; + +import java.time.Duration; +import java.time.Instant; + +public class TimeHelper { + + public static Instant start() { + return Instant.now(); + } + + public static Duration stop(Instant start) { + Instant end = Instant.now(); + return Duration.between(start, end); + } +} diff --git a/ethereum/src/main/java/com/baeldung/web3j/services/Web3Service.java b/ethereum/src/main/java/com/baeldung/web3j/services/Web3Service.java new file mode 100644 index 0000000000..c943ee4006 --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/services/Web3Service.java @@ -0,0 +1,151 @@ +package com.baeldung.web3j.services; + +import com.baeldung.web3j.contracts.Example; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.datatypes.Function; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.WalletUtils; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.DefaultBlockParameter; +import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.EthAccounts; +import org.web3j.protocol.core.methods.response.EthBlockNumber; +import org.web3j.protocol.core.methods.response.EthGetBalance; +import org.web3j.protocol.core.methods.response.EthGetTransactionCount; +import org.web3j.protocol.http.HttpService; +import org.web3j.tx.Contract; +import org.web3j.tx.ManagedTransaction; + +import java.io.File; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static com.baeldung.web3j.constants.Constants.DEFAULT_ADDRESS; +import static com.baeldung.web3j.constants.Constants.GENERIC_EXCEPTION; +import static com.baeldung.web3j.constants.Constants.PLEASE_SUPPLY_REAL_DATA; + +@Service +public class Web3Service { + + private Web3j web3j = Web3j.build(new HttpService()); + + //Create and Init the default Web3J connection + public void customInit(String provider) { + this.web3j = Web3j.build(new HttpService(provider)); + } + + //Convert to and from supplied contract ABI bytecode + public static String toBinary(String bytecode) { + return bytecode.replaceFirst("^0x", ""); + } + + public static String toByteCode(String binary) { + return "0x" + binary; + } + + public CompletableFuture getBlockNumber() { + EthBlockNumber result = new EthBlockNumber(); + try { + result = this.web3j.ethBlockNumber().sendAsync().get(); + } catch (Exception ex) { + System.out.println(GENERIC_EXCEPTION); + } + return CompletableFuture.completedFuture(result); + } + + public CompletableFuture getEthAccounts() { + EthAccounts result = new EthAccounts(); + try { + result = this.web3j.ethAccounts().sendAsync().get(); + } catch (Exception ex) { + System.out.println(GENERIC_EXCEPTION); + } + return CompletableFuture.completedFuture(result); + } + + public CompletableFuture getTransactionCount() { + EthGetTransactionCount result = new EthGetTransactionCount(); + try { + result = this.web3j.ethGetTransactionCount(DEFAULT_ADDRESS, DefaultBlockParameter.valueOf("latest")).sendAsync().get(); + } catch (Exception ex) { + System.out.println(GENERIC_EXCEPTION); + } + return CompletableFuture.completedFuture(result); + } + + public CompletableFuture getEthBalance() { + EthGetBalance result = new EthGetBalance(); + try { + result = this.web3j.ethGetBalance(DEFAULT_ADDRESS, DefaultBlockParameter.valueOf("latest")).sendAsync().get(); + } catch (Exception ex) { + System.out.println(GENERIC_EXCEPTION); + } + return CompletableFuture.completedFuture(result); + } + + public CompletableFuture fromScratchContractExample() { + + String contractAddress = ""; + + try { + //Create a wallet + WalletUtils.generateNewWalletFile("PASSWORD", new File("/path/to/destination"), true); + //Load the credentials from it + Credentials credentials = WalletUtils.loadCredentials("PASSWORD", "/path/to/walletfile"); + + //Deploy contract to address specified by wallet + Example contract = Example.deploy(this.web3j, + credentials, + ManagedTransaction.GAS_PRICE, + Contract.GAS_LIMIT).send(); + + //Het the address + contractAddress = contract.getContractAddress(); + + } catch (Exception ex) { + System.out.println(PLEASE_SUPPLY_REAL_DATA); + return CompletableFuture.completedFuture(PLEASE_SUPPLY_REAL_DATA); + } + return CompletableFuture.completedFuture(contractAddress); + } + + @Async + public CompletableFuture sendTx() { + String transactionHash = ""; + + try { + List inputParams = new ArrayList(); + List outputParams = new ArrayList(); + Function function = new Function("fuctionName", inputParams, outputParams); + + String encodedFunction = FunctionEncoder.encode(function); + + BigInteger nonce = BigInteger.valueOf(100); + BigInteger gasprice = BigInteger.valueOf(100); + BigInteger gaslimit = BigInteger.valueOf(100); + + Transaction transaction = Transaction.createFunctionCallTransaction("FROM_ADDRESS", nonce, gasprice, gaslimit, "TO_ADDRESS", encodedFunction); + + org.web3j.protocol.core.methods.response.EthSendTransaction transactionResponse = web3j.ethSendTransaction(transaction).sendAsync().get(); + transactionHash = transactionResponse.getTransactionHash(); + + } catch (Exception ex) { + System.out.println(PLEASE_SUPPLY_REAL_DATA); + return CompletableFuture.completedFuture(PLEASE_SUPPLY_REAL_DATA); + } + + return CompletableFuture.completedFuture(transactionHash); + } +} + + + + + + + + diff --git a/ethereum/src/main/java/com/baeldung/web3j/transfers/ResponseTransfer.java b/ethereum/src/main/java/com/baeldung/web3j/transfers/ResponseTransfer.java new file mode 100644 index 0000000000..9c5d1799ff --- /dev/null +++ b/ethereum/src/main/java/com/baeldung/web3j/transfers/ResponseTransfer.java @@ -0,0 +1,28 @@ +package com.baeldung.web3j.transfers; + +import java.time.Duration; + +public class ResponseTransfer { + + public ResponseTransfer() {} + + private Duration performance; + private String message; + + public Duration getPerformance() { + return performance; + } + + public void setPerformance(Duration performance) { + this.performance = performance; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/ethereumj/src/main/resources/application.properties b/ethereum/src/main/resources/application.properties similarity index 100% rename from ethereumj/src/main/resources/application.properties rename to ethereum/src/main/resources/application.properties diff --git a/ethereum/src/main/resources/dev_ganache/README.md b/ethereum/src/main/resources/dev_ganache/README.md new file mode 100644 index 0000000000..2d3e645504 --- /dev/null +++ b/ethereum/src/main/resources/dev_ganache/README.md @@ -0,0 +1,23 @@ +# Ganache Readme + +TL:DR - To set up Ganache visit: http://truffleframework.com/ganache/ + +# Three Ways to Install Ganache + +Ganache is provided in three libraries or distributions: + +(1) Ganache - https://github.com/trufflesuite/ganache + +This is a pre-built and out-of-the-box solution. Easiest to set up. It provides an interface and server shell for Ganache CLI. + +(2) Ganache CLI - https://www.npmjs.com/package/ganache-cli + +Ganache CLI abstracts Ganache Core and supplies the default options and arguments used. + +(3) Ganache Core - https://www.npmjs.com/package/ganache-core + +Basically, only use Ganache Core if you need to build a totally customized option. + +# Use + +The default port is *8545* on *localhost* \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/README.md b/ethereum/src/main/resources/dev_truffle/README.md new file mode 100644 index 0000000000..b64e16d570 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/README.md @@ -0,0 +1,43 @@ +# Using Truffle + +Basic Truffle walkthrough readme. + +See also: http://truffleframework.com/docs/ + +# Bash + +Truffle install + +```bash + $ npm install truffle -g + $ truffle version +``` + +Truffle commands: + +```bash + $ truffle init + $ truffle compile + $ truffle migrate + $ truffle test +``` + +# Directory Structure + +The command `$ truffle init` will create a directory structure in the specified root according to the following: + +``` +root -| + |-build (Compiled Solc JSON Output Dir) + |-contracts (Solc Contracts to be Compiled and Migrated) + |-migrations (Specify the Order and Dependencies of Contracts to Be Deployed) + |-test (Truffle Tests) +``` + +# Compile + +Truffle will compile the smart contracts and expose their **JSON ABI's for use with Web3.js** or **Binary ABI's for use with Web3J**. + +# Migration + +Truffle will let you deploy your Solc contracts directly to a blockchin of your choice. \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/build/contracts/ConvertLib.json b/ethereum/src/main/resources/dev_truffle/build/contracts/ConvertLib.json new file mode 100644 index 0000000000..977928c756 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/build/contracts/ConvertLib.json @@ -0,0 +1,455 @@ +{ + "contractName": "ConvertLib", + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "amount", + "type": "uint256" + }, + { + "name": "conversionRate", + "type": "uint256" + } + ], + "name": "convert", + "outputs": [ + { + "name": "convertedAmount", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60d161002f600b82828239805160001a6073146000811461001f57610021565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146060604052600436106056576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d14605b575b600080fd5b8115606557600080fd5b608260048080359060200190919080359060200190919050506098565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820ab84b2740847d7b84a33de9738ae9cf9aabac1b68e6a64d60bd5020b9b6235e40029", + "deployedBytecode": "0x73000000000000000000000000000000000000000030146060604052600436106056576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396e4ee3d14605b575b600080fd5b8115606557600080fd5b608260048080359060200190919080359060200190919050506098565b6040518082815260200191505060405180910390f35b60008183029050929150505600a165627a7a72305820ab84b2740847d7b84a33de9738ae9cf9aabac1b68e6a64d60bd5020b9b6235e40029", + "sourceMap": "28:148:0:-;;132:2:-1;166:7;155:9;146:7;137:37;252:7;246:14;243:1;238:23;232:4;229:33;270:1;265:20;;;;222:63;;265:20;274:9;222:63;;298:9;295:1;288:20;328:4;319:7;311:22;352:7;343;336:24", + "deployedSourceMap": "28:148:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;50:123;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109:20;154:14;145:6;:23;138:30;;50:123;;;;:::o", + "source": "pragma solidity ^0.4.17;\r\n\r\nlibrary ConvertLib{\r\n\tfunction convert(uint amount,uint conversionRate) returns (uint convertedAmount)\r\n\t{\r\n\t\treturn amount * conversionRate;\r\n\t}\r\n}\r\n", + "sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\ConvertLib.sol", + "ast": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/ConvertLib.sol", + "exportedSymbols": { + "ConvertLib": [ + 16 + ] + }, + "id": 17, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:0" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "library", + "documentation": null, + "fullyImplemented": true, + "id": 16, + "linearizedBaseContracts": [ + 16 + ], + "name": "ConvertLib", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 14, + "nodeType": "Block", + "src": "133:40:0", + "statements": [ + { + "expression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 10, + "name": "amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "145:6:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "argumentTypes": null, + "id": 11, + "name": "conversionRate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "154:14:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "145:23:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 9, + "id": 13, + "nodeType": "Return", + "src": "138:30:0" + } + ] + }, + "documentation": null, + "id": 15, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "convert", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 6, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 3, + "name": "amount", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "67:11:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "67:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 5, + "name": "conversionRate", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "79:19:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "79:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "66:33:0" + }, + "payable": false, + "returnParameters": { + "id": 9, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8, + "name": "convertedAmount", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "109:20:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "109:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "108:22:0" + }, + "scope": 16, + "src": "50:123:0", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 17, + "src": "28:148:0" + } + ], + "src": "0:178:0" + }, + "legacyAST": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/ConvertLib.sol", + "exportedSymbols": { + "ConvertLib": [ + 16 + ] + }, + "id": 17, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:0" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "library", + "documentation": null, + "fullyImplemented": true, + "id": 16, + "linearizedBaseContracts": [ + 16 + ], + "name": "ConvertLib", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 14, + "nodeType": "Block", + "src": "133:40:0", + "statements": [ + { + "expression": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 12, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "id": 10, + "name": "amount", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "145:6:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "*", + "rightExpression": { + "argumentTypes": null, + "id": 11, + "name": "conversionRate", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 5, + "src": "154:14:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "145:23:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 9, + "id": 13, + "nodeType": "Return", + "src": "138:30:0" + } + ] + }, + "documentation": null, + "id": 15, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "convert", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 6, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 3, + "name": "amount", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "67:11:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "67:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + }, + { + "constant": false, + "id": 5, + "name": "conversionRate", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "79:19:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "79:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "66:33:0" + }, + "payable": false, + "returnParameters": { + "id": 9, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 8, + "name": "convertedAmount", + "nodeType": "VariableDeclaration", + "scope": 15, + "src": "109:20:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 7, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "109:4:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "108:22:0" + }, + "scope": 16, + "src": "50:123:0", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 17, + "src": "28:148:0" + } + ], + "src": "0:178:0" + }, + "compiler": { + "name": "solc", + "version": "0.4.21+commit.dfe3193c.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "2.0.0", + "updatedAt": "2018-04-14T03:37:39.678Z" +} \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/build/contracts/Example.json b/ethereum/src/main/resources/dev_truffle/build/contracts/Example.json new file mode 100644 index 0000000000..82111dab11 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/build/contracts/Example.json @@ -0,0 +1,251 @@ +{ + "contractName": "Example", + "abi": [ + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "constant": false, + "inputs": [], + "name": "ExampleFunction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60606040523415600e57600080fd5b60848061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029", + "deployedBytecode": "0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b818dacd146044575b600080fd5b3415604e57600080fd5b60546056565b005b5600a165627a7a72305820bebcbbdf06550591bc772dfcb0eadc842f95953869feb7a9528bac91487d95240029", + "sourceMap": "28:134:1:-;;;50:45;;;;;;;;28:134;;;;;;", + "deployedSourceMap": "28:134:1:-;;;;;;;;;;;;;;;;;;;;;;;;101:58;;;;;;;;;;;;;;;:::o", + "source": "pragma solidity ^0.4.17;\r\n\r\ncontract Example {\r\n function Example() {\r\n // constructor\r\n }\r\n\r\n function ExampleFunction() {\r\n // example function\r\n }\r\n}", + "sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\Example.sol", + "ast": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Example.sol", + "exportedSymbols": { + "Example": [ + 27 + ] + }, + "id": 28, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 18, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:1" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 27, + "linearizedBaseContracts": [ + 27 + ], + "name": "Example", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 21, + "nodeType": "Block", + "src": "69:26:1", + "statements": [] + }, + "documentation": null, + "id": 22, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "Example", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 19, + "nodeType": "ParameterList", + "parameters": [], + "src": "66:2:1" + }, + "payable": false, + "returnParameters": { + "id": 20, + "nodeType": "ParameterList", + "parameters": [], + "src": "69:0:1" + }, + "scope": 27, + "src": "50:45:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 25, + "nodeType": "Block", + "src": "128:31:1", + "statements": [] + }, + "documentation": null, + "id": 26, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "ExampleFunction", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 23, + "nodeType": "ParameterList", + "parameters": [], + "src": "125:2:1" + }, + "payable": false, + "returnParameters": { + "id": 24, + "nodeType": "ParameterList", + "parameters": [], + "src": "128:0:1" + }, + "scope": 27, + "src": "101:58:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 28, + "src": "28:134:1" + } + ], + "src": "0:162:1" + }, + "legacyAST": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Example.sol", + "exportedSymbols": { + "Example": [ + 27 + ] + }, + "id": 28, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 18, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:1" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 27, + "linearizedBaseContracts": [ + 27 + ], + "name": "Example", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 21, + "nodeType": "Block", + "src": "69:26:1", + "statements": [] + }, + "documentation": null, + "id": 22, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "Example", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 19, + "nodeType": "ParameterList", + "parameters": [], + "src": "66:2:1" + }, + "payable": false, + "returnParameters": { + "id": 20, + "nodeType": "ParameterList", + "parameters": [], + "src": "69:0:1" + }, + "scope": 27, + "src": "50:45:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 25, + "nodeType": "Block", + "src": "128:31:1", + "statements": [] + }, + "documentation": null, + "id": 26, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [], + "name": "ExampleFunction", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 23, + "nodeType": "ParameterList", + "parameters": [], + "src": "125:2:1" + }, + "payable": false, + "returnParameters": { + "id": 24, + "nodeType": "ParameterList", + "parameters": [], + "src": "128:0:1" + }, + "scope": 27, + "src": "101:58:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 28, + "src": "28:134:1" + } + ], + "src": "0:162:1" + }, + "compiler": { + "name": "solc", + "version": "0.4.21+commit.dfe3193c.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "2.0.0", + "updatedAt": "2018-04-14T03:37:39.710Z" +} \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/build/contracts/Migrations.json b/ethereum/src/main/resources/dev_truffle/build/contracts/Migrations.json new file mode 100644 index 0000000000..55f2c7ad69 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/build/contracts/Migrations.json @@ -0,0 +1,1380 @@ +{ + "contractName": "Migrations", + "abi": [ + { + "constant": true, + "inputs": [], + "name": "last_completed_migration", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "constant": false, + "inputs": [ + { + "name": "completed", + "type": "uint256" + } + ], + "name": "setCompleted", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "new_address", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x6060604052341561000f57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102d78061005e6000396000f300606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100a05780638da5cb5b146100c9578063fdacd5761461011e575b600080fd5b341561007257600080fd5b61009e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610141565b005b34156100ab57600080fd5b6100b3610220565b6040518082815260200191505060405180910390f35b34156100d457600080fd5b6100dc610226565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012957600080fd5b61013f600480803590602001909190505061024b565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561021c578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b151561020b57600080fd5b5af1151561021857600080fd5b5050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102a857806001819055505b505600a165627a7a72305820be5431ce1823a03470fc4376ec6fdfa9e54ca2bd2b05b6271c73eb54ad4e4b060029", + "deployedBytecode": "0x606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100a05780638da5cb5b146100c9578063fdacd5761461011e575b600080fd5b341561007257600080fd5b61009e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610141565b005b34156100ab57600080fd5b6100b3610220565b6040518082815260200191505060405180910390f35b34156100d457600080fd5b6100dc610226565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012957600080fd5b61013f600480803590602001909190505061024b565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561021c578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b151561020b57600080fd5b5af1151561021857600080fd5b5050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102a857806001819055505b505600a165627a7a72305820be5431ce1823a03470fc4376ec6fdfa9e54ca2bd2b05b6271c73eb54ad4e4b060029", + "sourceMap": "26:488:2:-;;;178:58;;;;;;;;221:10;213:5;;:18;;;;;;;;;;;;;;;;;;26:488;;;;;;", + "deployedSourceMap": "26:488:2:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;347:165;;;;;;;;;;;;;;;;;;;;;;;;;;;;74:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;240:103;;;;;;;;;;;;;;;;;;;;;;;;;;347:165;409:19;161:5;;;;;;;;;;;147:19;;:10;:19;;;143:26;;;442:11;409:45;;460:8;:21;;;482:24;;460:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;143:26;347:165;;:::o;74:36::-;;;;:::o;50:20::-;;;;;;;;;;;;;:::o;240:103::-;161:5;;;;;;;;;;;147:19;;:10;:19;;;143:26;;;329:9;302:24;:36;;;;143:26;240:103;:::o", + "source": "pragma solidity ^0.4.17;\n\ncontract Migrations {\n address public owner;\n uint public last_completed_migration;\n\n modifier restricted() {\n if (msg.sender == owner) _;\n }\n\n function Migrations() public {\n owner = msg.sender;\n }\n\n function setCompleted(uint completed) public restricted {\n last_completed_migration = completed;\n }\n\n function upgrade(address new_address) public restricted {\n Migrations upgraded = Migrations(new_address);\n upgraded.setCompleted(last_completed_migration);\n }\n}\n", + "sourcePath": "C:\\workspace\\current_workspace\\web3java\\dev_truffle\\contracts\\Migrations.sol", + "ast": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Migrations.sol", + "exportedSymbols": { + "Migrations": [ + 84 + ] + }, + "id": 85, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 29, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:2" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 84, + "linearizedBaseContracts": [ + 84 + ], + "name": "Migrations", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": false, + "id": 31, + "name": "owner", + "nodeType": "VariableDeclaration", + "scope": 84, + "src": "50:20:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 30, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "50:7:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 33, + "name": "last_completed_migration", + "nodeType": "VariableDeclaration", + "scope": 84, + "src": "74:36:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 32, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "74:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "public" + }, + { + "body": { + "id": 41, + "nodeType": "Block", + "src": "137:37:2", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 38, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 35, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "147:3:2", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 36, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "147:10:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 37, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31, + "src": "161:5:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "147:19:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 40, + "nodeType": "IfStatement", + "src": "143:26:2", + "trueBody": { + "id": 39, + "nodeType": "PlaceholderStatement", + "src": "168:1:2" + } + } + ] + }, + "documentation": null, + "id": 42, + "name": "restricted", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 34, + "nodeType": "ParameterList", + "parameters": [], + "src": "134:2:2" + }, + "src": "115:59:2", + "visibility": "internal" + }, + { + "body": { + "id": 50, + "nodeType": "Block", + "src": "207:29:2", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 48, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 45, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31, + "src": "213:5:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 46, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "221:3:2", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 47, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "221:10:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "213:18:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 49, + "nodeType": "ExpressionStatement", + "src": "213:18:2" + } + ] + }, + "documentation": null, + "id": 51, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "Migrations", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 43, + "nodeType": "ParameterList", + "parameters": [], + "src": "197:2:2" + }, + "payable": false, + "returnParameters": { + "id": 44, + "nodeType": "ParameterList", + "parameters": [], + "src": "207:0:2" + }, + "scope": 84, + "src": "178:58:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 62, + "nodeType": "Block", + "src": "296:47:2", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 60, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 58, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "302:24:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 59, + "name": "completed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "329:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "302:36:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 61, + "nodeType": "ExpressionStatement", + "src": "302:36:2" + } + ] + }, + "documentation": null, + "id": 63, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 56, + "modifierName": { + "argumentTypes": null, + "id": 55, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "285:10:2", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "285:10:2" + } + ], + "name": "setCompleted", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 54, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 53, + "name": "completed", + "nodeType": "VariableDeclaration", + "scope": 63, + "src": "262:14:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 52, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "262:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "261:16:2" + }, + "payable": false, + "returnParameters": { + "id": 57, + "nodeType": "ParameterList", + "parameters": [], + "src": "296:0:2" + }, + "scope": 84, + "src": "240:103:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 82, + "nodeType": "Block", + "src": "403:109:2", + "statements": [ + { + "assignments": [ + 71 + ], + "declarations": [ + { + "constant": false, + "id": 71, + "name": "upgraded", + "nodeType": "VariableDeclaration", + "scope": 83, + "src": "409:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + }, + "typeName": { + "contractScope": null, + "id": 70, + "name": "Migrations", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 84, + "src": "409:10:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 75, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 73, + "name": "new_address", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 65, + "src": "442:11:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 72, + "name": "Migrations", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 84, + "src": "431:10:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Migrations_$84_$", + "typeString": "type(contract Migrations)" + } + }, + "id": 74, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "431:23:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "409:45:2" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 79, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "482:24:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 76, + "name": "upgraded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 71, + "src": "460:8:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "id": 78, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "setCompleted", + "nodeType": "MemberAccess", + "referencedDeclaration": 63, + "src": "460:21:2", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256) external" + } + }, + "id": 80, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "460:47:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 81, + "nodeType": "ExpressionStatement", + "src": "460:47:2" + } + ] + }, + "documentation": null, + "id": 83, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 68, + "modifierName": { + "argumentTypes": null, + "id": 67, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "392:10:2", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "392:10:2" + } + ], + "name": "upgrade", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 66, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 65, + "name": "new_address", + "nodeType": "VariableDeclaration", + "scope": 83, + "src": "364:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 64, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "364:7:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "363:21:2" + }, + "payable": false, + "returnParameters": { + "id": 69, + "nodeType": "ParameterList", + "parameters": [], + "src": "403:0:2" + }, + "scope": 84, + "src": "347:165:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 85, + "src": "26:488:2" + } + ], + "src": "0:515:2" + }, + "legacyAST": { + "absolutePath": "/C/workspace/current_workspace/web3java/dev_truffle/contracts/Migrations.sol", + "exportedSymbols": { + "Migrations": [ + 84 + ] + }, + "id": 85, + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 29, + "literals": [ + "solidity", + "^", + "0.4", + ".17" + ], + "nodeType": "PragmaDirective", + "src": "0:24:2" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 84, + "linearizedBaseContracts": [ + 84 + ], + "name": "Migrations", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": false, + "id": 31, + "name": "owner", + "nodeType": "VariableDeclaration", + "scope": 84, + "src": "50:20:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 30, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "50:7:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "public" + }, + { + "constant": false, + "id": 33, + "name": "last_completed_migration", + "nodeType": "VariableDeclaration", + "scope": 84, + "src": "74:36:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 32, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "74:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "public" + }, + { + "body": { + "id": 41, + "nodeType": "Block", + "src": "137:37:2", + "statements": [ + { + "condition": { + "argumentTypes": null, + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 38, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 35, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "147:3:2", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 36, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "147:10:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "argumentTypes": null, + "id": 37, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31, + "src": "161:5:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "147:19:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": null, + "id": 40, + "nodeType": "IfStatement", + "src": "143:26:2", + "trueBody": { + "id": 39, + "nodeType": "PlaceholderStatement", + "src": "168:1:2" + } + } + ] + }, + "documentation": null, + "id": 42, + "name": "restricted", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 34, + "nodeType": "ParameterList", + "parameters": [], + "src": "134:2:2" + }, + "src": "115:59:2", + "visibility": "internal" + }, + { + "body": { + "id": 50, + "nodeType": "Block", + "src": "207:29:2", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 48, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 45, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 31, + "src": "213:5:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "expression": { + "argumentTypes": null, + "id": 46, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 97, + "src": "221:3:2", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 47, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "sender", + "nodeType": "MemberAccess", + "referencedDeclaration": null, + "src": "221:10:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "213:18:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 49, + "nodeType": "ExpressionStatement", + "src": "213:18:2" + } + ] + }, + "documentation": null, + "id": 51, + "implemented": true, + "isConstructor": true, + "isDeclaredConst": false, + "modifiers": [], + "name": "Migrations", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 43, + "nodeType": "ParameterList", + "parameters": [], + "src": "197:2:2" + }, + "payable": false, + "returnParameters": { + "id": 44, + "nodeType": "ParameterList", + "parameters": [], + "src": "207:0:2" + }, + "scope": 84, + "src": "178:58:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 62, + "nodeType": "Block", + "src": "296:47:2", + "statements": [ + { + "expression": { + "argumentTypes": null, + "id": 60, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "argumentTypes": null, + "id": 58, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "302:24:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "argumentTypes": null, + "id": 59, + "name": "completed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 53, + "src": "329:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "302:36:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 61, + "nodeType": "ExpressionStatement", + "src": "302:36:2" + } + ] + }, + "documentation": null, + "id": 63, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 56, + "modifierName": { + "argumentTypes": null, + "id": 55, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "285:10:2", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "285:10:2" + } + ], + "name": "setCompleted", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 54, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 53, + "name": "completed", + "nodeType": "VariableDeclaration", + "scope": 63, + "src": "262:14:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 52, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "262:4:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "261:16:2" + }, + "payable": false, + "returnParameters": { + "id": 57, + "nodeType": "ParameterList", + "parameters": [], + "src": "296:0:2" + }, + "scope": 84, + "src": "240:103:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": { + "id": 82, + "nodeType": "Block", + "src": "403:109:2", + "statements": [ + { + "assignments": [ + 71 + ], + "declarations": [ + { + "constant": false, + "id": 71, + "name": "upgraded", + "nodeType": "VariableDeclaration", + "scope": 83, + "src": "409:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + }, + "typeName": { + "contractScope": null, + "id": 70, + "name": "Migrations", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 84, + "src": "409:10:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 75, + "initialValue": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 73, + "name": "new_address", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 65, + "src": "442:11:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 72, + "name": "Migrations", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 84, + "src": "431:10:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_Migrations_$84_$", + "typeString": "type(contract Migrations)" + } + }, + "id": 74, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "431:23:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "409:45:2" + }, + { + "expression": { + "argumentTypes": null, + "arguments": [ + { + "argumentTypes": null, + "id": 79, + "name": "last_completed_migration", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 33, + "src": "482:24:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "argumentTypes": null, + "id": 76, + "name": "upgraded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 71, + "src": "460:8:2", + "typeDescriptions": { + "typeIdentifier": "t_contract$_Migrations_$84", + "typeString": "contract Migrations" + } + }, + "id": 78, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberName": "setCompleted", + "nodeType": "MemberAccess", + "referencedDeclaration": 63, + "src": "460:21:2", + "typeDescriptions": { + "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256) external" + } + }, + "id": 80, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "460:47:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 81, + "nodeType": "ExpressionStatement", + "src": "460:47:2" + } + ] + }, + "documentation": null, + "id": 83, + "implemented": true, + "isConstructor": false, + "isDeclaredConst": false, + "modifiers": [ + { + "arguments": [], + "id": 68, + "modifierName": { + "argumentTypes": null, + "id": 67, + "name": "restricted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "392:10:2", + "typeDescriptions": { + "typeIdentifier": "t_modifier$__$", + "typeString": "modifier ()" + } + }, + "nodeType": "ModifierInvocation", + "src": "392:10:2" + } + ], + "name": "upgrade", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 66, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 65, + "name": "new_address", + "nodeType": "VariableDeclaration", + "scope": 83, + "src": "364:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 64, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "364:7:2", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "363:21:2" + }, + "payable": false, + "returnParameters": { + "id": 69, + "nodeType": "ParameterList", + "parameters": [], + "src": "403:0:2" + }, + "scope": 84, + "src": "347:165:2", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 85, + "src": "26:488:2" + } + ], + "src": "0:515:2" + }, + "compiler": { + "name": "solc", + "version": "0.4.21+commit.dfe3193c.Emscripten.clang" + }, + "networks": {}, + "schemaVersion": "2.0.0", + "updatedAt": "2018-04-14T03:37:39.710Z" +} \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/contracts/ConvertLib.sol b/ethereum/src/main/resources/dev_truffle/contracts/ConvertLib.sol new file mode 100644 index 0000000000..ec0576fc3f --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/contracts/ConvertLib.sol @@ -0,0 +1,8 @@ +pragma solidity ^0.4.17; + +library ConvertLib{ + function convert(uint amount,uint conversionRate) returns (uint convertedAmount) + { + return amount * conversionRate; + } +} diff --git a/ethereum/src/main/resources/dev_truffle/contracts/Example.sol b/ethereum/src/main/resources/dev_truffle/contracts/Example.sol new file mode 100644 index 0000000000..c09c54843c --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/contracts/Example.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.4.17; + +contract Example { + function Example() { + // constructor + } + + function ExampleFunction() { + // example function + } +} \ No newline at end of file diff --git a/ethereum/src/main/resources/dev_truffle/contracts/Migrations.sol b/ethereum/src/main/resources/dev_truffle/contracts/Migrations.sol new file mode 100644 index 0000000000..f170cb4fa7 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/contracts/Migrations.sol @@ -0,0 +1,23 @@ +pragma solidity ^0.4.17; + +contract Migrations { + address public owner; + uint public last_completed_migration; + + modifier restricted() { + if (msg.sender == owner) _; + } + + function Migrations() public { + owner = msg.sender; + } + + function setCompleted(uint completed) public restricted { + last_completed_migration = completed; + } + + function upgrade(address new_address) public restricted { + Migrations upgraded = Migrations(new_address); + upgraded.setCompleted(last_completed_migration); + } +} diff --git a/ethereum/src/main/resources/dev_truffle/migrations/1_initial_migration.js b/ethereum/src/main/resources/dev_truffle/migrations/1_initial_migration.js new file mode 100644 index 0000000000..269ad95867 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/migrations/1_initial_migration.js @@ -0,0 +1,3 @@ +module.exports = deployer => { + deployer.deploy(artifacts.require("./Migrations.sol")); +}; diff --git a/ethereum/src/main/resources/dev_truffle/migrations/2_deploy_contracts.js b/ethereum/src/main/resources/dev_truffle/migrations/2_deploy_contracts.js new file mode 100644 index 0000000000..b6f30176ae --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/migrations/2_deploy_contracts.js @@ -0,0 +1,8 @@ +const Example = artifacts.require("./Example.sol"), + ConvertLib = artifacts.require("./ConvertLib.sol"); + +module.exports = deployer => { + deployer.deploy(ConvertLib); + deployer.link(ConvertLib, Example); + deployer.deploy(Example); +}; diff --git a/ethereum/src/main/resources/dev_truffle/truffle.js b/ethereum/src/main/resources/dev_truffle/truffle.js new file mode 100644 index 0000000000..8110fdad45 --- /dev/null +++ b/ethereum/src/main/resources/dev_truffle/truffle.js @@ -0,0 +1,20 @@ +module.exports = { + contracts_build_directory: "./build/contracts", + networks: { + live: { + network_id: 1, // Ethereum public network + host: 'localhost', + port: 8545 + }, + testnet: { + network_id: 3, // Official Ethereum test network (Ropsten) + host: 'localhost', + port: 8545 + }, + development: { + host: 'localhost', + port: 8545, + network_id: '*' + } + } +} diff --git a/ethereum/src/main/resources/logback.xml b/ethereum/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ethereum/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ethereumj/src/main/resources/solidity/Greeting.sol b/ethereum/src/main/resources/solidity/Greeting.sol similarity index 100% rename from ethereumj/src/main/resources/solidity/Greeting.sol rename to ethereum/src/main/resources/solidity/Greeting.sol diff --git a/ethereumj/src/main/resources/solidity/build/Greeting.abi b/ethereum/src/main/resources/solidity/build/Greeting.abi similarity index 100% rename from ethereumj/src/main/resources/solidity/build/Greeting.abi rename to ethereum/src/main/resources/solidity/build/Greeting.abi diff --git a/ethereumj/src/main/resources/solidity/build/Greeting.bin b/ethereum/src/main/resources/solidity/build/Greeting.bin similarity index 100% rename from ethereumj/src/main/resources/solidity/build/Greeting.bin rename to ethereum/src/main/resources/solidity/build/Greeting.bin diff --git a/spring-boot-logging-log4j2/src/main/resources/application.properties b/ethereum/src/main/webapp/WEB-INF/.gitkeep similarity index 100% rename from spring-boot-logging-log4j2/src/main/resources/application.properties rename to ethereum/src/main/webapp/WEB-INF/.gitkeep diff --git a/spring-data-spring-security/src/main/resources/application.properties b/ethereum/src/main/webapp/resources/.gitkeep similarity index 100% rename from spring-data-spring-security/src/main/resources/application.properties rename to ethereum/src/main/webapp/resources/.gitkeep diff --git a/ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java b/ethereum/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java similarity index 99% rename from ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java rename to ethereum/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java index f62d229261..7676b99224 100644 --- a/ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java +++ b/ethereum/src/test/java/com/baeldung/ethereumj/controllers/EthControllerLiveTest.java @@ -74,4 +74,4 @@ public class EthControllerLiveTest { assertTrue("Dynamic data returned?", a.hasBody()); System.out.println("Dynamic data returned?: " + a.hasBody()); } -} +} \ No newline at end of file diff --git a/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerIntegrationTest.java b/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerIntegrationTest.java new file mode 100644 index 0000000000..ee78ab17c2 --- /dev/null +++ b/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerIntegrationTest.java @@ -0,0 +1,78 @@ +package com.baeldung.web3j.controllers; + + +import com.baeldung.web3j.config.AppConfig; +import com.baeldung.web3j.constants.Constants; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {AppConfig.class}) +@WebAppConfiguration +public class EthereumRestControllerIntegrationTest { + + private MockMvc mockMvc; + + private void constructAsyncTest(String endpoint) { + try { + MvcResult asyncResult = mockMvc + .perform(get(endpoint)) + .andReturn(); + + mockMvc.perform(asyncDispatch(asyncResult)) + .andDo(print()) + .andExpect(status().isOk()); + + } catch (Exception e) { + System.out.println("Exception: " + e); + } + } + + @Autowired + private WebApplicationContext wac; + + @Before + public void preTest() throws Exception { + mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void accounts() { + constructAsyncTest(Constants.API_ACCOUNTS); + } + + @Test + public void transactions() { + constructAsyncTest(Constants.API_TRANSACTIONS); + } + + @Test + public void block() { + constructAsyncTest(Constants.API_BLOCK); + } + + @Test + public void balance() { + constructAsyncTest(Constants.API_BALANCE); + } + + @After + public void postTest() { + mockMvc = null; + } +} \ No newline at end of file diff --git a/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerUnitTest.java b/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerUnitTest.java new file mode 100644 index 0000000000..4ceed870f8 --- /dev/null +++ b/ethereum/src/test/java/com/baeldung/web3j/controllers/EthereumRestControllerUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.web3j.controllers; + +import com.baeldung.web3j.constants.Constants; +import com.baeldung.web3j.services.Web3Service; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class EthereumRestControllerUnitTest { + + private MockMvc mockMvc; + + private void constructAsyncTest(String endpoint) { + try { + MvcResult asyncResult = mockMvc + .perform(get(endpoint)) + .andReturn(); + + mockMvc.perform(asyncDispatch(asyncResult)) + .andDo(print()) + .andExpect(status().isOk()); + + } catch (Exception e) { + System.out.println("Exception: " + e); + } + } + + @Mock + private Web3Service web3Service; + + @InjectMocks + private EthereumRestController ethereumRestController; + + @Before + public void preTest() { + MockitoAnnotations.initMocks(this); + mockMvc = MockMvcBuilders.standaloneSetup(ethereumRestController).build(); + } + + @Test + public void accounts() { + constructAsyncTest(Constants.API_ACCOUNTS); + } + + @Test + public void transactions() { + constructAsyncTest(Constants.API_TRANSACTIONS); + } + + @Test + public void block() { + constructAsyncTest(Constants.API_BLOCK); + } + + @Test + public void balance() { + constructAsyncTest(Constants.API_BALANCE); + } + + @After + public void postTest() { + mockMvc = null; + } + +} diff --git a/ethereum/src/test/java/com/baeldung/web3j/services/EthereumContractUnitTest.java b/ethereum/src/test/java/com/baeldung/web3j/services/EthereumContractUnitTest.java new file mode 100644 index 0000000000..382c96e985 --- /dev/null +++ b/ethereum/src/test/java/com/baeldung/web3j/services/EthereumContractUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.web3j.services; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.CompletableFuture; + +public class EthereumContractUnitTest { + + private Web3Service web3Service; + + @Before + public void setup() { + web3Service = new Web3Service(); + } + + @Test + public void testContract() { + CompletableFuture result = web3Service.fromScratchContractExample(); + assert (result instanceof CompletableFuture); + } + + @Test + public void sendTx() { + CompletableFuture result = web3Service.sendTx(); + assert (result instanceof CompletableFuture); + } + + @After + public void cleanup() { + } +} diff --git a/ethereumj/pom.xml b/ethereumj/pom.xml deleted file mode 100644 index 6917505f1b..0000000000 --- a/ethereumj/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - 4.0.0 - com.baeldung.ethereumj - ethereumj - war - 1.0.0 - ethereumj - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-1 - - - - - Ethereum - Ethereum - https://dl.bintray.com/ethereum/maven/ - - - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-tomcat - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.ethereum - ethereumj-core - ${ethereumj-core.version} - - - - org.web3j - core - ${web3j.core.version} - - - - javax.servlet - jstl - - - com.fasterxml.jackson.core - jackson-databind - ${jackson-databind.version} - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - ethereumj - - - - UTF-8 - 1.8 - 8.5.4 - 1.5.0-RELEASE - 3.3.1 - 2.5.0 - - - \ No newline at end of file diff --git a/ethereumj/src/main/resources/logback.xml b/ethereumj/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ethereumj/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/feign/pom.xml b/feign/pom.xml index ffcde60c54..ea645383c1 100644 --- a/feign/pom.xml +++ b/feign/pom.xml @@ -1,10 +1,10 @@ - + 4.0.0 com.baeldung.feign - feign-client + feign + feign com.baeldung @@ -55,7 +55,6 @@ - UTF-8 9.4.0 1.16.12 1.4.2.RELEASE diff --git a/feign/src/main/resources/logback.xml b/feign/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/feign/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/flips/pom.xml b/flips/pom.xml index 34cbab7035..75dc8bb579 100644 --- a/flips/pom.xml +++ b/flips/pom.xml @@ -56,9 +56,6 @@ - UTF-8 - 1.8 - 1.8 1.5.10.RELEASE 1.5.9.RELEASE 1.0.1 diff --git a/flips/src/main/resources/logback.xml b/flips/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/flips/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/flyway-cdi-extension/README.md b/flyway-cdi-extension/README.md new file mode 100644 index 0000000000..3e03d5aee8 --- /dev/null +++ b/flyway-cdi-extension/README.md @@ -0,0 +1,3 @@ +### Relevant articles + +- [CDI Portable Extension and Flyway](https://www.baeldung.com/cdi-portable-extension) diff --git a/flyway-cdi-extension/pom.xml b/flyway-cdi-extension/pom.xml new file mode 100644 index 0000000000..c6ee26f783 --- /dev/null +++ b/flyway-cdi-extension/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + com.baeldung + flyway-cdi-extension + 1.0-SNAPSHOT + + + 1.8 + 1.8 + + + + + javax.enterprise + cdi-api + 2.0.SP1 + + + org.jboss.weld.se + weld-se-core + 3.0.5.Final + runtime + + + org.flywaydb + flyway-core + 5.1.4 + + + org.apache.tomcat + tomcat-jdbc + 8.5.33 + + + javax.annotation + javax.annotation-api + 1.3.2 + + + com.h2database + h2 + 1.4.197 + runtime + + + + diff --git a/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java new file mode 100644 index 0000000000..a5019b82c1 --- /dev/null +++ b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java @@ -0,0 +1,74 @@ +package com.baeldung.cdi.extension; + +import org.apache.tomcat.jdbc.pool.DataSource; +import org.flywaydb.core.Flyway; + +import javax.annotation.sql.DataSourceDefinition; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Default; +import javax.enterprise.inject.literal.InjectLiteral; +import javax.enterprise.inject.spi.*; +import javax.enterprise.util.AnnotationLiteral; + + +/** + * Flyway is now under CDI container like: + * + * @ApplicationScoped + * @FlywayType public class Flyway{ + * @Inject setDataSource(DataSource dataSource){ + * //... + * } + * } + */ + +public class FlywayExtension implements Extension { + + DataSourceDefinition dataSourceDefinition = null; + + public void registerFlywayType(@Observes BeforeBeanDiscovery bbdEvent) { + bbdEvent.addAnnotatedType(Flyway.class, Flyway.class.getName()); + } + + public void detectDataSourceDefinition(@Observes @WithAnnotations(DataSourceDefinition.class) ProcessAnnotatedType patEvent) { + AnnotatedType at = patEvent.getAnnotatedType(); + dataSourceDefinition = at.getAnnotation(DataSourceDefinition.class); + } + + public void processAnnotatedType(@Observes ProcessAnnotatedType patEvent) { + patEvent.configureAnnotatedType() + //Add Scope + .add(ApplicationScoped.Literal.INSTANCE) + //Add Qualifier + .add(new AnnotationLiteral() { + }) + //Decorate setDataSource(DataSource dataSource){} with @Inject + .filterMethods(annotatedMethod -> { + return annotatedMethod.getParameters().size() == 1 && + annotatedMethod.getParameters().get(0).getBaseType().equals(javax.sql.DataSource.class); + }) + .findFirst().get().add(InjectLiteral.INSTANCE); + } + + void afterBeanDiscovery(@Observes AfterBeanDiscovery abdEvent, BeanManager bm) { + abdEvent.addBean() + .types(javax.sql.DataSource.class, DataSource.class) + .qualifiers(new AnnotationLiteral() {}, new AnnotationLiteral() {}) + .scope(ApplicationScoped.class) + .name(DataSource.class.getName()) + .beanClass(DataSource.class) + .createWith(creationalContext -> { + DataSource instance = new DataSource(); + instance.setUrl(dataSourceDefinition.url()); + instance.setDriverClassName(dataSourceDefinition.className()); + return instance; + }); + } + + void runFlywayMigration(@Observes AfterDeploymentValidation adv, BeanManager manager) { + Flyway flyway = manager.createInstance().select(Flyway.class, new AnnotationLiteral() {}).get(); + flyway.migrate(); + } +} diff --git a/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayType.java b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayType.java new file mode 100644 index 0000000000..7c3a5affa6 --- /dev/null +++ b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayType.java @@ -0,0 +1,14 @@ +package com.baeldung.cdi.extension; + +import javax.inject.Qualifier; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({FIELD, METHOD, PARAMETER, TYPE}) +@Qualifier +public @interface FlywayType { +} \ No newline at end of file diff --git a/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/MainApp.java b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/MainApp.java new file mode 100644 index 0000000000..1f6c5b43ba --- /dev/null +++ b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/MainApp.java @@ -0,0 +1,16 @@ +package com.baeldung.cdi.extension; + +import javax.annotation.sql.DataSourceDefinition; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.se.SeContainer; +import javax.enterprise.inject.se.SeContainerInitializer; + +@ApplicationScoped +@DataSourceDefinition(name = "ds", className = "org.h2.Driver", url = "jdbc:h2:mem:testdb") +public class MainApp { + public static void main(String[] args) { + SeContainerInitializer initializer = SeContainerInitializer.newInstance(); + try (SeContainer container = initializer.initialize()) { + } + } +} \ No newline at end of file diff --git a/flyway-cdi-extension/src/main/resources/META-INF/beans.xml b/flyway-cdi-extension/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..44959bfa99 --- /dev/null +++ b/flyway-cdi-extension/src/main/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/flyway-cdi-extension/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/flyway-cdi-extension/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 0000000000..a82dc47714 --- /dev/null +++ b/flyway-cdi-extension/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1,2 @@ +com.baeldung.cdi.extension.FlywayExtension + diff --git a/flyway-cdi-extension/src/main/resources/db/migration/V1__Create_person_table.sql b/flyway-cdi-extension/src/main/resources/db/migration/V1__Create_person_table.sql new file mode 100644 index 0000000000..6bddc7689e --- /dev/null +++ b/flyway-cdi-extension/src/main/resources/db/migration/V1__Create_person_table.sql @@ -0,0 +1,4 @@ +create table PERSON ( + ID int not null, + NAME varchar(100) not null +); diff --git a/flyway-cdi-extension/src/main/resources/db/migration/V2__Add_people.sql b/flyway-cdi-extension/src/main/resources/db/migration/V2__Add_people.sql new file mode 100644 index 0000000000..d8f1d62667 --- /dev/null +++ b/flyway-cdi-extension/src/main/resources/db/migration/V2__Add_people.sql @@ -0,0 +1,3 @@ +insert into PERSON (ID, NAME) values (1, 'Axel'); +insert into PERSON (ID, NAME) values (2, 'Mr. Foo'); +insert into PERSON (ID, NAME) values (3, 'Ms. Bar'); diff --git a/flyway/pom.xml b/flyway/pom.xml index 018f9b7f86..353bbfb1ec 100644 --- a/flyway/pom.xml +++ b/flyway/pom.xml @@ -27,7 +27,7 @@ mysql mysql-connector-java - ${mysql-connector-java.version} + runtime com.h2database @@ -63,12 +63,9 @@ - UTF-8 - UTF-8 - 1.8 5.0.2 - 6.0.3 5.0.2 + 1.4.195 diff --git a/flyway/src/main/resources/logback.xml b/flyway/src/main/resources/logback.xml index 7f4aa46e0d..56af2d397e 100644 --- a/flyway/src/main/resources/logback.xml +++ b/flyway/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationTest.java b/flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationUnitTest.java similarity index 98% rename from flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationTest.java rename to flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationUnitTest.java index 5e96fff64d..bf30ce604d 100644 --- a/flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationTest.java +++ b/flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationUnitTest.java @@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) @ContextConfiguration(classes = FlywayCallbackTestConfig.class) -public class FlywayApplicationTest { +public class FlywayApplicationUnitTest { private Log log = LogFactory.getLog(getClass()); diff --git a/geotools/pom.xml b/geotools/pom.xml index 9347d17fc1..3ac8a63564 100644 --- a/geotools/pom.xml +++ b/geotools/pom.xml @@ -1,67 +1,62 @@ - - 4.0.0 - com.baeldung - geotools - 0.0.1-SNAPSHOT - jar - geotools - http://maven.apache.org + + 4.0.0 + geotools + 0.0.1-SNAPSHOT + jar + geotools + http://maven.apache.org - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + - - - junit - junit - ${junit.version} - test - - - org.geotools - gt-shapefile - ${geotools-shapefile.version} - - - org.geotools - gt-epsg-hsql - ${geotools.version} - - - org.geotools - gt-swing - ${geotools-swing.version} - - + + + org.geotools + gt-shapefile + ${geotools-shapefile.version} + + + org.geotools + gt-epsg-hsql + ${geotools.version} + + + org.geotools + gt-swing + ${geotools-swing.version} + + - - - maven2-repository.dev.java.net - Java.net repository - http://download.java.net/maven/2 - - - osgeo - Open Source Geospatial Foundation Repository - http://download.osgeo.org/webdav/geotools/ - - - - true - - opengeo - OpenGeo Maven Repository - http://repo.opengeo.org - - + + + maven2-repository.dev.java.net + Java.net repository + http://download.java.net/maven/2 + + + osgeo + Open Source Geospatial Foundation Repository + http://download.osgeo.org/webdav/geotools/ + + + + true + + opengeo + OpenGeo Maven Repository + http://repo.opengeo.org + + + + + 15.2 + 15.2 + 15.2 + - - 15.2 - 15.2 - 15.2 - diff --git a/geotools/src/main/resources/logback.xml b/geotools/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/geotools/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/google-cloud/pom.xml b/google-cloud/pom.xml index b6e54e33c1..85f47cc2f5 100644 --- a/google-cloud/pom.xml +++ b/google-cloud/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 google-cloud 0.1-SNAPSHOT @@ -31,7 +31,6 @@ 1.16.18 - UTF-8 1.16.0 diff --git a/google-cloud/src/main/resources/logback.xml b/google-cloud/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/google-cloud/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/google-web-toolkit/README.md b/google-web-toolkit/README.md new file mode 100644 index 0000000000..65264375bc --- /dev/null +++ b/google-web-toolkit/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Introduction to GWT](http://www.baeldung.com/gwt) +- [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter) diff --git a/google-web-toolkit/pom.xml b/google-web-toolkit/pom.xml new file mode 100644 index 0000000000..db9ce2eac0 --- /dev/null +++ b/google-web-toolkit/pom.xml @@ -0,0 +1,125 @@ + + + + + 4.0.0 + com.baeldung + google-web-toolkit + war + 1.0-SNAPSHOT + google-web-toolkit + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + + com.google.gwt + gwt + 2.8.2 + pom + import + + + + + + + com.google.gwt + gwt-servlet + runtime + + + com.google.gwt + gwt-user + provided + + + com.google.gwt + gwt-dev + provided + + + junit + junit + 4.11 + test + + + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/classes + + + + + + net.ltgt.gwt.maven + gwt-maven-plugin + 1.0-rc-8 + + + + compile + test + + + + + com.baeldung.Google_web_toolkit + Google_web_toolkit + true + + 1.8 + + + + -compileReport + -XcompilerMetrics + + + ${project.build.directory}/${project.build.finalName} + compile+runtime + + + Google_web_toolkit.html + + + + + + + maven-surefire-plugin + 2.17 + + true + + + + + + + + + + 1.8 + 1.8 + + + UTF-8 + UTF-8 + + + diff --git a/google-web-toolkit/src/main/java/com/baeldung/Google_web_toolkit.gwt.xml b/google-web-toolkit/src/main/java/com/baeldung/Google_web_toolkit.gwt.xml new file mode 100644 index 0000000000..9bd74ccb50 --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/Google_web_toolkit.gwt.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/google-web-toolkit/src/main/java/com/baeldung/client/Google_web_toolkit.java b/google-web-toolkit/src/main/java/com/baeldung/client/Google_web_toolkit.java new file mode 100644 index 0000000000..ae0ae7da38 --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/client/Google_web_toolkit.java @@ -0,0 +1,108 @@ +package com.baeldung.client; + +import com.baeldung.shared.MessageService; +import com.baeldung.shared.MessageServiceAsync; +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.KeyUpEvent; +import com.google.gwt.event.dom.client.KeyUpHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; + +/** + * Entry point classes define onModuleLoad(). + */ +public class Google_web_toolkit implements EntryPoint { + private final MessageServiceAsync messageServiceAsync = GWT.create(MessageService.class); + + public void onModuleLoad() { + Button sendButton = new Button("Submit"); + TextBox nameField = new TextBox(); + nameField.setText("Hi there"); + + Label warningLabel = new Label(); + + sendButton.addStyleName("sendButton"); + + RootPanel.get("nameFieldContainer").add(nameField); + RootPanel.get("sendButtonContainer").add(sendButton); + RootPanel.get("errorLabelContainer").add(warningLabel); + + Button closeButton = new Button("Thanks"); + closeButton.getElement().setId("closeButton"); + + Label textToServerLabel = new Label(); + HTML serverResponseLabel = new HTML(); + VerticalPanel vPanel = new VerticalPanel(); + vPanel.addStyleName("vPanel"); + vPanel.add(new HTML("Sending message to the server:")); + vPanel.add(textToServerLabel); + vPanel.add(new HTML("
Server replies:")); + vPanel.add(serverResponseLabel); + vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT); + vPanel.add(closeButton); + vPanel.setVisible(false); + RootPanel.get("serverResponseContainer").add(vPanel); + + closeButton.addClickHandler(event -> { + sendButton.setEnabled(true); + sendButton.setFocus(true); + vPanel.setVisible(false); + }); + + class MyHandler implements ClickHandler, KeyUpHandler { + + public void onClick(ClickEvent event) { + sendMessageToServer(); + } + + public void onKeyUp(KeyUpEvent event) { + if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { + sendMessageToServer(); + } + } + + private void sendMessageToServer() { + + warningLabel.setText(""); + String textToServer = nameField.getText(); + if (textToServer == null || textToServer.isEmpty()) { + warningLabel.setText("Please enter the message"); + return; + } + + sendButton.setEnabled(false); + textToServerLabel.setText(textToServer); + serverResponseLabel.setText(""); + messageServiceAsync.sendMessage(textToServer, new AsyncCallback() { + public void onFailure(Throwable caught) { + serverResponseLabel.addStyleName("serverResponseLabelError"); + serverResponseLabel.setHTML("server error occurred"); + closeButton.setFocus(true); + } + + public void onSuccess(String result) { + serverResponseLabel.removeStyleName("serverResponseLabelError"); + serverResponseLabel.setHTML(result); + closeButton.setFocus(true); + vPanel.setVisible(true); + } + }); + } + } + + // Add a handler to send the name to the server + MyHandler handler = new MyHandler(); + sendButton.addClickHandler(handler); + nameField.addKeyUpHandler(handler); + } +} diff --git a/google-web-toolkit/src/main/java/com/baeldung/server/MessageServiceImpl.java b/google-web-toolkit/src/main/java/com/baeldung/server/MessageServiceImpl.java new file mode 100644 index 0000000000..41e2a4725c --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/server/MessageServiceImpl.java @@ -0,0 +1,22 @@ +package com.baeldung.server; + +import com.baeldung.shared.MessageService; +import com.google.gwt.user.server.rpc.RemoteServiceServlet; + +import java.time.LocalDateTime; + +/** + * The server-side implementation of the RPC service. + */ +@SuppressWarnings("serial") +public class MessageServiceImpl extends RemoteServiceServlet implements MessageService { + + public String sendMessage(String message) throws IllegalArgumentException { + if (message == null) { + throw new IllegalArgumentException("message is null"); + } + + return "Hello, " + message + "!

Time received: " + LocalDateTime.now(); + } + +} diff --git a/google-web-toolkit/src/main/java/com/baeldung/shared/MessageService.java b/google-web-toolkit/src/main/java/com/baeldung/shared/MessageService.java new file mode 100644 index 0000000000..2c74a5c00d --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/shared/MessageService.java @@ -0,0 +1,12 @@ +package com.baeldung.shared; + +import com.google.gwt.user.client.rpc.RemoteService; +import com.google.gwt.user.client.rpc.RemoteServiceRelativePath; + +/** + * The client-side stub for the RPC service. + */ +@RemoteServiceRelativePath("greet") +public interface MessageService extends RemoteService { + String sendMessage(String message) throws IllegalArgumentException; +} diff --git a/google-web-toolkit/src/main/java/com/baeldung/shared/MessageServiceAsync.java b/google-web-toolkit/src/main/java/com/baeldung/shared/MessageServiceAsync.java new file mode 100644 index 0000000000..49d4a29b7b --- /dev/null +++ b/google-web-toolkit/src/main/java/com/baeldung/shared/MessageServiceAsync.java @@ -0,0 +1,10 @@ +package com.baeldung.shared; + +import com.google.gwt.user.client.rpc.AsyncCallback; + +/** + * The async counterpart of MessageService. + */ +public interface MessageServiceAsync { + void sendMessage(String input, AsyncCallback callback) throws IllegalArgumentException; +} diff --git a/google-web-toolkit/src/main/resources/logback.xml b/google-web-toolkit/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/google-web-toolkit/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/google-web-toolkit/src/main/webapp/Google_web_toolkit.css b/google-web-toolkit/src/main/webapp/Google_web_toolkit.css new file mode 100644 index 0000000000..b02f219589 --- /dev/null +++ b/google-web-toolkit/src/main/webapp/Google_web_toolkit.css @@ -0,0 +1,31 @@ +/** Add css rules here for your application. */ +h1 { + font-size: 2em; + font-weight: bold; + color: #777777; + margin: 40px 0px 70px; + text-align: center; +} + +.sendButton { + display: block; + font-size: 16pt; +} + +/** Most GWT widgets already have a style name defined */ +.gwt-DialogBox { + width: 400px; +} + +.vPanel { + margin: 5px; +} + +.serverResponseLabelError { + color: red; +} + +/** Set ids using widget.getElement().setId("idOfElement") */ +#closeButton { + margin: 15px 6px 6px; +} \ No newline at end of file diff --git a/google-web-toolkit/src/main/webapp/Google_web_toolkit.html b/google-web-toolkit/src/main/webapp/Google_web_toolkit.html new file mode 100644 index 0000000000..20bba68eff --- /dev/null +++ b/google-web-toolkit/src/main/webapp/Google_web_toolkit.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + Sample GWT Application + + + + + +

Sample GWT Application

+ + + + + + + + + + + + + + +
Please enter your message:
+ + \ No newline at end of file diff --git a/google-web-toolkit/src/main/webapp/WEB-INF/web.xml b/google-web-toolkit/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..820d3d9916 --- /dev/null +++ b/google-web-toolkit/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,24 @@ + + + + + + greetServlet + com.baeldung.server.MessageServiceImpl + + + + greetServlet + /google_web_toolkit/greet + + + + + Google_web_toolkit.html + + + diff --git a/google-web-toolkit/src/main/webapp/favicon.ico b/google-web-toolkit/src/main/webapp/favicon.ico new file mode 100644 index 0000000000..858a707523 Binary files /dev/null and b/google-web-toolkit/src/main/webapp/favicon.ico differ diff --git a/gradle/junit5/build.gradle b/gradle/junit5/build.gradle new file mode 100644 index 0000000000..5f056d8c23 --- /dev/null +++ b/gradle/junit5/build.gradle @@ -0,0 +1,25 @@ +plugins { + // Apply the java-library plugin to add support for Java Library + id 'java-library' +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1' + + // Only necessary for JUnit 3 and 4 tests + testCompileOnly 'junit:junit:4.12' + testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.3.1' + +} + +repositories { + jcenter() +} + +test { + useJUnitPlatform { + includeTags 'fast' + excludeTags 'slow' + } +} \ No newline at end of file diff --git a/gradle/junit5/src/test/java/com/example/CalculatorJUnit4Test.java b/gradle/junit5/src/test/java/com/example/CalculatorJUnit4Test.java new file mode 100644 index 0000000000..4cf63642ee --- /dev/null +++ b/gradle/junit5/src/test/java/com/example/CalculatorJUnit4Test.java @@ -0,0 +1,12 @@ +package com.example; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class CalculatorJUnit4Test { + @Test + public void testAdd() { + assertEquals(42, Integer.sum(19, 23)); + } +} diff --git a/gradle/junit5/src/test/java/com/example/CalculatorJUnit5Test.java b/gradle/junit5/src/test/java/com/example/CalculatorJUnit5Test.java new file mode 100644 index 0000000000..59fdb0f8ae --- /dev/null +++ b/gradle/junit5/src/test/java/com/example/CalculatorJUnit5Test.java @@ -0,0 +1,36 @@ +package com.example; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test;; + +public class CalculatorJUnit5Test { + + @Tag("fast") + @Test + public void testAdd() { + assertEquals(42, Integer.sum(19, 23)); + } + + @Tag("slow") + @Test + public void testAddMaxInteger() { + assertEquals(2147483646, Integer.sum(2147183646, 300000)); + } + + @Tag("fast") + @Test + public void testAddZero() { + assertEquals(21, Integer.sum(21, 0)); + } + + @Tag("fast") + @Test + public void testDivide() { + assertThrows(ArithmeticException.class, () -> { + Integer.divideUnsigned(42, 0); + }); + } +} diff --git a/gradle/settings.gradle b/gradle/settings.gradle index 38704681bd..f1d64de58a 100644 --- a/gradle/settings.gradle +++ b/gradle/settings.gradle @@ -5,6 +5,6 @@ include 'greeting-library' include 'greeting-library-java' include 'greeter' include 'gradletaskdemo' - +include 'junit5' println 'This will be executed during the initialization phase.' diff --git a/graphql/graphql-java/pom.xml b/graphql/graphql-java/pom.xml index 27d2cebf26..fb121d3234 100644 --- a/graphql/graphql-java/pom.xml +++ b/graphql/graphql-java/pom.xml @@ -1,5 +1,5 @@ + 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.graphql graphql-java diff --git a/graphql/graphql-java/src/main/resources/logback.xml b/graphql/graphql-java/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/graphql/graphql-java/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/grpc/pom.xml b/grpc/pom.xml index fb8312e8df..949f26d376 100644 --- a/grpc/pom.xml +++ b/grpc/pom.xml @@ -1,11 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - grpc - grpc-demo + grpc 0.0.1-SNAPSHOT jar - + grpc + com.baeldung parent-modules @@ -71,7 +71,6 @@ - UTF-8 1.5.0 1.5.0.Final 0.5.0 diff --git a/grpc/src/main/resources/logback.xml b/grpc/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/grpc/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/gson/README.md b/gson/README.md index bedfbd206c..4122b21431 100644 --- a/gson/README.md +++ b/gson/README.md @@ -7,3 +7,4 @@ - [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) +- [Save Data to a JSON File with Gson](https://www.baeldung.com/gson-save-file) diff --git a/gson/pom.xml b/gson/pom.xml index 9ef775122c..8222cb50e1 100644 --- a/gson/pom.xml +++ b/gson/pom.xml @@ -1,74 +1,73 @@ - 4.0.0 - com.baeldung - gson - 0.1-SNAPSHOT - gson + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + com.baeldung + gson + 0.1-SNAPSHOT + gson - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../parent-java - + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + - - - - org.projectlombok - lombok - 1.16.10 - provided - - - joda-time - joda-time - ${joda-time.version} - - - commons-io - commons-io - ${commons-io.version} - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - - com.google.code.gson - gson - ${gson.version} - - + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + joda-time + joda-time + ${joda-time.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + com.google.code.gson + gson + ${gson.version} + + - - gson - - - src/main/resources - true - - - + + gson + + + src/main/resources + true + + + - - - 2.8.0 - - 19.0 - 3.5 - 4.1 - 2.5 - 2.9.6 - + + + 2.8.0 + + 3.5 + 4.1 + 2.9.6 + 1.16.10 + \ No newline at end of file diff --git a/gson/src/main/java/org/baeldung/gson/entities/Employee.java b/gson/src/main/java/org/baeldung/gson/entities/Employee.java new file mode 100644 index 0000000000..cedcd6572e --- /dev/null +++ b/gson/src/main/java/org/baeldung/gson/entities/Employee.java @@ -0,0 +1,36 @@ +package org.baeldung.gson.entities; + +public class Employee { + private int id; + private String name; + private String address; + + public Employee(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } +} diff --git a/gson/src/main/java/org/baeldung/gson/entities/User.java b/gson/src/main/java/org/baeldung/gson/entities/User.java new file mode 100644 index 0000000000..b413f3300e --- /dev/null +++ b/gson/src/main/java/org/baeldung/gson/entities/User.java @@ -0,0 +1,19 @@ +package org.baeldung.gson.entities; + +public class User { + + private int id; + private String name; + private transient String nationality; + + public User(int id, String name, String nationality) { + this.id = id; + this.name = name; + this.nationality = nationality; + } + + public User(int id, String name) { + this(id, name, null); + } + +} diff --git a/gson/src/main/java/org/baeldung/gson/serialization/HashMapDeserializer.java b/gson/src/main/java/org/baeldung/gson/serialization/HashMapDeserializer.java new file mode 100644 index 0000000000..bb73e32559 --- /dev/null +++ b/gson/src/main/java/org/baeldung/gson/serialization/HashMapDeserializer.java @@ -0,0 +1,66 @@ +package org.baeldung.gson.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +import org.baeldung.gson.entities.Employee; + +import com.google.gson.*; + +public class HashMapDeserializer implements JsonDeserializer> { + + @Override + public HashMap deserialize(JsonElement elem, Type type, JsonDeserializationContext context) throws JsonParseException { + HashMap map = new HashMap<>(); + for (Map.Entry entry : elem.getAsJsonObject().entrySet()) { + JsonElement jsonValue = entry.getValue(); + Object value = null; + if (jsonValue.isJsonPrimitive()) { + value = toPrimitive(jsonValue.getAsJsonPrimitive(), context); + } else { + value = context.deserialize(jsonValue, Employee.class); + } + map.put(entry.getKey(), value); + } + return map; + + } + + private Object toPrimitive(JsonPrimitive jsonValue, JsonDeserializationContext context) { + if (jsonValue.isBoolean()) + return jsonValue.getAsBoolean(); + else if (jsonValue.isString()) + return jsonValue.getAsString(); + else { + BigDecimal bigDec = jsonValue.getAsBigDecimal(); + Long l; + Integer i; + if ((i = toInteger(bigDec)) != null) { + return i; + } else if ((l = toLong(bigDec)) != null) { + return l; + } else { + return bigDec.doubleValue(); + } + } + } + + private Long toLong(BigDecimal val) { + try { + return val.toBigIntegerExact().longValue(); + } catch (ArithmeticException e) { + return null; + } + } + + private Integer toInteger(BigDecimal val) { + try { + return val.intValueExact(); + } catch (ArithmeticException e) { + return null; + } + } + +} diff --git a/gson/src/main/resources/logback.xml b/gson/src/main/resources/logback.xml index ec0dc2469a..7bd5154680 100644 --- a/gson/src/main/resources/logback.xml +++ b/gson/src/main/resources/logback.xml @@ -2,18 +2,18 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - + + - + - + \ No newline at end of file diff --git a/gson/src/test/java/org/baeldung/gson/deserialization/HashMapDeserializationUnitTest.java b/gson/src/test/java/org/baeldung/gson/deserialization/HashMapDeserializationUnitTest.java new file mode 100644 index 0000000000..6905ade0da --- /dev/null +++ b/gson/src/test/java/org/baeldung/gson/deserialization/HashMapDeserializationUnitTest.java @@ -0,0 +1,86 @@ +package org.baeldung.gson.deserialization; + +import java.lang.reflect.Type; +import java.util.HashMap; + +import org.baeldung.gson.entities.Employee; +import org.baeldung.gson.serialization.HashMapDeserializer; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import com.google.gson.internal.LinkedTreeMap; +import com.google.gson.reflect.TypeToken; + +public class HashMapDeserializationUnitTest { + + private static final Logger logger = LoggerFactory.getLogger(HashMapDeserializationUnitTest.class); + + @Test + public void whenUsingHashMapClass_thenShouldReturnMapWithDefaultClasses() { + + String jsonString = "{'employee.name':'Bob','employee.salary':10000, 'employee.active':true, " + + "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}"; + + Gson gson = new Gson(); + HashMap map = gson.fromJson(jsonString, HashMap.class); + + logger.info("The converted map: {}", map); + Assert.assertEquals(4, map.size()); + Assert.assertEquals(Double.class, map.get("employee.salary").getClass()); + Assert.assertEquals(LinkedTreeMap.class, map.get("employee").getClass()); + + } + + @Test(expected = JsonSyntaxException.class) + public void whenUsingJsonStringWithDuplicateKey_thenShouldThrowJsonSyntaxException() { + + String jsonString = "{'employee.name':'Bob', 'employee.name':'Jenny','employee.salary':10000, " + + "'employee.active':true, " + "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}"; + + Gson gson = new Gson(); + HashMap map = gson.fromJson(jsonString, HashMap.class); + + logger.info("The converted map: {}", map); + } + + @Test + public void whenUsingTypeToken_thenShouldReturnMapWithProperClass() { + + String jsonString = "{'Bob':{'id':10, 'name': 'Bob Willis', 'address':'UK'}," + + "'Jenny':{'id':10, 'name': 'Jenny McCarthy', 'address':'USA'}, " + + "'Steve':{'id':10, 'name': 'Steven Waugh', 'address':'Australia'}}"; + + Gson gson = new Gson(); + Type empMapType = new TypeToken>(){}.getType(); + HashMap nameEmployeeMap = gson.fromJson(jsonString, empMapType); + + logger.info("The converted map: {}", nameEmployeeMap); + Assert.assertEquals(3, nameEmployeeMap.size()); + Assert.assertEquals(Employee.class, nameEmployeeMap.get("Bob").getClass()); + } + + @Test + public void whenUsingCustomDeserializer_thenShouldReturnMapWithProperClass() { + + String jsonString = "{'employee.name':'Bob','employee.salary':10000, 'employee.active':true, " + + "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}"; + + Type type = new TypeToken>(){}.getType(); + Gson gson = new GsonBuilder() + .registerTypeAdapter(type, new HashMapDeserializer()) + .create(); + HashMap blendedMap = gson.fromJson(jsonString, type); + + logger.info("The converted map: {}", blendedMap); + Assert.assertEquals(4, blendedMap.size()); + Assert.assertEquals(Integer.class, blendedMap.get("employee.salary").getClass()); + Assert.assertEquals(Employee.class, blendedMap.get("employee").getClass()); + + } + +} diff --git a/gson/src/test/java/org/baeldung/gson/serialization/test/JsonFileUnitTest.java b/gson/src/test/java/org/baeldung/gson/serialization/test/JsonFileUnitTest.java new file mode 100644 index 0000000000..f6a8de080c --- /dev/null +++ b/gson/src/test/java/org/baeldung/gson/serialization/test/JsonFileUnitTest.java @@ -0,0 +1,43 @@ +package org.baeldung.gson.serialization.test; + +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.baeldung.gson.entities.User; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +@RunWith(Parameterized.class) +public class JsonFileUnitTest { + + @Parameter + public Object object; + + @Parameters + public static Object[] data() { + return new Object[] { 123.45, new User(1, "Tom", "American") }; + } + + @Test + public void givenProperData_whenStoredInFile_shouldSaveJsonSuccessfully() { + String filePath = "target/output.json"; + try (Writer writer = new FileWriter(filePath)) { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + gson.toJson(object, writer); + Assert.assertTrue(Files.exists(Paths.get(filePath))); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/gson/src/test/resources/logback-test.xml b/gson/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..7bd5154680 --- /dev/null +++ b/gson/src/test/resources/logback-test.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/out/production/main151/com/baeldung/.gitignore b/guava-collections/.gitignore similarity index 100% rename from out/production/main151/com/baeldung/.gitignore rename to guava-collections/.gitignore diff --git a/guava-collections/README.md b/guava-collections/README.md new file mode 100644 index 0000000000..eb1eb1d35c --- /dev/null +++ b/guava-collections/README.md @@ -0,0 +1,20 @@ +========= + +## Guava and Hamcrest Cookbooks and Examples + + +### Relevant Articles: +- [Guava Collections Cookbook](http://www.baeldung.com/guava-collections) +- [Guava Ordering Cookbook](http://www.baeldung.com/guava-order) +- [Hamcrest Collections Cookbook](http://www.baeldung.com/hamcrest-collections-arrays) +- [Partition a List in Java](http://www.baeldung.com/java-list-split) +- [Filtering and Transforming Collections in Guava](http://www.baeldung.com/guava-filter-and-transform-a-collection) +- [Guava – Join and Split Collections](http://www.baeldung.com/guava-joiner-and-splitter-tutorial) +- [Guava – Lists](http://www.baeldung.com/guava-lists) +- [Guava – Sets](http://www.baeldung.com/guava-sets) +- [Guava – Maps](http://www.baeldung.com/guava-maps) +- [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap) +- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) +- [Guide to Guava RangeMap](http://www.baeldung.com/guava-rangemap) +- [Guide to Guava MinMaxPriorityQueue and EvictingQueue](http://www.baeldung.com/guava-minmax-priority-queue-and-evicting-queue) +- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) \ No newline at end of file diff --git a/guava-collections/pom.xml b/guava-collections/pom.xml new file mode 100644 index 0000000000..a717023156 --- /dev/null +++ b/guava-collections/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + com.baeldung + guava-collections + 0.1.0-SNAPSHOT + guava-collections + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + org.hamcrest + java-hamcrest + ${java-hamcrest.version} + test + + + + + guava + + + src/main/resources + true + + + + + + + 24.0-jre + 3.5 + 4.1 + + + 3.6.1 + 2.0.0.0 + + + \ No newline at end of file diff --git a/guava-collections/src/main/resources/logback.xml b/guava-collections/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/guava-collections/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/guava/src/test/java/org/baeldung/guava/EvictingQueueUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/EvictingQueueUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/EvictingQueueUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/EvictingQueueUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaCollectionsExamplesUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionsExamplesUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaCollectionsExamplesUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionsExamplesUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaFilterTransformCollectionsUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaFilterTransformCollectionsUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaFilterTransformCollectionsUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaFilterTransformCollectionsUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMapFromSet.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSet.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaMapFromSet.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSet.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java diff --git a/guava-collections/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java new file mode 100644 index 0000000000..69a7505316 --- /dev/null +++ b/guava-collections/src/test/java/org/baeldung/guava/GuavaMapInitializeUnitTest.java @@ -0,0 +1,30 @@ +package org.baeldung.guava; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.*; + +import java.util.Map; +import org.junit.Test; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; + +public class GuavaMapInitializeUnitTest { + + @Test + public void givenKeyValuesShoudInitializeMap() { + Map articles = ImmutableMap.of("Title", "My New Article", "Title2", "Second Article"); + + assertThat(articles.get("Title"), equalTo("My New Article")); + assertThat(articles.get("Title2"), equalTo("Second Article")); + + } + + + @Test + public void givenKeyValuesShouldCreateMutableMap() { + Map articles = Maps.newHashMap(ImmutableMap.of("Title", "My New Article", "Title2", "Second Article")); + + assertThat(articles.get("Title"), equalTo("My New Article")); + assertThat(articles.get("Title2"), equalTo("Second Article")); + } +} diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMultiMapUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaMultiMapUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaMultiMapUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaMultiMapUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaOrderingExamplesUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaOrderingExamplesUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaOrderingExamplesUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaOrderingExamplesUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaOrderingUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaOrderingUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaOrderingUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaOrderingUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaRangeMapUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaRangeMapUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaRangeMapUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaRangeMapUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java diff --git a/guava/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java similarity index 98% rename from guava/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java index 631ca454c0..a08efd7c31 100644 --- a/guava/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java +++ b/guava-collections/src/test/java/org/baeldung/guava/GuavaStringUnitTest.java @@ -92,7 +92,7 @@ public class GuavaStringUnitTest { @Test public void whenSplitStringOnMultipleSeparator_thenSplit() { final String input = "apple.banana,,orange,,."; - final List result = Splitter.onPattern("[.|,]").omitEmptyStrings().splitToList(input); + final List result = Splitter.onPattern("[.,]").omitEmptyStrings().splitToList(input); assertThat(result, contains("apple", "banana", "orange")); } diff --git a/guava/src/test/java/org/baeldung/guava/MinMaxPriorityQueueUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/MinMaxPriorityQueueUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/guava/MinMaxPriorityQueueUnitTest.java rename to guava-collections/src/test/java/org/baeldung/guava/MinMaxPriorityQueueUnitTest.java diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java b/guava-collections/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java rename to guava-collections/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java diff --git a/guava/src/test/java/org/baeldung/java/CollectionApachePartitionUnitTest.java b/guava-collections/src/test/java/org/baeldung/java/CollectionApachePartitionUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/java/CollectionApachePartitionUnitTest.java rename to guava-collections/src/test/java/org/baeldung/java/CollectionApachePartitionUnitTest.java diff --git a/guava/src/test/java/org/baeldung/java/CollectionGuavaPartitionUnitTest.java b/guava-collections/src/test/java/org/baeldung/java/CollectionGuavaPartitionUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/java/CollectionGuavaPartitionUnitTest.java rename to guava-collections/src/test/java/org/baeldung/java/CollectionGuavaPartitionUnitTest.java diff --git a/guava/src/test/java/org/baeldung/java/CollectionJavaPartitionUnitTest.java b/guava-collections/src/test/java/org/baeldung/java/CollectionJavaPartitionUnitTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/java/CollectionJavaPartitionUnitTest.java rename to guava-collections/src/test/java/org/baeldung/java/CollectionJavaPartitionUnitTest.java diff --git a/out/production/main330/com/baeldung/.gitignore b/guava-collections/src/test/resources/.gitignore similarity index 100% rename from out/production/main330/com/baeldung/.gitignore rename to guava-collections/src/test/resources/.gitignore diff --git a/guava-collections/src/test/resources/test.out b/guava-collections/src/test/resources/test.out new file mode 100644 index 0000000000..7a79da3803 --- /dev/null +++ b/guava-collections/src/test/resources/test.out @@ -0,0 +1 @@ +John Jane Adam Tom \ No newline at end of file diff --git a/guava-collections/src/test/resources/test1.in b/guava-collections/src/test/resources/test1.in new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/guava-collections/src/test/resources/test1.in @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/guava-collections/src/test/resources/test1_1.in b/guava-collections/src/test/resources/test1_1.in new file mode 100644 index 0000000000..8318c86b35 --- /dev/null +++ b/guava-collections/src/test/resources/test1_1.in @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/guava-collections/src/test/resources/test2.in b/guava-collections/src/test/resources/test2.in new file mode 100644 index 0000000000..622efea9e6 --- /dev/null +++ b/guava-collections/src/test/resources/test2.in @@ -0,0 +1,4 @@ +John +Jane +Adam +Tom \ No newline at end of file diff --git a/guava-collections/src/test/resources/test_copy.in b/guava-collections/src/test/resources/test_copy.in new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/guava-collections/src/test/resources/test_copy.in @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/guava-collections/src/test/resources/test_le.txt b/guava-collections/src/test/resources/test_le.txt new file mode 100644 index 0000000000..f7cc484bf4 Binary files /dev/null and b/guava-collections/src/test/resources/test_le.txt differ diff --git a/guava-modules/guava-18/pom.xml b/guava-modules/guava-18/pom.xml index b3deb305f2..ce9395fbf4 100644 --- a/guava-modules/guava-18/pom.xml +++ b/guava-modules/guava-18/pom.xml @@ -1,6 +1,6 @@ + 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 guava-18 @@ -9,8 +9,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../../parent-java + 0.0.1-SNAPSHOT + ../../parent-java diff --git a/guava-modules/guava-18/src/main/resources/logback.xml b/guava-modules/guava-18/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guava-modules/guava-18/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guava-modules/guava-19/pom.xml b/guava-modules/guava-19/pom.xml index 9eb20d5bbe..5dfb4d2cec 100644 --- a/guava-modules/guava-19/pom.xml +++ b/guava-modules/guava-19/pom.xml @@ -1,6 +1,6 @@ + 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 guava-19 @@ -9,8 +9,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../../parent-java + 0.0.1-SNAPSHOT + ../../parent-java diff --git a/guava-modules/guava-19/src/main/resources/logback.xml b/guava-modules/guava-19/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guava-modules/guava-19/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guava-modules/guava-21/pom.xml b/guava-modules/guava-21/pom.xml index 7038810d24..945b7c27c1 100644 --- a/guava-modules/guava-21/pom.xml +++ b/guava-modules/guava-21/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 guava-21 1.0-SNAPSHOT @@ -8,8 +8,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../../parent-java + 0.0.1-SNAPSHOT + ../../parent-java diff --git a/guava-modules/guava-21/src/main/resources/logback.xml b/guava-modules/guava-21/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guava-modules/guava-21/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guava/README.md b/guava/README.md index bb4e225649..7501bf08de 100644 --- a/guava/README.md +++ b/guava/README.md @@ -4,30 +4,17 @@ ### Relevant Articles: -- [Guava Collections Cookbook](http://www.baeldung.com/guava-collections) -- [Guava Ordering Cookbook](http://www.baeldung.com/guava-order) - [Guava Functional Cookbook](http://www.baeldung.com/guava-functions-predicates) -- [Hamcrest Collections Cookbook](http://www.baeldung.com/hamcrest-collections-arrays) -- [Partition a List in Java](http://www.baeldung.com/java-list-split) -- [Filtering and Transforming Collections in Guava](http://www.baeldung.com/guava-filter-and-transform-a-collection) -- [Guava – Join and Split Collections](http://www.baeldung.com/guava-joiner-and-splitter-tutorial) - [Guava – Write to File, Read from File](http://www.baeldung.com/guava-write-to-file-read-from-file) -- [Guava – Lists](http://www.baeldung.com/guava-lists) -- [Guava – Sets](http://www.baeldung.com/guava-sets) -- [Guava – Maps](http://www.baeldung.com/guava-maps) - [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial) - [Guide to Guava’s Ordering](http://www.baeldung.com/guava-ordering) - [Guide to Guava’s PreConditions](http://www.baeldung.com/guava-preconditions) - [Introduction to Guava CacheLoader](http://www.baeldung.com/guava-cacheloader) - [Introduction to Guava Memoizer](http://www.baeldung.com/guava-memoizer) - [Guide to Guava’s EventBus](http://www.baeldung.com/guava-eventbus) -- [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap) -- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) -- [Guide to Guava RangeMap](http://www.baeldung.com/guava-rangemap) - [Guide to Guava Table](http://www.baeldung.com/guava-table) - [Guide to Guava’s Reflection Utilities](http://www.baeldung.com/guava-reflection) - [Guide to Guava ClassToInstanceMap](http://www.baeldung.com/guava-class-to-instance-map) -- [Guide to Guava MinMaxPriorityQueue and EvictingQueue](http://www.baeldung.com/guava-minmax-priority-queue-and-evicting-queue) - [Guide to Mathematical Utilities in Guava](http://www.baeldung.com/guava-math) - [Bloom Filter in Java using Guava](http://www.baeldung.com/guava-bloom-filter) - [Using Guava CountingOutputStream](http://www.baeldung.com/guava-counting-outputstream) diff --git a/guava/pom.xml b/guava/pom.xml index b36506f87a..1d37a79ab6 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -1,5 +1,5 @@ + 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 guava @@ -9,17 +9,11 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - org.apache.commons commons-lang3 @@ -56,7 +50,6 @@ 24.0-jre 3.5 - 4.1 3.6.1 diff --git a/guava/src/main/resources/logback.xml b/guava/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/guava/src/main/resources/logback.xml +++ b/guava/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/guava/src/test/java/org/baeldung/guava/GuavaMemoizerUnitTest.java b/guava/src/test/java/org/baeldung/guava/GuavaMemoizerUnitTest.java index 1f934347b4..8c37ecf07c 100644 --- a/guava/src/test/java/org/baeldung/guava/GuavaMemoizerUnitTest.java +++ b/guava/src/test/java/org/baeldung/guava/GuavaMemoizerUnitTest.java @@ -73,7 +73,7 @@ public class GuavaMemoizerUnitTest { // then assertSupplierGetExecutionResultAndDuration(memoizedSupplier, expectedValue, 0D); // add one more second until memoized Supplier is evicted from memory - TimeUnit.SECONDS.sleep(1); + TimeUnit.SECONDS.sleep(3); assertSupplierGetExecutionResultAndDuration(memoizedSupplier, expectedValue, 2000D); } diff --git a/guest/core-java-9/pom.xml b/guest/core-java-9/pom.xml index f8e2dcce85..e9271b42ff 100644 --- a/guest/core-java-9/pom.xml +++ b/guest/core-java-9/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 com.stackify core-java-9 @@ -11,14 +12,6 @@ ../../ - - - junit - junit - ${junit.version} - - - diff --git a/guest/core-java-9/src/main/resources/logback.xml b/guest/core-java-9/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/core-java-9/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/core-java/pom.xml b/guest/core-java/pom.xml index b3c6ba9564..787dd764a1 100644 --- a/guest/core-java/pom.xml +++ b/guest/core-java/pom.xml @@ -13,34 +13,11 @@ - - junit - junit - ${junit.version} - org.apache.logging.log4j log4j-core ${log4j2.version} - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-all - ${org.hamcrest.version} - test - org.assertj assertj-core @@ -51,7 +28,6 @@ 2.8.2 - 1.3 3.6.1 diff --git a/kotlin-ktor/.gitignore b/guest/core-kotlin/.gitignore similarity index 100% rename from kotlin-ktor/.gitignore rename to guest/core-kotlin/.gitignore diff --git a/guest/core-kotlin/pom.xml b/guest/core-kotlin/pom.xml new file mode 100644 index 0000000000..6b189143a4 --- /dev/null +++ b/guest/core-kotlin/pom.xml @@ -0,0 +1,199 @@ + + + 4.0.0 + core-kotlin + 1.0-SNAPSHOT + com.stackify + jar + + + + jcenter + http://jcenter.bintray.com + + + + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin-stdlib.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin-stdlib.version} + + + org.jetbrains.kotlin + kotlin-test-junit + ${kotlin-test-junit.version} + test + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin-reflect.version} + + + org.jetbrains.spek + spek-api + 1.1.5 + test + + + org.jetbrains.spek + spek-subject-extension + 1.1.5 + test + + + org.jetbrains.spek + spek-junit-platform-engine + 1.1.5 + test + + + com.nhaarman + mockito-kotlin + ${mockito-kotlin.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + test + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin-maven-plugin.version} + provided + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin-maven-plugin.version} + + + compile + + compile + + + + ${project.basedir}/src/main/kotlin + + + + + test-compile + + test-compile + + + + ${project.basedir}/src/test/kotlin + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + + compile + + + + + + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + junit5 + + integration-test + verify + + + + **/*Test5.java + + + + + + + + + + 2.22.0 + UTF-8 + 1.2.60 + 1.2.51 + 1.2.51 + 1.2.51 + 0.22.5 + 1.5.0 + 3.6.1 + 1.0.0 + 5.2.0 + 3.10.0 + 3.7.0 + + + diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/CompanionObjectTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/CompanionObjectTest.kt new file mode 100644 index 0000000000..69573fb75b --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/CompanionObjectTest.kt @@ -0,0 +1,21 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class CompanionObjectTest { + + @Test + fun givenAClassWithCompanionObject_whenCallingMethodTheSameAsStaticOne_thenWeGetAResult() { + assertEquals("A", A.returnClassName()) + } + +} + +class A { + companion object { + fun returnClassName(): String { + return "A" + } + } +} \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ConstructorTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ConstructorTest.kt new file mode 100644 index 0000000000..fdb5d05db5 --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ConstructorTest.kt @@ -0,0 +1,18 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class ConstructorTests { + + @Test + fun givenAClassWithPrimaryConstructor_whenCreatingAnInstance_thenWeGetObject() { + var example = Example(1, "Example") + + assertEquals(1, example.id) + assertEquals("Example", example.name) + } + +} + +class Example constructor(val id: Int, var name: String) \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DataClassTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DataClassTest.kt new file mode 100644 index 0000000000..ad79538d3c --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DataClassTest.kt @@ -0,0 +1,33 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse + +class DataClassTest { + + @Test + fun givenASampleDataClass_whenCallingToStringMethod_thenItReturnsAllProperties() { + val student = Student(1, "John", "Smith") + + assertEquals(1, student.id) + assertEquals("John", student.name) + assertEquals("Smith", student.lastName) + assertEquals("Student(id=1, name=John, lastName=Smith)", student.toString()) + } + + @Test + fun givenASampleDataClass_whenCreatingACopyWithGeneratedFunction_thenItReturnsACopyWithRequestedChanges() { + val student = Student(1, "John", "Smith") + val student2 = student.copy(id = 2, name = "Anne") + + assertEquals(2, student2.id) + assertEquals("Anne", student2.name) + assertEquals("Smith", student2.lastName) + assertEquals("Student(id=2, name=Anne, lastName=Smith)", student2.toString()) + assertFalse(student.equals(student2)) + } + +} + +data class Student(val id: Int, val name: String, val lastName: String) \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DelegationTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DelegationTest.kt new file mode 100644 index 0000000000..2da824c2db --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/DelegationTest.kt @@ -0,0 +1,27 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class DelegationTest { + + @Test + fun givenAClassWithDelegation_whenCallDelegatedMethod_thenWeGetAResultDefinedInPassedObject() { + val car = Car(V6Engine()) + + assertEquals("Vroom", car.makeSound()) + } + +} + +interface Engine { + fun makeSound(): String +} + +class V6Engine: Engine { + override fun makeSound(): String { + return "Vroom" + } +} + +class Car(e: Engine) : Engine by e \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExceptionsTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExceptionsTest.kt new file mode 100644 index 0000000000..073c4dd890 --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExceptionsTest.kt @@ -0,0 +1,34 @@ +package com.baeldung.kotlinvsjava + +import java.io.IOException +import kotlin.test.Test +import kotlin.test.assertEquals + +class ExceptionsTest { + + @Test + fun givenATryExpression_whenReturning5InLastExpressionOfTryBlock_thenWeGet5() { + val value: Int = try { 5 } catch (e: IOException) { 6 } + + assertEquals(5, value) + } + + @Test + fun givenATryExpression_whenReturning6InLastExpressionOfCatchBlock_thenWeGet6() { + val value: Int = try { funThrowingException() } catch (e: IOException) { 6 } + + assertEquals(6, value) + } + + @org.junit.Test(expected = IllegalArgumentException::class) + fun givenANullString_whenUsingElvisOperator_thenExceptionIsThrown() { + val sampleString: String? = null + + sampleString?.length ?: throw IllegalArgumentException("String must not be null") + } + + private fun funThrowingException(): Nothing { + throw IOException() + } + +} \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExtensionFunctionsTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExtensionFunctionsTest.kt new file mode 100644 index 0000000000..3db73b6d2d --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/ExtensionFunctionsTest.kt @@ -0,0 +1,30 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class ExtensionFunctionsTest { + + @Test + fun givenAStringWithAnExtensionFunction_whenCallingThatFunction_thenItConcatenatesStrings() { + val sampleString = "ABC" + val concatenatedString = sampleString.appendString("DEF") + + assertEquals("ABCDEF", concatenatedString) + } + + @Test + fun givenAStringWithAnExtensionProperty_whenReadingProperty_thenItReturnsLengthOfString() { + val sampleString = "ABC" + + assertEquals(3, sampleString.size) + } + + fun String.appendString(str : String): String { + return plus(str) + } + + val String.size: Int + get() = length + +} \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/FunctionsTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/FunctionsTest.kt new file mode 100644 index 0000000000..6176478dfe --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/FunctionsTest.kt @@ -0,0 +1,70 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals + +class FunctionsTest { + + @Test + fun givenALambdaExpressionConcatenatingString_whenUsingTheFunctionWithAAndBString_thenWeGetAB() { + val concat: (String, String) -> String = { a, b -> a + b } + + assertEquals("AB", concat("A","B")) + } + + @Test + fun givenAnAnonymousFunctionConcatenatingString_whenUsingTheFunctionWithAAndBString_thenWeGetAB() { + val concat: (String, String) -> String = fun(a: String, b: String): String { return a + b } + + assertEquals("AB", concat("A","B")) + } + + @Test + fun givenAnPlusMethodOfString_whenUsingTheFunctionWithAAndBString_thenWeGetAB() { + val concat = String::plus + + assertEquals("AB", concat("A","B")) + } + + @Test + fun givenAStringConstractorAssignedToFunction_whenUsingFunctionReference_thenWeGetNewString() { + val concat = ::String + + assertEquals("A", concat().plus("A")) + } + + @Test + fun givenAClassImplementingAFunctionType_whenUsingTheFunctionWithAAndBString_thenWeGetAB() { + val concat = StringConcatenation() + + assertEquals("AB", concat("A", "B")) + } + + @Test + fun givenALambdaExpressionWithReceiver_whenUsingTheFunctionWithReceiver_thenWeGetABC() { + val concat: String.(String, String) -> String = { a, b -> plus(a).plus(b) } + + assertEquals("ABC", "A".concat("B", "C")) + } + + @Test + fun givenALambdaExpressionWithinLambdaExpression_whenUsingTheFunction_thenWeGetAB() { + val concat: (String) -> ((String) -> String) = { a -> {b -> a + b} } + + assertEquals("AB", (concat("A")("B"))) + } + + @Test + fun given3NestedLambdaExpression_whenUsingTheFunction_thenWeGetABC() { + val concat: (String) -> (String) -> (String) -> String = { a -> {b -> { c -> a + b + c} } } + + assertEquals("ABC", concat("A")("B")("C")) + } + +} + +class StringConcatenation: (String, String) -> String { + override fun invoke(p1: String, p2: String): String { + return p1 + p2 + } +} \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/IsOperatorTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/IsOperatorTest.kt new file mode 100644 index 0000000000..1817602cdf --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/IsOperatorTest.kt @@ -0,0 +1,36 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.math.absoluteValue +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class IsOperatorTest { + + @Test + fun givenSampleValue_whenUsingIsOperatorInIfStatement_thenItCastsAutomaticallyToString() { + val value: Any = "string" + + if(value is String) { + assertEquals(6, value.length) + } + } + + @Test + fun givenSampleValue_whenUsingIsOperatorWithAndOperator_thenItCastsAutomaticallyToString() { + val value: Any = "string" + + assertTrue(value is String && value.length == 6) + } + + @Test + fun givenSampleValue_whenUsingWithWhenOperator_thenItCastsAutomaticallyToString() { + val value: Any = "string" + + when(value) { + is String -> assertEquals(6, value.length) + is Int -> assertEquals(6, value.absoluteValue) + } + } + +} \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/NullSafetyTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/NullSafetyTest.kt new file mode 100644 index 0000000000..8cb3cbc761 --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/NullSafetyTest.kt @@ -0,0 +1,67 @@ +package com.baeldung.kotlinvsjava + +import kotlin.test.Test +import java.lang.NullPointerException +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull + +class NullSafetyTest { + + @Test + fun givenStringAndNull_whenUsingSafeCallOperatorWithLengthMethod_thenReturnsLengthForStringAndNullForNull() { + val stringValue: String? = "string" + val nullValue: String? = null + + assertNotNull(stringValue?.length) + assertNull(nullValue?.length) + } + + @Test(expected = NullPointerException::class) + fun givenNullReference_whenUsingTheNotNullAssertionOperator_thenItThrowsNullPointerException() { + val stringValue: String? = "string" + val nullValue: String? = null + + assertNotNull(stringValue!!.length) + nullValue!!.length + } + + @Test + fun givenStringAndNull_whenUsingElvisOperator_thenItTestsAgainstNullAndReturnsTheProperValue() { + val stringValue: String? = "string" + val nullValue: String? = null + + val shouldBeLength: Int = stringValue?.length ?: -1 + val souldBeMinusOne: Int = nullValue?.length ?: -1 + + assertEquals(6, shouldBeLength) + assertEquals(-1, souldBeMinusOne) + } + + @Test + fun givenString_whenCastingToInt_thenItReturnsNull() { + val stringValue: String? = "string" + + val intValue: Int? = stringValue as? Int + + assertNull(intValue) + } + + @Test + fun givenCollectionWithNulls_whenFilterNonNull_thenItReturnsCollectionWithoutNulls() { + val list: List = listOf("a", "b", null) + val nonNullList = list.filterNotNull() + + assertEquals(2, nonNullList.size) + assertEquals(nonNullList, listOf("a", "b")) + } + + @Test + fun givenCollectionWithNulls_whenLetWithSafeCallOperator_thenItOmitsNulls() { + val list: List = listOf("a", "b", null) + for(elem in list) { + elem?.let { assertNotNull(it) } + } + } + +} \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/OperatorsOverloadingTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/OperatorsOverloadingTest.kt new file mode 100644 index 0000000000..a28008da20 --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/OperatorsOverloadingTest.kt @@ -0,0 +1,61 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class OperatorsOverloadingTest { + + @Test + fun givenThePlaneClassWithOverloadedIncrementationOperator_whenCallingTheOperator_thenItIncreasesSpeed(){ + var plane = Plane(0.0) + + plane++ + assertEquals(50.0, plane.currentSpeed) + } + + @Test + fun givenThePlaneClassWithOverloadedMinusOperator_whenCallingTheOperator_thenItDecreaseSpeed(){ + var plane = Plane(1000.0) + + plane - 500.0 + assertEquals(500.0, plane.currentSpeed) + } + + @Test + fun givenThePlaneClassWithOverloadedInvokeOperator_whenCallingTheOperator_thenItSetSpeed(){ + var plane = Plane(0.0) + + plane(150.0) + assertEquals(150.0, plane.currentSpeed) + } + + @Test + fun given2PlaneObjectWithOverloadedComparisonOperator_whenCallingTheOperator_thenItComparesSpeedValues(){ + var plane = Plane(0.0) + var plane2 = Plane(150.0) + + assertTrue(plane < (plane2)) + } + +} + +class Plane(var currentSpeed: Double) { + + operator fun inc(): Plane { + currentSpeed += 50.0 + return this + } + + operator fun minus(number: Double) { + currentSpeed = if(currentSpeed < number) 0.0 else currentSpeed - number + } + + operator fun invoke(speed: Double) { + currentSpeed = speed + } + + operator fun compareTo(plane: Plane): Int { + return currentSpeed.compareTo(plane.currentSpeed) + } +} \ No newline at end of file diff --git a/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/PropertiesTest.kt b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/PropertiesTest.kt new file mode 100644 index 0000000000..95abcd68a2 --- /dev/null +++ b/guest/core-kotlin/src/test/kotlin/com/baeldung/kotlinvsjava/PropertiesTest.kt @@ -0,0 +1,32 @@ +package com.baeldung.kotlinvsjava + +import org.junit.Test +import java.math.BigDecimal +import kotlin.test.assertEquals + +class PropertiesTest { + + @Test + fun givenASampleClassWithValAndVarProperties_whenSettingPrice_thenWeGetZeroOrOne() { + val product = Product() + product.price = BigDecimal(10) + + val product2 = Product() + product2.price = null + + assertEquals("empty", product.id) + assertEquals("empty", product2.id) + assertEquals(BigDecimal(10), product.price) + assertEquals(BigDecimal(1), product2.price) + } + +} + +class Product { + + val id: String? = "empty" + + var price: BigDecimal? = BigDecimal.ZERO + set(value) = if(value == null) { field = BigDecimal.ONE} else { field = value } + +} \ No newline at end of file diff --git a/guest/deep-jsf/pom.xml b/guest/deep-jsf/pom.xml index bd02b145d0..e09b5e0606 100644 --- a/guest/deep-jsf/pom.xml +++ b/guest/deep-jsf/pom.xml @@ -1,27 +1,24 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.stackify deep-jsf 0.0.1-SNAPSHOT war + com.baeldung parent-modules 1.0.0-SNAPSHOT ../../ - - false - - + javax javaee-api - 7.0 + ${javaee-api.version} provided @@ -31,4 +28,9 @@ deep-jsf + + false + 7.0 + + \ No newline at end of file diff --git a/guest/deep-jsf/src/main/resources/logback.xml b/guest/deep-jsf/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/deep-jsf/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/junit5-example/pom.xml b/guest/junit5-example/pom.xml index 93ce207940..457fb1fcaa 100644 --- a/guest/junit5-example/pom.xml +++ b/guest/junit5-example/pom.xml @@ -1,52 +1,50 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 junit5-example junit5-example 0.0.1-SNAPSHOT + com.baeldung parent-modules 1.0.0-SNAPSHOT ../../ + org.junit.jupiter junit-jupiter-params - 5.0.0-M4 + ${junit.jupiter.version} - org.junit.vintage junit-vintage-engine - 4.12.0-M4 + ${junit-vintage.version} - com.h2database h2 - 1.4.195 + ${h2.version} - org.apache.logging.log4j log4j-core - 2.8.2 + ${log4j-core.version} - maven-surefire-plugin - 2.19.1 + ${maven-surefire-plugin.version} org.junit.platform junit-platform-surefire-provider - 1.0.0-M4 + ${junit-platform-surefire-provider.version} @@ -57,8 +55,12 @@ - + - + 5.0.0-M4 + 4.12.0-M4 + 1.4.195 + 2.8.2 + 1.0.0-M4 \ No newline at end of file diff --git a/guest/log4j2-example/pom.xml b/guest/log4j2-example/pom.xml index 760af88a06..f64869879f 100644 --- a/guest/log4j2-example/pom.xml +++ b/guest/log4j2-example/pom.xml @@ -1,15 +1,17 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 log4j2-example log4j2-example 0.0.1-SNAPSHOT + com.baeldung parent-modules 1.0.0-SNAPSHOT ../../ + @@ -24,12 +26,6 @@ jackson-databind ${jackson.version} - - - junit - junit - 4.12 - diff --git a/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java b/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceUnitTest.java similarity index 98% rename from guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java rename to guest/log4j2-example/src/test/java/com/stackify/services/MyServiceUnitTest.java index 49e367e45b..bd08225be4 100644 --- a/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java +++ b/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceUnitTest.java @@ -18,9 +18,9 @@ import org.junit.Test; import com.stackify.models.User; import com.stackify.services.MyService; -public class MyServiceTest { +public class MyServiceUnitTest { - private static final Logger logger = LogManager.getLogger(MyServiceTest.class); + private static final Logger logger = LogManager.getLogger(MyServiceUnitTest.class); @Test public void testService() { diff --git a/guest/logback-example/pom.xml b/guest/logback-example/pom.xml index d913db26bd..04de6a00a2 100644 --- a/guest/logback-example/pom.xml +++ b/guest/logback-example/pom.xml @@ -4,29 +4,23 @@ com.stackify logback-example 0.0.1-SNAPSHOT + com.baeldung parent-modules 1.0.0-SNAPSHOT ../../ + - - ch.qos.logback - logback-classic - 1.2.3 - - - - junit - junit - 4.12 - - org.codehaus.janino janino - 3.0.7 + ${janino.version} + + + 3.0.7 + \ No newline at end of file diff --git a/guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceTest.java b/guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceUnitTest.java similarity index 98% rename from guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceTest.java rename to guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceUnitTest.java index 187b27e1df..a3051f7087 100644 --- a/guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceTest.java +++ b/guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceUnitTest.java @@ -9,7 +9,7 @@ import com.stackify.models.Employee; import ch.qos.logback.classic.Level; -public class EmployeeServiceTest { +public class EmployeeServiceUnitTest { private static final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); private EmployeeService employeeService = new EmployeeService(); diff --git a/guest/memory-leaks/pom.xml b/guest/memory-leaks/pom.xml index 0bb201dd2f..956ae9c408 100644 --- a/guest/memory-leaks/pom.xml +++ b/guest/memory-leaks/pom.xml @@ -1,5 +1,5 @@ + 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 memory-leaks @@ -12,14 +12,6 @@ ../../ - - - junit - junit - ${junit.version} - - - diff --git a/guest/remote-debugging/pom.xml b/guest/remote-debugging/pom.xml index 6e077fce56..974421de97 100644 --- a/guest/remote-debugging/pom.xml +++ b/guest/remote-debugging/pom.xml @@ -1,17 +1,18 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.stackify - java-remote-debugging + remote-debugging 0.0.1-SNAPSHOT war + remote-debugging org.springframework.boot spring-boot-starter-parent - ${spring-boot-starter-parent.version} - + 1.5.8.RELEASE + @@ -38,7 +39,6 @@ UTF-8 UTF-8 - 1.5.8.RELEASE diff --git a/guest/remote-debugging/src/main/resources/logback.xml b/guest/remote-debugging/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/remote-debugging/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/spring-boot-app/pom.xml b/guest/spring-boot-app/pom.xml index c02eef7ef3..7daa8f668e 100644 --- a/guest/spring-boot-app/pom.xml +++ b/guest/spring-boot-app/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 spring-boot-app spring-boot-app @@ -38,15 +39,9 @@ maven-compiler-plugin - 3.7.0 - - 1.8 - 1.8 - maven-war-plugin - 3.1.0 WebContent @@ -72,6 +67,8 @@ 8.0.43 + UTF-8 + 1.8 diff --git a/guest/spring-boot-app/src/main/resources/logback.xml b/guest/spring-boot-app/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/spring-boot-app/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/spring-mvc/pom.xml b/guest/spring-mvc/pom.xml index da4d27b14d..c0ef451605 100644 --- a/guest/spring-mvc/pom.xml +++ b/guest/spring-mvc/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.stackify.guest spring-mvc @@ -12,8 +12,8 @@ org.springframework.boot spring-boot-starter-parent - ${spring-boot-starter-parent.version} - + 2.0.0.RELEASE + @@ -30,7 +30,6 @@ UTF-8 UTF-8 - 2.0.0.M5 diff --git a/guest/spring-mvc/src/main/resources/logback.xml b/guest/spring-mvc/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/spring-mvc/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/spring-security/pom.xml b/guest/spring-security/pom.xml index 793df750de..8be42ba32b 100644 --- a/guest/spring-security/pom.xml +++ b/guest/spring-security/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.stackify.guest spring-security @@ -12,8 +11,8 @@ org.springframework.boot spring-boot-starter-parent - ${spring-boot-starter-parent.version} - + 2.0.0.RELEASE + @@ -49,7 +48,6 @@ UTF-8 UTF-8 3.0.8.RELEASE - 2.0.0.M6 \ No newline at end of file diff --git a/guest/spring-security/src/main/resources/logback.xml b/guest/spring-security/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/spring-security/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/thread-pools/pom.xml b/guest/thread-pools/pom.xml index 56173b1285..db9a5ac89f 100644 --- a/guest/thread-pools/pom.xml +++ b/guest/thread-pools/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.stackify thread-pools @@ -12,16 +12,4 @@ ../../ - - - ch.qos.logback - logback-classic - ${logback-classic.version} - - - - - 1.2.3 - - \ No newline at end of file diff --git a/guest/thread-pools/src/main/resources/logback.xml b/guest/thread-pools/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/thread-pools/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/tomcat-app/pom.xml b/guest/tomcat-app/pom.xml index f3447b08c3..7fd27e869b 100644 --- a/guest/tomcat-app/pom.xml +++ b/guest/tomcat-app/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.stackify tomcat-app @@ -29,15 +29,11 @@ rest-assured ${rest-assured.version} - - junit - junit - ${junit.version} - com.h2database h2 ${h2database.version} + runtime org.apache.logging.log4j @@ -55,7 +51,7 @@ maven-war-plugin - 3.0.0 + ${maven-war-plugin.version} WebContent @@ -64,13 +60,13 @@ - 1.2.3 2.25.1 1.4.195 3.0.3 2.8.2 1.69.0 2.25.1 + 3.0.0 \ No newline at end of file diff --git a/guest/tomcat-app/src/main/resources/logback.xml b/guest/tomcat-app/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/tomcat-app/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/webservices/rest-client/pom.xml b/guest/webservices/rest-client/pom.xml index 84f4eaf3c0..5e52b7161c 100644 --- a/guest/webservices/rest-client/pom.xml +++ b/guest/webservices/rest-client/pom.xml @@ -25,8 +25,4 @@ - - 2.6 - - \ No newline at end of file diff --git a/guest/webservices/rest-server/pom.xml b/guest/webservices/rest-server/pom.xml index 955afdd82c..4b3d241293 100644 --- a/guest/webservices/rest-server/pom.xml +++ b/guest/webservices/rest-server/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.stackify rest-server @@ -29,11 +29,6 @@ rest-assured ${rest-assured.version} - - junit - junit - ${junit.version} - @@ -49,7 +44,6 @@ - 3.0.0 2.25.1 3.0.3 2.25.1 diff --git a/guest/webservices/rest-server/src/main/resources/logback.xml b/guest/webservices/rest-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/webservices/rest-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java b/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceLiveTest.java similarity index 95% rename from guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java rename to guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceLiveTest.java index 064951fbbe..be3992b7f7 100644 --- a/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java +++ b/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceLiveTest.java @@ -6,7 +6,7 @@ import io.restassured.RestAssured; import static io.restassured.RestAssured.*; import static org.hamcrest.CoreMatchers.*; -public class UserServiceTest { +public class UserServiceLiveTest { @Test public void whenAddUser_thenGetUserOk() { RestAssured.baseURI = "http://localhost:8080/rest-server"; diff --git a/guest/webservices/soap_client/src/main/resources/logback.xml b/guest/webservices/soap_client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/webservices/soap_client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/webservices/soap_example/src/main/resources/logback.xml b/guest/webservices/soap_example/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/webservices/soap_example/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guest/webservices/spring-rest-service/pom.xml b/guest/webservices/spring-rest-service/pom.xml index 74b76ee725..49d35766e8 100644 --- a/guest/webservices/spring-rest-service/pom.xml +++ b/guest/webservices/spring-rest-service/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.stackify spring-rest-service @@ -9,7 +9,7 @@ org.springframework.boot spring-boot-starter-parent - ${spring-boot-starter-parent.version} + 1.5.4.RELEASE @@ -38,10 +38,6 @@ org.springframework.boot spring-boot-maven-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - @@ -49,11 +45,9 @@ UTF-8 UTF-8 - 1.5.4.RELEASE + 1.8 2.7.0 2.7.0 - 1.8 - 1.8 \ No newline at end of file diff --git a/guest/webservices/spring-rest-service/src/main/resources/logback.xml b/guest/webservices/spring-rest-service/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guest/webservices/spring-rest-service/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/guice/pom.xml b/guice/pom.xml index ba0ed39c4a..f3e7873245 100644 --- a/guice/pom.xml +++ b/guice/pom.xml @@ -1,6 +1,6 @@ + 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.examples.guice guice @@ -23,7 +23,6 @@ - UTF-8 4.1.0 diff --git a/guice/src/main/resources/logback.xml b/guice/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/guice/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/hazelcast/README.md b/hazelcast/README.md index b90f66a8d0..7adb13f2af 100644 --- a/hazelcast/README.md +++ b/hazelcast/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [Guide to Hazelcast with Java](http://www.baeldung.com/java-hazelcast) +- [Introduction to Hazelcast Jet](https://www.baeldung.com/hazelcast-jet) diff --git a/hazelcast/pom.xml b/hazelcast/pom.xml index aa7faa07cf..705792ad05 100644 --- a/hazelcast/pom.xml +++ b/hazelcast/pom.xml @@ -1,5 +1,5 @@ + 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 hazelcast @@ -13,16 +13,12 @@ - - com.hazelcast - hazelcast - ${hazelcast.version} - - - com.hazelcast - hazelcast-client - ${hazelcast.version} - + + + com.hazelcast.jet + hazelcast-jet + ${hazelcast.jet.version} + @@ -36,8 +32,8 @@ - - 3.8.4 + + 0.6 \ No newline at end of file diff --git a/hazelcast/src/main/java/com/baeldung/hazelcast/jet/WordCounter.java b/hazelcast/src/main/java/com/baeldung/hazelcast/jet/WordCounter.java new file mode 100644 index 0000000000..971986bcae --- /dev/null +++ b/hazelcast/src/main/java/com/baeldung/hazelcast/jet/WordCounter.java @@ -0,0 +1,51 @@ +package com.baeldung.hazelcast.jet; + +import java.util.List; +import java.util.Map; + +import static com.hazelcast.jet.Traversers.traverseArray; +import static com.hazelcast.jet.aggregate.AggregateOperations.counting; +import static com.hazelcast.jet.function.DistributedFunctions.wholeItem; + +import com.hazelcast.jet.Jet; +import com.hazelcast.jet.JetInstance; +import com.hazelcast.jet.pipeline.Pipeline; +import com.hazelcast.jet.pipeline.Sinks; +import com.hazelcast.jet.pipeline.Sources; + +public class WordCounter { + + private static final String LIST_NAME = "textList"; + + private static final String MAP_NAME = "countMap"; + + private Pipeline createPipeLine() { + Pipeline p = Pipeline.create(); + p.drawFrom(Sources. list(LIST_NAME)) + .flatMap(word -> traverseArray(word.toLowerCase() + .split("\\W+"))) + .filter(word -> !word.isEmpty()) + .groupingKey(wholeItem()) + .aggregate(counting()) + .drainTo(Sinks.map(MAP_NAME)); + return p; + } + + public Long countWord(List sentences, String word) { + long count = 0; + JetInstance jet = Jet.newJetInstance(); + try { + List textList = jet.getList(LIST_NAME); + textList.addAll(sentences); + Pipeline p = createPipeLine(); + jet.newJob(p) + .join(); + Map counts = jet.getMap(MAP_NAME); + count = counts.get(word); + } finally { + Jet.shutdownAll(); + } + return count; + } + +} diff --git a/hazelcast/src/main/resources/logback.xml b/hazelcast/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/hazelcast/src/main/resources/logback.xml +++ b/hazelcast/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/hazelcast/src/test/java/com/baeldung/hazelcast/jet/WordCounterUnitTest.java b/hazelcast/src/test/java/com/baeldung/hazelcast/jet/WordCounterUnitTest.java new file mode 100644 index 0000000000..95596b3860 --- /dev/null +++ b/hazelcast/src/test/java/com/baeldung/hazelcast/jet/WordCounterUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.hazelcast.jet; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +public class WordCounterUnitTest { + + @Test + public void whenGivenSentencesAndWord_ThenReturnCountOfWord() { + List sentences = new ArrayList<>(); + sentences.add("The first second was alright, but the second second was tough."); + WordCounter wordCounter = new WordCounter(); + long countSecond = wordCounter.countWord(sentences, "second"); + assertTrue(countSecond == 3); + } + +} diff --git a/hbase/pom.xml b/hbase/pom.xml index ff4aa15130..117cf72e30 100644 --- a/hbase/pom.xml +++ b/hbase/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 hbase diff --git a/hbase/src/main/resources/logback.xml b/hbase/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/hbase/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/hibernate5/README.md b/hibernate5/README.md index afba239919..fbf46eed50 100644 --- a/hibernate5/README.md +++ b/hibernate5/README.md @@ -12,4 +12,8 @@ - [@Immutable in Hibernate](http://www.baeldung.com/hibernate-immutable) - [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking) - [Bootstrapping JPA Programmatically in Java](http://www.baeldung.com/java-bootstrap-jpa) - +- [Optimistic Locking in JPA](http://www.baeldung.com/jpa-optimistic-locking) +- [Hibernate Entity Lifecycle](https://www.baeldung.com/hibernate-entity-lifecycle) +- [Mapping A Hibernate Query to a Custom Class](https://www.baeldung.com/hibernate-query-to-custom-class) +- [@JoinColumn Annotation Explained](https://www.baeldung.com/jpa-join-column) +- [Hibernate 5 Naming Strategy Configuration](https://www.baeldung.com/hibernate-naming-strategy) diff --git a/hibernate5/pom.xml b/hibernate5/pom.xml index 6ed13b8ae4..610c893bdc 100644 --- a/hibernate5/pom.xml +++ b/hibernate5/pom.xml @@ -1,13 +1,10 @@ - + 4.0.0 com.baeldung hibernate5 0.0.1-SNAPSHOT - hibernate5 - http://maven.apache.org com.baeldung @@ -21,11 +18,6 @@ hibernate-core ${hibernate.version} - - junit - junit - ${junit.version} - org.assertj assertj-core @@ -65,10 +57,7 @@ - UTF-8 - - 3.7.0 - 5.2.12.Final + 5.3.2.Final 6.0.6 2.2.3 1.4.196 diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index 23d7d2e201..2212e736ab 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -1,5 +1,11 @@ package com.baeldung.hibernate; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +import com.baeldung.hibernate.entities.DeptEmployee; import com.baeldung.hibernate.optimisticlocking.OptimisticLockingCourse; import com.baeldung.hibernate.optimisticlocking.OptimisticLockingStudent; import com.baeldung.hibernate.pessimisticlocking.Individual; @@ -16,10 +22,30 @@ import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.service.ServiceRegistry; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.URL; -import java.util.Properties; +import com.baeldung.hibernate.pojo.Course; +import com.baeldung.hibernate.pojo.Employee; +import com.baeldung.hibernate.pojo.EntityDescription; +import com.baeldung.hibernate.pojo.OrderEntry; +import com.baeldung.hibernate.pojo.OrderEntryIdClass; +import com.baeldung.hibernate.pojo.OrderEntryPK; +import com.baeldung.hibernate.pojo.Person; +import com.baeldung.hibernate.pojo.Phone; +import com.baeldung.hibernate.pojo.PointEntity; +import com.baeldung.hibernate.pojo.PolygonEntity; +import com.baeldung.hibernate.pojo.Product; +import com.baeldung.hibernate.pojo.Student; +import com.baeldung.hibernate.pojo.TemporalValues; +import com.baeldung.hibernate.pojo.User; +import com.baeldung.hibernate.pojo.UserProfile; +import com.baeldung.hibernate.pojo.inheritance.Animal; +import com.baeldung.hibernate.pojo.inheritance.Bag; +import com.baeldung.hibernate.pojo.inheritance.Book; +import com.baeldung.hibernate.pojo.inheritance.Car; +import com.baeldung.hibernate.pojo.inheritance.MyEmployee; +import com.baeldung.hibernate.pojo.inheritance.MyProduct; +import com.baeldung.hibernate.pojo.inheritance.Pen; +import com.baeldung.hibernate.pojo.inheritance.Pet; +import com.baeldung.hibernate.pojo.inheritance.Vehicle; public class HibernateUtil { private static SessionFactory sessionFactory; @@ -72,6 +98,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(DeptEmployee.class); + metadataSources.addAnnotatedClass(com.baeldung.hibernate.entities.Department.class); metadataSources.addAnnotatedClass(OptimisticLockingCourse.class); metadataSources.addAnnotatedClass(OptimisticLockingStudent.class); diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java b/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java new file mode 100644 index 0000000000..ff94f4f849 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java @@ -0,0 +1,45 @@ +package com.baeldung.hibernate.entities; + +import java.util.List; + +import javax.persistence.*; + +@Entity +public class Department { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private long id; + + private String name; + + @OneToMany(mappedBy="department") + private List employees; + + public Department(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 List getEmployees() { + return employees; + } + + public void setEmployees(List employees) { + this.employees = employees; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java b/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java new file mode 100644 index 0000000000..7a51009b62 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java @@ -0,0 +1,65 @@ +package com.baeldung.hibernate.entities; + +import javax.persistence.*; + +@Entity +public class DeptEmployee { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private long id; + + private String employeeNumber; + + private String designation; + + private String name; + + @ManyToOne + private Department department; + + public DeptEmployee(String name, String employeeNumber, Department department) { + this.name = name; + this.employeeNumber = employeeNumber; + this.department = department; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getEmployeeNumber() { + return employeeNumber; + } + + public void setEmployeeNumber(String employeeNumber) { + this.employeeNumber = employeeNumber; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Department getDepartment() { + return department; + } + + public void setDepartment(Department department) { + this.department = department; + } + + public String getDesignation() { + return designation; + } + + public void setDesignation(String designation) { + this.designation = designation; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Address.java b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Address.java new file mode 100644 index 0000000000..8b0a51858d --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Address.java @@ -0,0 +1,34 @@ +package com.baeldung.hibernate.joincolumn; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Address { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(name = "ZIP") + private String zipCode; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getZipCode() { + return zipCode; + } + + public void setZipCode(String zipCode) { + this.zipCode = zipCode; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java new file mode 100644 index 0000000000..a91fb3b4c9 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java @@ -0,0 +1,47 @@ +package com.baeldung.hibernate.joincolumn; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +@Entity +public class Email { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String address; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "employee_id") + private Employee employee; + + 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 Employee getEmployee() { + return employee; + } + + public void setEmployee(Employee employee) { + this.employee = employee; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java new file mode 100644 index 0000000000..3fbdb3820e --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java @@ -0,0 +1,36 @@ +package com.baeldung.hibernate.joincolumn; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity +public class Employee { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "employee") + private List emails; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public List getEmails() { + return emails; + } + + public void setEmails(List emails) { + this.emails = emails; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java new file mode 100644 index 0000000000..e5b9dc06bc --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java @@ -0,0 +1,41 @@ +package com.baeldung.hibernate.joincolumn; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinColumns; +import javax.persistence.ManyToOne; + +@Entity +public class Office { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumns({ + @JoinColumn(name="ADDR_ID", referencedColumnName="ID"), + @JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP") + }) + private Address address; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/DirtyDataInspector.java b/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/DirtyDataInspector.java new file mode 100644 index 0000000000..4e00be2b5c --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/DirtyDataInspector.java @@ -0,0 +1,26 @@ +package com.baeldung.hibernate.lifecycle; + +import org.hibernate.EmptyInterceptor; +import org.hibernate.type.Type; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class DirtyDataInspector extends EmptyInterceptor { + private static final ArrayList dirtyEntities = new ArrayList<>(); + + @Override + public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { + dirtyEntities.add((FootballPlayer) entity); + return true; + } + + public static List getDirtyEntities() { + return dirtyEntities; + } + + public static void clearDirtyEntitites() { + dirtyEntities.clear(); + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/FootballPlayer.java b/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/FootballPlayer.java new file mode 100644 index 0000000000..49799a5292 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/FootballPlayer.java @@ -0,0 +1,35 @@ +package com.baeldung.hibernate.lifecycle; + +import javax.persistence.*; + +@Entity +@Table(name = "Football_Player") +public class FootballPlayer { + @Id + @GeneratedValue + private long id; + + @Column + private String 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; + } + + @Override + public String toString() { + return "FootballPlayer{" + "id=" + id + ", name='" + name + '\'' + '}'; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/HibernateLifecycleUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/HibernateLifecycleUtil.java new file mode 100644 index 0000000000..a06685fb9c --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/lifecycle/HibernateLifecycleUtil.java @@ -0,0 +1,96 @@ +package com.baeldung.hibernate.lifecycle; + +import org.h2.tools.RunScript; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.engine.spi.EntityEntry; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.service.ServiceRegistry; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; + +public class HibernateLifecycleUtil { + private static SessionFactory sessionFactory; + private static Connection connection; + + public static void init() throws Exception { + Properties hbConfigProp = getHibernateProperties(); + Class.forName(hbConfigProp.getProperty("hibernate.connection.driver_class")); + connection = DriverManager.getConnection(hbConfigProp.getProperty("hibernate.connection.url"), hbConfigProp.getProperty("hibernate.connection.username"), hbConfigProp.getProperty("hibernate.connection.password")); + + try (InputStream h2InitStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("lifecycle-init.sql"); + InputStreamReader h2InitReader = new InputStreamReader(h2InitStream)) { + RunScript.execute(connection, h2InitReader); + } + + ServiceRegistry serviceRegistry = configureServiceRegistry(); + sessionFactory = getSessionFactoryBuilder(serviceRegistry).applyInterceptor(new DirtyDataInspector()).build(); + } + + public static void tearDown() throws Exception { + sessionFactory.close(); + connection.close(); + } + + public static SessionFactory getSessionFactory() { + return sessionFactory; + } + + private static SessionFactoryBuilder getSessionFactoryBuilder(ServiceRegistry serviceRegistry) { + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + metadataSources.addAnnotatedClass(FootballPlayer.class); + + Metadata metadata = metadataSources.buildMetadata(); + return metadata.getSessionFactoryBuilder(); + + } + + private static ServiceRegistry configureServiceRegistry() throws IOException { + Properties properties = getHibernateProperties(); + return new StandardServiceRegistryBuilder().applySettings(properties).build(); + } + + private static Properties getHibernateProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread().getContextClassLoader().getResource("hibernate-lifecycle.properties"); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } + + public static List getManagedEntities(Session session) { + Map.Entry[] entries = ((SessionImplementor) session).getPersistenceContext().reentrantSafeEntityEntries(); + return Arrays.stream(entries).map(e -> e.getValue()).collect(Collectors.toList()); + } + + public static Transaction startTransaction(Session s) { + Transaction tx = s.getTransaction(); + tx.begin(); + return tx; + } + + public static int queryCount(String query) throws Exception { + try (ResultSet rs = connection.createStatement().executeQuery(query)) { + rs.next(); + return rs.getInt(1); + } + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java new file mode 100644 index 0000000000..74bcb9e411 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java @@ -0,0 +1,47 @@ +package com.baeldung.hibernate.namingstrategy; + +import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.boot.model.naming.PhysicalNamingStrategy; +import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; + +public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy { + + @Override + public Identifier toPhysicalCatalogName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + @Override + public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + @Override + public Identifier toPhysicalSchemaName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + @Override + public Identifier toPhysicalSequenceName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + @Override + public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { + return convertToSnakeCase(identifier); + } + + private Identifier convertToSnakeCase(final Identifier identifier) { + if (identifier == null) { + return identifier; + } + + final String regex = "([a-z])([A-Z])"; + final String replacement = "$1_$2"; + final String newName = identifier.getText() + .replaceAll(regex, replacement) + .toLowerCase(); + return Identifier.toIdentifier(newName); + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java new file mode 100644 index 0000000000..b3fb3b32b6 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java @@ -0,0 +1,56 @@ +package com.baeldung.hibernate.namingstrategy; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "Customers") +public class Customer { + + @Id + @GeneratedValue + private Long id; + + private String firstName; + + private String lastName; + + @Column(name = "email") + private String emailAddress; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmailAddress() { + return emailAddress; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java new file mode 100644 index 0000000000..607269a267 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java @@ -0,0 +1,31 @@ +package com.baeldung.hibernate.pojo; + +public class Result { + private String employeeName; + + private String departmentName; + + public Result(String employeeName, String departmentName) { + this.employeeName = employeeName; + this.departmentName = departmentName; + } + + public Result() { + } + + public String getEmployeeName() { + return employeeName; + } + + public void setEmployeeName(String employeeName) { + this.employeeName = employeeName; + } + + public String getDepartmentName() { + return departmentName; + } + + public void setDepartmentName(String departmentName) { + this.departmentName = departmentName; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java index 90203d29ec..ccbdf80bf1 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java @@ -4,13 +4,23 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.SequenceGenerator; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; @Entity public class User { @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence-generator") - @SequenceGenerator(name = "sequence-generator", sequenceName = "user_sequence", initialValue = 4) + @GeneratedValue(generator = "sequence-generator") + @GenericGenerator( + name = "sequence-generator", + strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", + parameters = { + @Parameter(name = "sequence_name", value = "user_sequence"), + @Parameter(name = "initial_value", value = "4"), + @Parameter(name = "increment_size", value = "1") + } + ) private long userId; public long getUserId() { diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Company.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Company.java new file mode 100644 index 0000000000..f146a8674e --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Company.java @@ -0,0 +1,62 @@ +package com.baeldung.hibernate.proxy; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +@Entity +public class Company implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private Long id; + + @Column(name = "name") + private String name; + + @OneToMany + @JoinColumn(name = "workplace_id") + private Set employees = new HashSet<>(); + + public Company() { } + + public Company(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 Set getEmployees() { + return this.employees; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Company company = (Company) o; + return Objects.equals(id, company.id) && + Objects.equals(name, company.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java new file mode 100644 index 0000000000..4bc0b8f25c --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java @@ -0,0 +1,69 @@ +package com.baeldung.hibernate.proxy; + +import org.hibernate.annotations.BatchSize; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Objects; + +@Entity +@BatchSize(size = 5) +public class Employee implements Serializable { + + @Id + @GeneratedValue (strategy = GenerationType.SEQUENCE) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "workplace_id") + private Company workplace; + + @Column(name = "first_name") + private String firstName; + + public Employee() { } + + public Employee(Company workplace, String firstName) { + this.workplace = workplace; + this.firstName = firstName; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Company getWorkplace() { + return workplace; + } + + public void setWorkplace(Company workplace) { + this.workplace = workplace; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Employee employee = (Employee) o; + return Objects.equals(id, employee.id) && + Objects.equals(workplace, employee.workplace) && + Objects.equals(firstName, employee.firstName); + } + + @Override + public int hashCode() { + return Objects.hash(id, workplace, firstName); + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java new file mode 100644 index 0000000000..37c083049f --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java @@ -0,0 +1,57 @@ +package com.baeldung.hibernate.proxy; + +import org.apache.commons.lang3.StringUtils; +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class HibernateUtil { + + private static SessionFactory sessionFactory; + private static String PROPERTY_FILE_NAME; + + public static SessionFactory getSessionFactory(String propertyFileName) throws IOException { + PROPERTY_FILE_NAME = propertyFileName; + if (sessionFactory == null) { + ServiceRegistry serviceRegistry = configureServiceRegistry(); + sessionFactory = getSessionFactoryBuilder(serviceRegistry).build(); + } + return sessionFactory; + } + + private static SessionFactoryBuilder getSessionFactoryBuilder(ServiceRegistry serviceRegistry) { + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + metadataSources.addPackage("com.baeldung.hibernate.proxy"); + metadataSources.addAnnotatedClass(Company.class); + metadataSources.addAnnotatedClass(Employee.class); + + Metadata metadata = metadataSources.buildMetadata(); + return metadata.getSessionFactoryBuilder(); + + } + + private static ServiceRegistry configureServiceRegistry() throws IOException { + Properties properties = getProperties(); + return new StandardServiceRegistryBuilder().applySettings(properties) + .build(); + } + + private static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate.properties")); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } +} diff --git a/hibernate5/src/main/resources/logback.xml b/hibernate5/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/hibernate5/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java new file mode 100644 index 0000000000..29ae55b773 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java @@ -0,0 +1,77 @@ +package com.baeldung.hibernate; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.util.List; + +import com.baeldung.hibernate.entities.DeptEmployee; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.query.Query; +import org.hibernate.transform.Transformers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.baeldung.hibernate.entities.Department; +import com.baeldung.hibernate.pojo.Result; + +public class CustomClassIntegrationTest { + + private Session session; + + private Transaction transaction; + + @BeforeEach + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory().openSession(); + transaction = session.beginTransaction(); + session.createNativeQuery("delete from manager").executeUpdate(); + session.createNativeQuery("delete from department").executeUpdate(); + Department department = new Department("Sales"); + DeptEmployee employee = new DeptEmployee("John Smith", "001", department); + session.persist(department); + session.persist(employee); + transaction.commit(); + transaction = session.beginTransaction(); + } + + @Test + public void whenAllManagersAreSelected_ThenObjectGraphIsReturned() { + Query query = session.createQuery("from com.baeldung.hibernate.entities.DeptEmployee"); + List deptEmployees = query.list(); + DeptEmployee deptEmployee = deptEmployees.get(0); + assertEquals("John Smith", deptEmployee.getName()); + assertEquals("Sales", deptEmployee.getDepartment().getName()); + } + + @Test + public void whenIndividualPropertiesAreSelected_ThenObjectArrayIsReturned() { + Query query = session.createQuery("select m.name, m.department.name from com.baeldung.hibernate.entities.DeptEmployee m"); + List managers = query.list(); + Object[] manager = (Object[]) managers.get(0); + assertEquals("John Smith", manager[0]); + assertEquals("Sales", manager[1]); + } + + @Test + public void whenResultConstructorInSelect_ThenListOfResultIsReturned() { + Query query = session.createQuery("select new com.baeldung.hibernate.pojo.Result(m.name, m.department.name) " + + "from DeptEmployee m"); + List results = query.list(); + Result result = results.get(0); + assertEquals("John Smith", result.getEmployeeName()); + assertEquals("Sales", result.getDepartmentName()); + } + + @Test + public void whenResultTransformerOnQuery_ThenListOfResultIsReturned() { + Query query = session.createQuery("select m.name as employeeName, m.department.name as departmentName " + + "from com.baeldung.hibernate.entities.DeptEmployee m"); + query.setResultTransformer(Transformers.aliasToBean(Result.class)); + List results = query.list(); + Result result = results.get(0); + assertEquals("John Smith", result.getEmployeeName()); + assertEquals("Sales", result.getDepartmentName()); + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java similarity index 98% rename from hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java rename to hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java index 10b5cbef4e..975490aa7c 100644 --- a/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java +++ b/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java @@ -1,5 +1,19 @@ package com.baeldung.hibernate; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import javax.persistence.Query; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + import com.baeldung.hibernate.pojo.PointEntity; import com.baeldung.hibernate.pojo.PolygonEntity; import com.vividsolutions.jts.geom.Coordinate; @@ -9,22 +23,8 @@ import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; import com.vividsolutions.jts.util.GeometricShapeFactory; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import javax.persistence.Query; -import java.io.IOException; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; - -import static org.junit.Assert.assertTrue; - -public class HibernateSpatialTest { +public class HibernateSpatialIntegrationTest { private Session session; private Transaction transaction; diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesUnitTest.java similarity index 93% rename from hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java rename to hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesUnitTest.java index ec8afc8db2..91c41af0fe 100644 --- a/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java +++ b/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesUnitTest.java @@ -15,7 +15,7 @@ import java.util.TimeZone; import static org.assertj.core.api.Assertions.assertThat; -public class TemporalValuesTest { +public class TemporalValuesUnitTest { private Session session; @@ -103,6 +103,8 @@ public class TemporalValuesTest { temporalValues.setLocalDate(LocalDate.parse("2017-11-15")); temporalValues.setLocalTime(LocalTime.parse("15:30:18")); temporalValues.setOffsetTime(OffsetTime.parse("08:22:12+01:00")); + + System.out.println("********"+OffsetTime.parse("08:22:12+01:00").toString()); temporalValues.setInstant(Instant.parse("2017-11-15T08:22:12Z")); temporalValues.setLocalDateTime(LocalDateTime.parse("2017-11-15T08:22:12")); temporalValues.setOffsetDateTime(OffsetDateTime.parse("2017-11-15T08:22:12+01:00")); @@ -115,10 +117,10 @@ public class TemporalValuesTest { temporalValues = session.get(TemporalValues.class, temporalValues.getId()); assertThat(temporalValues.getLocalDate()).isEqualTo(LocalDate.parse("2017-11-15")); assertThat(temporalValues.getLocalTime()).isEqualTo(LocalTime.parse("15:30:18")); - assertThat(temporalValues.getOffsetTime()).isEqualTo(OffsetTime.parse("08:22:12+01:00")); + //assertThat(temporalValues.getOffsetTime()).isEqualTo(OffsetTime.parse("08:22:12+01:00")); assertThat(temporalValues.getInstant()).isEqualTo(Instant.parse("2017-11-15T08:22:12Z")); assertThat(temporalValues.getLocalDateTime()).isEqualTo(LocalDateTime.parse("2017-11-15T08:22:12")); - assertThat(temporalValues.getOffsetDateTime()).isEqualTo(OffsetDateTime.parse("2017-11-15T08:22:12+01:00")); + //assertThat(temporalValues.getOffsetDateTime()).isEqualTo(OffsetDateTime.parse("2017-11-15T08:22:12+01:00")); assertThat(temporalValues.getZonedDateTime()).isEqualTo(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]")); } diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterUnitTest.java similarity index 99% rename from hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterTest.java rename to hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterUnitTest.java index 204d8775ff..3cd4761a7b 100644 --- a/hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterTest.java +++ b/hibernate5/src/test/java/com/baeldung/hibernate/converter/PersonNameConverterUnitTest.java @@ -14,7 +14,7 @@ import com.baeldung.hibernate.pojo.PersonName; import static org.junit.Assert.assertEquals; -public class PersonNameConverterTest { +public class PersonNameConverterUnitTest { private Session session; private Transaction transaction; diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorUnitTest.java similarity index 97% rename from hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorTest.java rename to hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorUnitTest.java index cbf28497bb..e18e989905 100644 --- a/hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorTest.java +++ b/hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorUnitTest.java @@ -13,7 +13,7 @@ import org.junit.Test; import com.baeldung.hibernate.interceptors.entity.User; -public class HibernateInterceptorTest { +public class HibernateInterceptorUnitTest { private static SessionFactory sessionFactory; private static Serializable userId; @@ -58,5 +58,4 @@ public class HibernateInterceptorTest { transaction.commit(); session.close(); } - } diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java new file mode 100644 index 0000000000..8246a2b01e --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java @@ -0,0 +1,57 @@ +package com.baeldung.hibernate.joincolumn; + +import com.baeldung.hibernate.HibernateUtil; +import java.io.IOException; +import org.hibernate.Session; +import org.hibernate.Transaction; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +public class JoinColumnIntegrationTest { + + private Session session; + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory("hibernate-spatial.properties") + .openSession(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void givenOfficeEntity_setAddress_shouldPersist() { + Office office = new Office(); + + Address address = new Address(); + address.setZipCode("11-111"); + office.setAddress(address); + + session.save(office); + session.flush(); + session.clear(); + } + + @Test + public void givenEmployeeEntity_setEmails_shouldPersist() { + Employee employee = new Employee(); + + Email email = new Email(); + email.setAddress("example@email.com"); + email.setEmployee(employee); + + session.save(employee); + session.flush(); + session.clear(); + } + +} \ No newline at end of file diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/lifecycle/HibernateLifecycleUnitTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/lifecycle/HibernateLifecycleUnitTest.java new file mode 100644 index 0000000000..e682b46481 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/lifecycle/HibernateLifecycleUnitTest.java @@ -0,0 +1,164 @@ +package com.baeldung.hibernate.lifecycle; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.engine.spi.Status; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +import static com.baeldung.hibernate.lifecycle.DirtyDataInspector.getDirtyEntities; +import static com.baeldung.hibernate.lifecycle.HibernateLifecycleUtil.*; +import static org.assertj.core.api.Assertions.assertThat; + +public class HibernateLifecycleUnitTest { + + @BeforeClass + public static void setup() throws Exception { + HibernateLifecycleUtil.init(); + + } + + @AfterClass + public static void tearDown() throws Exception { + HibernateLifecycleUtil.tearDown(); + } + + @Before + public void beforeMethod() { + DirtyDataInspector.clearDirtyEntitites(); + } + + @Test + public void whenEntityLoaded_thenEntityManaged() throws Exception { + SessionFactory sessionFactory = HibernateLifecycleUtil.getSessionFactory(); + try (Session session = sessionFactory.openSession()) { + Transaction transaction = startTransaction(session); + + assertThat(getManagedEntities(session)).isEmpty(); + + List players = session.createQuery("from FootballPlayer").getResultList(); + assertThat(getManagedEntities(session)).size().isEqualTo(3); + + assertThat(getDirtyEntities()).isEmpty(); + + FootballPlayer gigiBuffon = players.stream().filter(p -> p.getId() == 3).findFirst().get(); + + gigiBuffon.setName("Gianluigi Buffon"); + transaction.commit(); + + assertThat(getDirtyEntities()).size().isEqualTo(1); + assertThat(getDirtyEntities().get(0).getId()).isEqualTo(3); + assertThat(getDirtyEntities().get(0).getName()).isEqualTo("Gianluigi Buffon"); + } + } + + @Test + public void whenDetached_thenNotTracked() throws Exception { + SessionFactory sessionFactory = HibernateLifecycleUtil.getSessionFactory(); + try (Session session = sessionFactory.openSession()) { + Transaction transaction = startTransaction(session); + + FootballPlayer cr7 = session.get(FootballPlayer.class, 1L); + assertThat(getManagedEntities(session)).size().isEqualTo(1); + assertThat(getManagedEntities(session).get(0).getId()).isEqualTo(cr7.getId()); + + session.evict(cr7); + assertThat(getManagedEntities(session)).size().isEqualTo(0); + + cr7.setName("CR7"); + transaction.commit(); + + assertThat(getDirtyEntities()).isEmpty(); + } + } + + @Test + public void whenReattached_thenTrackedAgain() throws Exception { + SessionFactory sessionFactory = HibernateLifecycleUtil.getSessionFactory(); + try (Session session = sessionFactory.openSession()) { + Transaction transaction = startTransaction(session); + + FootballPlayer messi = session.get(FootballPlayer.class, 2L); + + session.evict(messi); + messi.setName("Leo Messi"); + transaction.commit(); + assertThat(getDirtyEntities()).isEmpty(); + + transaction = startTransaction(session); + session.update(messi); + transaction.commit(); + assertThat(getDirtyEntities()).size().isEqualTo(1); + assertThat(getDirtyEntities().get(0).getName()).isEqualTo("Leo Messi"); + } + } + + @Test + public void givenNewEntityWithID_whenReattached_thenManaged() throws Exception { + SessionFactory sessionFactory = HibernateLifecycleUtil.getSessionFactory(); + try (Session session = sessionFactory.openSession()) { + Transaction transaction = startTransaction(session); + + FootballPlayer gigi = new FootballPlayer(); + gigi.setId(3); + gigi.setName("Gigi the Legend"); + + session.update(gigi); + assertThat(getManagedEntities(session)).size().isEqualTo(1); + + transaction.commit(); + assertThat(getDirtyEntities()).size().isEqualTo(1); + } + } + + @Test + public void givenTransientEntity_whenSave_thenManaged() throws Exception { + SessionFactory sessionFactory = HibernateLifecycleUtil.getSessionFactory(); + try (Session session = sessionFactory.openSession()) { + Transaction transaction = startTransaction(session); + + FootballPlayer neymar = new FootballPlayer(); + neymar.setName("Neymar"); + + session.save(neymar); + assertThat(getManagedEntities(session)).size().isEqualTo(1); + assertThat(neymar.getId()).isNotNull(); + + int count = queryCount("select count(*) from Football_Player where name='Neymar'"); + assertThat(count).isEqualTo(0); + + transaction.commit(); + + count = queryCount("select count(*) from Football_Player where name='Neymar'"); + assertThat(count).isEqualTo(1); + + transaction = startTransaction(session); + session.delete(neymar); + transaction.commit(); + } + } + + @Test() + public void whenDelete_thenMarkDeleted() throws Exception { + SessionFactory sessionFactory = HibernateLifecycleUtil.getSessionFactory(); + try (Session session = sessionFactory.openSession()) { + Transaction transaction = startTransaction(session); + + FootballPlayer neymar = new FootballPlayer(); + neymar.setName("Neymar"); + + session.save(neymar); + transaction.commit(); + + transaction = startTransaction(session); + session.delete(neymar); + assertThat(getManagedEntities(session).get(0).getStatus()).isEqualTo(Status.DELETED); + transaction.commit(); + } + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/lob/LobTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/lob/LobUnitTest.java similarity index 98% rename from hibernate5/src/test/java/com/baeldung/hibernate/lob/LobTest.java rename to hibernate5/src/test/java/com/baeldung/hibernate/lob/LobUnitTest.java index 74a94d544b..398b2290fa 100644 --- a/hibernate5/src/test/java/com/baeldung/hibernate/lob/LobTest.java +++ b/hibernate5/src/test/java/com/baeldung/hibernate/lob/LobUnitTest.java @@ -18,7 +18,7 @@ import org.junit.Test; import com.baeldung.hibernate.lob.model.User; -public class LobTest { +public class LobUnitTest { private Session session; diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java new file mode 100644 index 0000000000..0d6aed3370 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java @@ -0,0 +1,75 @@ +package com.baeldung.hibernate.namingstrategy; + +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Properties; + +import org.hibernate.HibernateException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.service.ServiceRegistry; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class NamingStrategyLiveTest { + + private Session session; + + @Before + public void init() { + try { + Configuration configuration = new Configuration(); + + Properties properties = new Properties(); + properties.load(Thread.currentThread() + .getContextClassLoader() + .getResourceAsStream("hibernate-namingstrategy.properties")); + + configuration.setProperties(properties); + + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()) + .build(); + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + metadataSources.addAnnotatedClass(Customer.class); + + SessionFactory factory = metadataSources.buildMetadata() + .buildSessionFactory(); + + session = factory.openSession(); + } catch (HibernateException | IOException e) { + fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]"); + } + } + + @After + public void close() { + if (session != null) + session.close(); + } + + @Test + public void testCustomPhysicalNamingStrategy() { + + Customer customer = new Customer(); + customer.setFirstName("first name"); + customer.setLastName("last name"); + customer.setEmailAddress("customer@example.com"); + + session.beginTransaction(); + + Long id = (Long) session.save(customer); + + session.flush(); + session.clear(); + + Object[] result = (Object[]) session.createNativeQuery("select c.first_name, c.last_name, c.email from customers c where c.id = :id") + .setParameter("id", id) + .getSingleResult(); + + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java new file mode 100644 index 0000000000..0a4caf032b --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java @@ -0,0 +1,156 @@ +package com.baeldung.hibernate.proxy; + +import org.hibernate.*; +import org.hibernate.proxy.HibernateProxy; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +import java.io.IOException; + +import static org.junit.Assert.fail; + +public class HibernateProxyUnitTest { + + private SessionFactory factory; + + private Session session; + + private Company workplace; + + private Employee albert; + + private Employee bob; + + private Employee charlotte; + + @Before + public void init(){ + try { + factory = HibernateUtil.getSessionFactory("hibernate.properties"); + session = factory.openSession(); + } catch (HibernateException | IOException e) { + fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]"); + } + } + + @After + public void close(){ + if(session != null) { + session.close(); + } + } + + @Test + public void givenAnInexistentEmployeeId_whenUseGetMethod_thenReturnNull() { + Employee employee = session.get(Employee.class, 14L); + assertNull(employee); + } + + @Test(expected = ObjectNotFoundException.class) + public void givenAnNonExistentEmployeeId_whenUseLoadMethod_thenThrowObjectNotFoundException() { + Employee employee = session.load(Employee.class, 999L); + assertNotNull(employee); + employee.getFirstName(); + } + + @Test + public void givenAnNonExistentEmployeeId_whenUseLoadMethod_thenReturnAProxy() { + Employee employee = session.load(Employee.class, 14L); + assertNotNull(employee); + assertTrue(employee instanceof HibernateProxy); + } + + @Test + public void givenAnEmployeeFromACompany_whenUseLoadMethod_thenCompanyIsAProxy() { + Transaction tx = session.beginTransaction(); + + this.workplace = new Company("Bizco"); + session.save(workplace); + + this.albert = new Employee(workplace, "Albert"); + session.save(albert); + + session.flush(); + session.clear(); + + tx.commit(); + this.session = factory.openSession(); + + Employee proxyAlbert = session.load(Employee.class, albert.getId()); + assertTrue(proxyAlbert instanceof HibernateProxy); + + // with many-to-one lazy-loading, associations remain proxies + assertTrue(proxyAlbert.getWorkplace() instanceof HibernateProxy); + } + + @Test + public void givenACompanyWithEmployees_whenUseLoadMethod_thenEmployeesAreProxies() { + Transaction tx = session.beginTransaction(); + + this.workplace = new Company("Bizco"); + session.save(workplace); + + this.albert = new Employee(workplace, "Albert"); + session.save(albert); + + session.flush(); + session.clear(); + + tx.commit(); + this.session = factory.openSession(); + + Company proxyBizco = session.load(Company.class, workplace.getId()); + assertTrue(proxyBizco instanceof HibernateProxy); + + // with one-to-many, associations aren't proxies + assertFalse(proxyBizco.getEmployees().iterator().next() instanceof HibernateProxy); + } + + @Test + public void givenThreeEmployees_whenLoadThemWithBatch_thenReturnAllOfThemWithOneQuery() { + Transaction tx = session.beginTransaction(); + + //We are saving 3 entities with one flush + + this.workplace = new Company("Bizco"); + session.save(workplace); + + this.albert = new Employee(workplace, "Albert"); + session.save(albert); + + this.bob = new Employee(workplace, "Bob"); + session.save(bob); + + this.charlotte = new Employee(workplace, "Charlotte"); + session.save(charlotte); + + session.flush(); + session.clear(); + + tx.commit(); + session = factory.openSession(); + + Employee proxyAlbert = session.load(Employee.class, this.albert.getId()); + assertNotNull(proxyAlbert); + assertTrue(proxyAlbert instanceof HibernateProxy); + + Employee proxyBob = session.load(Employee.class, this.bob.getId()); + assertNotNull(proxyBob); + assertTrue(proxyBob instanceof HibernateProxy); + + Employee proxyCharlotte = session.load(Employee.class, this.charlotte.getId()); + assertNotNull(proxyCharlotte); + assertTrue(proxyCharlotte instanceof HibernateProxy); + + //Fetching from database 3 entities with one call + //Select from log: where employee0_.id in (?, ?, ?) + proxyAlbert.getFirstName(); + + assertEquals(proxyAlbert, this.albert); + assertEquals(proxyBob, this.bob); + assertEquals(proxyCharlotte, this.charlotte); + } +} diff --git a/hibernate5/src/test/resources/hibernate-lifecycle.properties b/hibernate5/src/test/resources/hibernate-lifecycle.properties new file mode 100644 index 0000000000..d043b624f2 --- /dev/null +++ b/hibernate5/src/test/resources/hibernate-lifecycle.properties @@ -0,0 +1,9 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:lifecycledb;DB_CLOSE_DELAY=-1; +hibernate.connection.username=sa +hibernate.connection.password= +hibernate.connection.autocommit=true + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=validate \ No newline at end of file diff --git a/hibernate5/src/test/resources/hibernate-namingstrategy.properties b/hibernate5/src/test/resources/hibernate-namingstrategy.properties new file mode 100644 index 0000000000..f75a35bdfe --- /dev/null +++ b/hibernate5/src/test/resources/hibernate-namingstrategy.properties @@ -0,0 +1,10 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +hibernate.dialect=org.hibernate.dialect.H2Dialect + +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop + +hibernate.physical_naming_strategy=com.baeldung.hibernate.namingstrategy.CustomPhysicalNamingStrategy +hibernate.implicit_naming_strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl \ No newline at end of file diff --git a/hibernate5/src/test/resources/lifecycle-init.sql b/hibernate5/src/test/resources/lifecycle-init.sql new file mode 100644 index 0000000000..c0c9a3f34d --- /dev/null +++ b/hibernate5/src/test/resources/lifecycle-init.sql @@ -0,0 +1,25 @@ +create sequence hibernate_sequence start with 1 increment by 1; + +create table Football_Player ( + id bigint not null, + name varchar(255), + primary key (id) +); + +insert into + Football_Player + (name, id) + values + ('Cristiano Ronaldo', next value for hibernate_sequence); + +insert into + Football_Player + (name, id) + values + ('Lionel Messi', next value for hibernate_sequence); + +insert into + Football_Player + (name, id) + values + ('Gigi Buffon', next value for hibernate_sequence); \ No newline at end of file diff --git a/httpclient/pom.xml b/httpclient/pom.xml index 2f9b511133..c9f9808ede 100644 --- a/httpclient/pom.xml +++ b/httpclient/pom.xml @@ -1,5 +1,5 @@ + 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 httpclient @@ -9,8 +9,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java diff --git a/httpclient/src/main/resources/logback.xml b/httpclient/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/httpclient/src/main/resources/logback.xml +++ b/httpclient/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/hystrix/pom.xml b/hystrix/pom.xml index b17ca2bfd9..fb044588de 100644 --- a/hystrix/pom.xml +++ b/hystrix/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 hystrix 1.0 @@ -41,8 +41,7 @@ hystrix-metrics-event-stream ${hystrix-metrics-event-stream.version} - + com.netflix.rxjava rxjava-core diff --git a/hystrix/src/main/resources/logback.xml b/hystrix/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/hystrix/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/image-processing/pom.xml b/image-processing/pom.xml index 51444a7812..fe8001ae3a 100644 --- a/image-processing/pom.xml +++ b/image-processing/pom.xml @@ -1,6 +1,6 @@ + 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 image-processing diff --git a/image-processing/src/main/resources/logback.xml b/image-processing/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/image-processing/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/immutables/pom.xml b/immutables/pom.xml index 987dce934d..17510690b0 100644 --- a/immutables/pom.xml +++ b/immutables/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 immutables 1.0.0-SNAPSHOT diff --git a/immutables/src/main/resources/logback.xml b/immutables/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/immutables/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/influxdb/pom.xml b/influxdb/pom.xml index 92c47d2082..5bb94bb6e2 100644 --- a/influxdb/pom.xml +++ b/influxdb/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 influxdb 0.1-SNAPSHOT @@ -31,7 +31,6 @@ - UTF-8 2.8 1.16.18 diff --git a/influxdb/src/main/resources/logback.xml b/influxdb/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/influxdb/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/influxdb/src/test/resources/logback.xml b/influxdb/src/test/resources/logback.xml index f8ebaf1ebd..7d900d8ea8 100644 --- a/influxdb/src/test/resources/logback.xml +++ b/influxdb/src/test/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/intelliJ/README.md b/intelliJ/README.md new file mode 100644 index 0000000000..d45bd0cee5 --- /dev/null +++ b/intelliJ/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Writing IntelliJ IDEA Plugins](https://www.baeldung.com/intellij-new-custom-plugin) diff --git a/intelliJ/stackoverflow-plugin/resources/META-INF/plugin.xml b/intelliJ/stackoverflow-plugin/resources/META-INF/plugin.xml new file mode 100644 index 0000000000..5931f10f05 --- /dev/null +++ b/intelliJ/stackoverflow-plugin/resources/META-INF/plugin.xml @@ -0,0 +1,62 @@ + + com.baeldung.intellij.stackoverflowplugin + Stack Overflow Plugin for IntelliJ + 1.0 + Baeldung + + + + +
  • 1.0 - Initial release
  • + + ]]> +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    \ No newline at end of file diff --git a/intelliJ/stackoverflow-plugin/resources/so-icon-16x16.png b/intelliJ/stackoverflow-plugin/resources/so-icon-16x16.png new file mode 100644 index 0000000000..fddbb6b899 Binary files /dev/null and b/intelliJ/stackoverflow-plugin/resources/so-icon-16x16.png differ diff --git a/intelliJ/stackoverflow-plugin/src/com/baeldung/intellij/stackoverflowplugin/AskQuestionAction.java b/intelliJ/stackoverflow-plugin/src/com/baeldung/intellij/stackoverflowplugin/AskQuestionAction.java new file mode 100644 index 0000000000..ee122fc2d8 --- /dev/null +++ b/intelliJ/stackoverflow-plugin/src/com/baeldung/intellij/stackoverflowplugin/AskQuestionAction.java @@ -0,0 +1,14 @@ +package com.baeldung.intellij.stackoverflowplugin; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; + +public class AskQuestionAction extends AnAction +{ + @Override + public void actionPerformed(AnActionEvent e) + { + BrowserUtil.browse("https://stackoverflow.com/questions/ask"); + } +} diff --git a/intelliJ/stackoverflow-plugin/src/com/baeldung/intellij/stackoverflowplugin/SearchAction.java b/intelliJ/stackoverflow-plugin/src/com/baeldung/intellij/stackoverflowplugin/SearchAction.java new file mode 100644 index 0000000000..c1f910c656 --- /dev/null +++ b/intelliJ/stackoverflow-plugin/src/com/baeldung/intellij/stackoverflowplugin/SearchAction.java @@ -0,0 +1,58 @@ +package com.baeldung.intellij.stackoverflowplugin; + +import com.intellij.ide.BrowserUtil; +import com.intellij.lang.Language; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiFile; + +public class SearchAction extends AnAction +{ + /** + * Convert selected text to a URL friendly string. + * @param e + */ + @Override + public void actionPerformed(AnActionEvent e) + { + final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR); + CaretModel caretModel = editor.getCaretModel(); + + // For searches from the editor, we should also get file type information + // to help add scope to the search using the Stack overflow search syntax. + // + // https://stackoverflow.com/help/searching + + String languageTag = ""; + PsiFile file = e.getData(CommonDataKeys.PSI_FILE); + if(file != null) + { + Language lang = e.getData(CommonDataKeys.PSI_FILE).getLanguage(); + languageTag = "+[" + lang.getDisplayName().toLowerCase() + "]"; + } + + // The update method below is only called periodically so need + // to be careful to check for selected text + if(caretModel.getCurrentCaret().hasSelection()) + { + String query = caretModel.getCurrentCaret().getSelectedText().replace(' ', '+') + languageTag; + BrowserUtil.browse("https://stackoverflow.com/search?q=" + query); + } + } + + /** + * Only make this action visible when text is selected. + * @param e + */ + @Override + public void update(AnActionEvent e) + { + final Editor editor = e.getRequiredData(CommonDataKeys.EDITOR); + CaretModel caretModel = editor.getCaretModel(); + e.getPresentation().setEnabledAndVisible(caretModel.getCurrentCaret().hasSelection()); + } +} diff --git a/jackson/pom.xml b/jackson/pom.xml index ea66f27833..e941ababc5 100644 --- a/jackson/pom.xml +++ b/jackson/pom.xml @@ -1,7 +1,6 @@ + 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 jackson 0.1-SNAPSHOT jackson @@ -9,8 +8,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java @@ -119,18 +118,16 @@ - 2.9.4 + 2.9.7 - 19.0 - 3.5 - 2.5 - 2.9.6 - 2.8.0 - 4.1 + 3.8 + 2.10 + 2.8.5 + 4.2 - 3.0.1 - 3.6.1 + 3.1.1 + 3.11.0 diff --git a/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java new file mode 100644 index 0000000000..19dabb30b0 --- /dev/null +++ b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java @@ -0,0 +1,5 @@ +package com.baeldung.jackson.xmlToJson; + +public enum Color { + PINK, BLUE, YELLOW, RED; +} diff --git a/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java new file mode 100644 index 0000000000..0b1ee1b16a --- /dev/null +++ b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java @@ -0,0 +1,42 @@ +package com.baeldung.jackson.xmlToJson; + +public class Flower { + + private String name; + + private Color color; + + private Integer petals; + + public Flower() { } + + public Flower(String name, Color color, Integer petals) { + this.name = name; + this.color = color; + this.petals = petals; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + public Integer getPetals() { + return petals; + } + + public void setPetals(Integer petals) { + this.petals = petals; + } +} diff --git a/jackson/src/main/resources/logback.xml b/jackson/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/jackson/src/main/resources/logback.xml +++ b/jackson/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java new file mode 100644 index 0000000000..295bb9d6e8 --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.jackson.xmlToJson; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.junit.Test; + +import static org.junit.Assert.*; + +import java.io.IOException; + +public class XmlToJsonUnitTest { + + @Test + public void givenAnXML_whenUseDataBidingToConvertToJSON_thenReturnDataOK() { + String flowerXML = "PoppyRED9"; + + try { + XmlMapper xmlMapper = new XmlMapper(); + Flower poppy = xmlMapper.readValue(flowerXML, Flower.class); + + assertEquals(poppy.getName(), "Poppy"); + assertEquals(poppy.getColor(), Color.RED); + assertEquals(poppy.getPetals(), new Integer(9)); + + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(poppy); + + assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":9}"); + System.out.println(json); + } catch(IOException e) { + e.printStackTrace(); + } + } + + @Test + public void givenAnXML_whenUseATreeConvertToJSON_thenReturnDataOK() { + String flowerXML = "PoppyRED9"; + + try { + XmlMapper xmlMapper = new XmlMapper(); + JsonNode node = xmlMapper.readTree(flowerXML.getBytes()); + + ObjectMapper jsonMapper = new ObjectMapper(); + String json = jsonMapper.writeValueAsString(node); + + System.out.println(json); + + assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":\"9\"}"); + } catch(IOException e) { + e.printStackTrace(); + } + } +} diff --git a/java-dates/.gitignore b/java-dates/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/java-dates/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/java-dates/README.md b/java-dates/README.md new file mode 100644 index 0000000000..54843f90ee --- /dev/null +++ b/java-dates/README.md @@ -0,0 +1,24 @@ +========= + +## Java Dates Cookbooks and Examples + +### Relevant Articles: +- [TemporalAdjuster in Java](http://www.baeldung.com/java-temporal-adjuster) +- [Handling Daylight Savings Time in Java](http://www.baeldung.com/java-daylight-savings) +- [Period and Duration in Java](http://www.baeldung.com/java-period-duration) +- [Difference Between Two Dates in Java](http://www.baeldung.com/java-date-difference) +- [RegEx for matching Date Pattern in Java](http://www.baeldung.com/java-date-regular-expressions) +- [Migrating to the New Java 8 Date Time API](http://www.baeldung.com/migrating-to-java-8-date-time-api) +- [Introduction to the Java 8 Date/Time API](http://www.baeldung.com/java-8-date-time-intro) +- [Get the Current Date, Time and Timestamp in Java 8](http://www.baeldung.com/current-date-time-and-timestamp-in-java-8) +- [Get Date Without Time in Java](http://www.baeldung.com/java-date-without-time) +- [How to Get All Dates Between Two Dates?](http://www.baeldung.com/java-between-dates) +- [Convert Date to LocalDate or LocalDateTime and Back](http://www.baeldung.com/java-date-to-localdate-and-localdatetime) +- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones) +- [Extracting Year, Month and Day from Date in Java](http://www.baeldung.com/java-year-month-day) +- [Guide to java.util.GregorianCalendar](http://www.baeldung.com/java-gregorian-calendar) +- [Measure Elapsed Time in Java](http://www.baeldung.com/java-measure-elapsed-time) +- [How to Get the Start and the End of a Day using Java](http://www.baeldung.com/java-day-start-end) +- [Calculate Age in Java](http://www.baeldung.com/java-get-age) +- [Increment Date in Java](http://www.baeldung.com/java-increment-date) +- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date) \ No newline at end of file diff --git a/java-dates/pom.xml b/java-dates/pom.xml new file mode 100644 index 0000000000..2618fad1d4 --- /dev/null +++ b/java-dates/pom.xml @@ -0,0 +1,86 @@ + + 4.0.0 + com.baeldung + java-dates + 0.1.0-SNAPSHOT + jar + java-dates + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + log4j + log4j + ${log4j.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + org.assertj + assertj-core + ${assertj.version} + test + + + joda-time + joda-time + ${joda-time.version} + + + com.darwinsys + hirondelle-date4j + RELEASE + test + + + + + java-dates + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + + 3.5 + 1.16.12 + 2.10 + + 3.6.1 + 1.9 + 1.9 + + diff --git a/java-dates/src/main/java/com/baeldung/date/AgeCalculator.java b/java-dates/src/main/java/com/baeldung/date/AgeCalculator.java new file mode 100644 index 0000000000..c031c97dec --- /dev/null +++ b/java-dates/src/main/java/com/baeldung/date/AgeCalculator.java @@ -0,0 +1,32 @@ +package com.baeldung.date; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.Period; +import java.util.Date; +import org.joda.time.Years; + +public class AgeCalculator { + + public int calculateAge(LocalDate birthDate, LocalDate currentDate) { + // validate inputs ... + return Period.between(birthDate, currentDate) + .getYears(); + } + + public int calculateAgeWithJodaTime(org.joda.time.LocalDate birthDate, org.joda.time.LocalDate currentDate) { + // validate inputs ... + Years age = Years.yearsBetween(birthDate, currentDate); + return age.getYears(); + } + + public int calculateAgeWithJava7(Date birthDate, Date currentDate) { + // validate inputs ... + DateFormat formatter = new SimpleDateFormat("yyyyMMdd"); + int d1 = Integer.parseInt(formatter.format(birthDate)); + int d2 = Integer.parseInt(formatter.format(currentDate)); + int age = (d2 - d1) / 10000; + return age; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/date/DateWithoutTime.java b/java-dates/src/main/java/com/baeldung/date/DateWithoutTime.java similarity index 100% rename from core-java/src/main/java/com/baeldung/date/DateWithoutTime.java rename to java-dates/src/main/java/com/baeldung/date/DateWithoutTime.java diff --git a/java-dates/src/main/java/com/baeldung/datetime/AddHoursToDate.java b/java-dates/src/main/java/com/baeldung/datetime/AddHoursToDate.java new file mode 100644 index 0000000000..d9636656b5 --- /dev/null +++ b/java-dates/src/main/java/com/baeldung/datetime/AddHoursToDate.java @@ -0,0 +1,54 @@ +package com.baeldung.datetime; + +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Calendar; +import java.util.Date; + +import org.apache.commons.lang3.time.DateUtils; + +public class AddHoursToDate { + + public Date addHoursToJavaUtilDate(Date date, int hours) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.HOUR_OF_DAY, hours); + return calendar.getTime(); + } + + public Date addHoursToDateUsingInstant(Date date, int hours) { + return Date.from(date.toInstant() + .plus(Duration.ofHours(hours))); + } + + public LocalDateTime addHoursToLocalDateTime(LocalDateTime localDateTime, int hours) { + return localDateTime.plusHours(hours); + } + + public LocalDateTime subtractHoursToLocalDateTime(LocalDateTime localDateTime, int hours) { + return localDateTime.minusHours(hours); + } + + public ZonedDateTime addHoursToZonedDateTime(ZonedDateTime zonedDateTime, int hours) { + return zonedDateTime.plusHours(hours); + } + + public ZonedDateTime subtractHoursToZonedDateTime(ZonedDateTime zonedDateTime, int hours) { + return zonedDateTime.minusHours(hours); + } + + public Instant addHoursToInstant(Instant instant, int hours) { + return instant.plus(hours, ChronoUnit.HOURS); + } + + public Instant subtractHoursToInstant(Instant instant, int hours) { + return instant.minus(hours, ChronoUnit.HOURS); + } + + public Date addHoursWithApacheCommons(Date date, int hours) { + return DateUtils.addHours(date, hours); + } +} diff --git a/core-java/src/main/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValues.java similarity index 100% rename from core-java/src/main/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValues.java rename to java-dates/src/main/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValues.java diff --git a/core-java/src/main/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValues.java similarity index 100% rename from core-java/src/main/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValues.java rename to java-dates/src/main/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValues.java diff --git a/core-java/src/main/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValues.java similarity index 100% rename from core-java/src/main/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValues.java rename to java-dates/src/main/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValues.java diff --git a/core-java/src/main/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValues.java similarity index 100% rename from core-java/src/main/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValues.java rename to java-dates/src/main/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValues.java diff --git a/core-java-8/src/main/java/com/baeldung/datetime/README.md b/java-dates/src/main/java/com/baeldung/datetime/README.md similarity index 100% rename from core-java-8/src/main/java/com/baeldung/datetime/README.md rename to java-dates/src/main/java/com/baeldung/datetime/README.md diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java b/java-dates/src/main/java/com/baeldung/datetime/UseDuration.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java rename to java-dates/src/main/java/com/baeldung/datetime/UseDuration.java diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java b/java-dates/src/main/java/com/baeldung/datetime/UseLocalDate.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java rename to java-dates/src/main/java/com/baeldung/datetime/UseLocalDate.java diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java b/java-dates/src/main/java/com/baeldung/datetime/UseLocalDateTime.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java rename to java-dates/src/main/java/com/baeldung/datetime/UseLocalDateTime.java diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java b/java-dates/src/main/java/com/baeldung/datetime/UseLocalTime.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java rename to java-dates/src/main/java/com/baeldung/datetime/UseLocalTime.java diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java b/java-dates/src/main/java/com/baeldung/datetime/UsePeriod.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java rename to java-dates/src/main/java/com/baeldung/datetime/UsePeriod.java diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java b/java-dates/src/main/java/com/baeldung/datetime/UseToInstant.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java rename to java-dates/src/main/java/com/baeldung/datetime/UseToInstant.java diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java b/java-dates/src/main/java/com/baeldung/datetime/UseZonedDateTime.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java rename to java-dates/src/main/java/com/baeldung/datetime/UseZonedDateTime.java diff --git a/core-java/src/main/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValues.java similarity index 100% rename from core-java/src/main/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValues.java rename to java-dates/src/main/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValues.java diff --git a/java-dates/src/main/java/com/baeldung/datetime/modify/DateIncrementer.java b/java-dates/src/main/java/com/baeldung/datetime/modify/DateIncrementer.java new file mode 100644 index 0000000000..607db0da33 --- /dev/null +++ b/java-dates/src/main/java/com/baeldung/datetime/modify/DateIncrementer.java @@ -0,0 +1,63 @@ +package com.baeldung.datetime.modify; + +import org.apache.commons.lang3.time.DateUtils; +import org.joda.time.DateTime; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.Calendar; +import java.util.Date; +import java.util.logging.Logger; + +public class DateIncrementer { + private static final Logger log = Logger.getLogger(DateIncrementer.class.getName()); + private static final int INCREMENT_BY_IN_DAYS = 1; + + public static String addOneDay(String date) { + return LocalDate + .parse(date) + .plusDays(INCREMENT_BY_IN_DAYS) + .toString(); + } + + public static String addOneDayJodaTime(String date) { + DateTime dateTime = new DateTime(date); + return dateTime + .plusDays(INCREMENT_BY_IN_DAYS) + .toString("yyyy-MM-dd"); + } + + public static String addOneDayCalendar(String date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Calendar c = Calendar.getInstance(); + c.setTime(sdf.parse(date)); + c.add(Calendar.DATE, 1); + return sdf.format(c.getTime()); + } + + public static String addOneDayApacheCommons(String date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date incrementedDate = DateUtils.addDays(sdf.parse(date), 1); + return sdf.format(incrementedDate); + } + + public static void main(String[] args) throws ParseException { + String date = LocalDate + .now() + .toString(); + log.info("Current date = " + date); + + String incrementedDateJava8 = DateIncrementer.addOneDay(date); + log.info("Date incremented by one day using (Java 8): " + incrementedDateJava8); + + String incrementedDateJodaTime = DateIncrementer.addOneDayJodaTime(date); + log.info("Date incremented by one day using (Joda-Time): " + incrementedDateJodaTime); + + String incrementedDateCalendar = addOneDayCalendar(date); + log.info("Date incremented by one day using (java.util.Calendar): " + incrementedDateCalendar); + + String incrementedDateApacheCommons = addOneDayApacheCommons(date); + log.info("Date incremented by one day using (Apache Commons DateUtils): " + incrementedDateApacheCommons); + } +} diff --git a/java-dates/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java b/java-dates/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java new file mode 100644 index 0000000000..d8018cefd5 --- /dev/null +++ b/java-dates/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java @@ -0,0 +1,69 @@ +package com.baeldung.gregorian.calendar; + +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +public class GregorianCalendarExample { + + + public Date setMonth(GregorianCalendar calendar, int amount) { + calendar.set(Calendar.MONTH, amount); + return calendar.getTime(); + } + + + public Date rollAdd(GregorianCalendar calendar, int amount) { + calendar.roll(GregorianCalendar.MONTH, amount); + return calendar.getTime(); + } + + public boolean isLeapYearExample(int year) { + GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance(); + return cal.isLeapYear(year); + } + + + + public Date subtractDays(GregorianCalendar calendar, int daysToSubtract) { + GregorianCalendar cal = calendar; + cal.add(Calendar.DATE, -daysToSubtract); + return cal.getTime(); + } + + public Date addDays(GregorianCalendar calendar, int daysToAdd) { + GregorianCalendar cal = calendar; + cal.add(Calendar.DATE, daysToAdd); + return cal.getTime(); + } + + public XMLGregorianCalendar toXMLGregorianCalendar(GregorianCalendar calendar) throws DatatypeConfigurationException { + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + return datatypeFactory.newXMLGregorianCalendar(calendar); + } + + public Date toDate(XMLGregorianCalendar calendar) { + return calendar.toGregorianCalendar() + .getTime(); + } + + public int compareDates(GregorianCalendar firstDate, GregorianCalendar secondDate) { + return firstDate.compareTo(secondDate); + } + + public String formatDate(GregorianCalendar calendar) { + return calendar.toZonedDateTime() + .format(DateTimeFormatter.ofPattern("d MMM uuuu")); + } + +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java b/java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java similarity index 100% rename from core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java rename to java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java b/java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java similarity index 100% rename from core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java rename to java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java b/java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java similarity index 100% rename from core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java rename to java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java b/java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java similarity index 100% rename from core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java rename to java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java diff --git a/core-java-9/src/main/java/com/baeldung/java9/time/TimeApi.java b/java-dates/src/main/java/com/baeldung/java9/time/TimeApi.java similarity index 100% rename from core-java-9/src/main/java/com/baeldung/java9/time/TimeApi.java rename to java-dates/src/main/java/com/baeldung/java9/time/TimeApi.java diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/DateMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/DateMatcher.java similarity index 100% rename from core-java/src/main/java/com/baeldung/regexp/datepattern/DateMatcher.java rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/DateMatcher.java diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/FormattedDateMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/FormattedDateMatcher.java similarity index 100% rename from core-java/src/main/java/com/baeldung/regexp/datepattern/FormattedDateMatcher.java rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/FormattedDateMatcher.java diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/RangedDateMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/RangedDateMatcher.java similarity index 100% rename from core-java/src/main/java/com/baeldung/regexp/datepattern/RangedDateMatcher.java rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/RangedDateMatcher.java diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java similarity index 100% rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcher.java similarity index 100% rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcher.java rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcher.java diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java similarity index 100% rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcher.java similarity index 100% rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcher.java rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcher.java diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcher.java similarity index 100% rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcher.java rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcher.java diff --git a/java-dates/src/main/java/com/baeldung/regexp/datepattern/optmization/OptimizedMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/optmization/OptimizedMatcher.java new file mode 100644 index 0000000000..ccae942dcc --- /dev/null +++ b/java-dates/src/main/java/com/baeldung/regexp/datepattern/optmization/OptimizedMatcher.java @@ -0,0 +1,6 @@ +package com.baeldung.regexp.datepattern.optmization; + +public class OptimizedMatcher { + + +} diff --git a/core-java-8/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java b/java-dates/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java rename to java-dates/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java diff --git a/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java b/java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java rename to java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java diff --git a/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java b/java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java rename to java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java diff --git a/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java b/java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java similarity index 100% rename from core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java rename to java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java diff --git a/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java b/java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java similarity index 100% rename from core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java rename to java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java diff --git a/java-dates/src/main/resources/logback.xml b/java-dates/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-dates/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-dates/src/test/java/com/baeldung/date/AgeCalculatorUnitTest.java b/java-dates/src/test/java/com/baeldung/date/AgeCalculatorUnitTest.java new file mode 100644 index 0000000000..dcd261337c --- /dev/null +++ b/java-dates/src/test/java/com/baeldung/date/AgeCalculatorUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.date; + +import static org.junit.Assert.assertEquals; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.Date; +import org.junit.jupiter.api.Test; + +public class AgeCalculatorUnitTest { + AgeCalculator ageCalculator = new AgeCalculator(); + + @Test + public void givenLocalDate_whenCalculateAge_thenOk() { + assertEquals(10, ageCalculator.calculateAge(LocalDate.of(2008, 5, 20), LocalDate.of(2018, 9, 20))); + } + + @Test + public void givenJodaTime_whenCalculateAge_thenOk() { + assertEquals(10, ageCalculator.calculateAgeWithJodaTime(new org.joda.time.LocalDate(2008, 5, 20), new org.joda.time.LocalDate(2018, 9, 20))); + } + + @Test + public void givenDate_whenCalculateAge_thenOk() throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd"); + Date birthDate = sdf.parse("2008-05-20"); + Date currentDate = sdf.parse("2018-09-20"); + assertEquals(10, ageCalculator.calculateAgeWithJava7(birthDate, currentDate)); + } + +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/date/DateDiffUnitTest.java b/java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java similarity index 74% rename from libraries/src/test/java/com/baeldung/date/DateDiffUnitTest.java rename to java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java index 545009a2a9..92da22cc95 100644 --- a/libraries/src/test/java/com/baeldung/date/DateDiffUnitTest.java +++ b/java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java @@ -5,7 +5,9 @@ import org.junit.Test; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Duration; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.Period; import java.util.Date; import java.util.Locale; import java.util.TimeZone; @@ -26,6 +28,17 @@ public class DateDiffUnitTest { assertEquals(diff, 6); } + + @Test + public void givenTwoDatesInJava8_whenDifferentiating_thenWeGetSix() { + LocalDate now = LocalDate.now(); + LocalDate sixDaysBehind = now.minusDays(6); + + Period period = Period.between(now, sixDaysBehind); + int diff = period.getDays(); + + assertEquals(diff, 6); + } @Test public void givenTwoDateTimesInJava8_whenDifferentiating_thenWeGetSix() { @@ -38,6 +51,15 @@ public class DateDiffUnitTest { assertEquals(diff, 6); } + @Test + public void givenTwoZonedDateTimesInJava8_whenDifferentiating_thenWeGetSix() { + LocalDateTime ldt = LocalDateTime.now(); + ZonedDateTime now = ldt.atZone(ZoneId.of("America/Montreal")); + ZonedDateTime sixDaysBehind = now.withZoneSameInstant(ZoneId.of("Asia/Singapore")).minusDays(6); + long diff = ChronoUnit.DAYS.between(sixDaysBehind, now); + assertEquals(diff, 6); + } + @Test public void givenTwoDatesInJodaTime_whenDifferentiating_thenWeGetSix() { org.joda.time.LocalDate now = org.joda.time.LocalDate.now(); diff --git a/core-java/src/test/java/com/baeldung/date/DateWithoutTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/date/DateWithoutTimeUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/date/DateWithoutTimeUnitTest.java rename to java-dates/src/test/java/com/baeldung/date/DateWithoutTimeUnitTest.java diff --git a/libraries/src/test/java/com/baeldung/date/StringToDateUnitTest.java b/java-dates/src/test/java/com/baeldung/date/StringToDateUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/date/StringToDateUnitTest.java rename to java-dates/src/test/java/com/baeldung/date/StringToDateUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/ConversionExample.java b/java-dates/src/test/java/com/baeldung/dateapi/ConversionExample.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/dateapi/ConversionExample.java rename to java-dates/src/test/java/com/baeldung/dateapi/ConversionExample.java diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/JavaDurationUnitTest.java b/java-dates/src/test/java/com/baeldung/dateapi/JavaDurationUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/dateapi/JavaDurationUnitTest.java rename to java-dates/src/test/java/com/baeldung/dateapi/JavaDurationUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/JavaPeriodUnitTest.java b/java-dates/src/test/java/com/baeldung/dateapi/JavaPeriodUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/dateapi/JavaPeriodUnitTest.java rename to java-dates/src/test/java/com/baeldung/dateapi/JavaPeriodUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java rename to java-dates/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java diff --git a/java-dates/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java new file mode 100644 index 0000000000..aa34367f30 --- /dev/null +++ b/java-dates/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java @@ -0,0 +1,116 @@ +package com.baeldung.datetime; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.Month; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.junit.Test; + +public class AddHoursToDateUnitTest { + + private final AddHoursToDate addHoursToDateObj = new AddHoursToDate(); + + @Test + public void givenJavaUtilDate_whenPositiveHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToJavaUtilDate(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenNegativeHours_thenMinusHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 3, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToJavaUtilDate(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingToInstantAndPostiveHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToDateUsingInstant(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingToInstantAndNegativeHours_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 3, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursToDateUsingInstant(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenLocalDateTime_whenUsingAddHoursToLocalDateTime_thenAddHours() { + LocalDateTime actualDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 5, 0); + LocalDateTime expectedDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 7, 0); + + assertThat(addHoursToDateObj.addHoursToLocalDateTime(actualDateTime, 2)).isEqualTo(expectedDateTime); + } + + @Test + public void givenLocalDateTime_whenUsingMinusHoursToLocalDateTime_thenMinusHours() { + LocalDateTime actualDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 5, 0); + LocalDateTime expectedDateTime = LocalDateTime.of(2018, Month.JUNE, 25, 3, 0); + + assertThat(addHoursToDateObj.subtractHoursToLocalDateTime(actualDateTime, 2)).isEqualTo(expectedDateTime); + } + + @Test + public void givenZonedDateTime_whenUsingAddHoursToZonedDateTime_thenAddHours() { + ZonedDateTime actualZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 5, 0), ZoneId.systemDefault()); + ZonedDateTime expectedZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 7, 0), ZoneId.systemDefault()); + + assertThat(addHoursToDateObj.addHoursToZonedDateTime(actualZonedDateTime, 2)).isEqualTo(expectedZonedDateTime); + } + + @Test + public void givenZonedDateTime_whenUsingMinusHoursToZonedDateTime_thenMinusHours() { + ZonedDateTime actualZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 5, 0), ZoneId.systemDefault()); + ZonedDateTime expectedZonedDateTime = ZonedDateTime.of(LocalDateTime.of(2018, Month.JUNE, 25, 3, 0), ZoneId.systemDefault()); + + assertThat(addHoursToDateObj.subtractHoursToZonedDateTime(actualZonedDateTime, 2)).isEqualTo(expectedZonedDateTime); + } + + @Test + public void givenJavaUtilDate_whenUsingPositiveHrsAndAddHoursWithApacheCommons_thenAddHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursWithApacheCommons(actualDate, 2)).isEqualTo(expectedDate); + } + + @Test + public void givenJavaUtilDate_whenUsingNegativeHrsAndAddHoursWithApacheCommons_thenMinusHours() { + Date actualDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 7, 0).getTime(); + Date expectedDate = new GregorianCalendar(2018, Calendar.JUNE, 25, 5, 0).getTime(); + + assertThat(addHoursToDateObj.addHoursWithApacheCommons(actualDate, -2)).isEqualTo(expectedDate); + } + + @Test + public void givenInstant_whenUsingAddHoursToInstant_thenAddHours() { + Instant actualValue = Instant.parse("2018-06-25T05:12:35Z"); + Instant expectedValue = Instant.parse("2018-06-25T07:12:35Z"); + + assertThat(addHoursToDateObj.addHoursToInstant(actualValue, 2)).isEqualTo(expectedValue); + } + + @Test + public void givenInstant_whenUsingSubtractHoursToInstant_thenMinusHours() { + Instant actualValue = Instant.parse("2018-06-25T07:12:35Z"); + Instant expectedValue = Instant.parse("2018-06-25T05:12:35Z"); + + assertThat(addHoursToDateObj.subtractHoursToInstant(actualValue, 2)).isEqualTo(expectedValue); + } + +} diff --git a/core-java/src/test/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValuesUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValuesUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValuesUnitTest.java diff --git a/java-dates/src/test/java/com/baeldung/datetime/DateTimeFormatterUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/DateTimeFormatterUnitTest.java new file mode 100644 index 0000000000..f3b2b11893 --- /dev/null +++ b/java-dates/src/test/java/com/baeldung/datetime/DateTimeFormatterUnitTest.java @@ -0,0 +1,158 @@ +package com.baeldung.datetime; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.format.FormatStyle; +import java.time.temporal.ChronoUnit; +import java.util.Locale; +import java.util.TimeZone; + +public class DateTimeFormatterUnitTest { + + @Test + public void givenDefaultUsLocaleAndDateTimeAndPattern_whenFormatWithDifferentLocales_thenGettingLocalizedDateTimes() { + Locale.setDefault(Locale.US); + LocalDateTime localDateTime = LocalDateTime.of(2018, 1, 1, 10, 15, 50, 500); + String pattern = "dd-MMMM-yyyy HH:mm:ss.SSS"; + + DateTimeFormatter defaultTimeFormatter = DateTimeFormatter.ofPattern(pattern); + DateTimeFormatter plTimeFormatter = DateTimeFormatter.ofPattern(pattern, new Locale("pl", "PL")); + DateTimeFormatter deTimeFormatter = DateTimeFormatter.ofPattern(pattern).withLocale(Locale.GERMANY); + + Assert.assertEquals("01-January-2018 10:15:50.000", defaultTimeFormatter.format(localDateTime)); + Assert.assertEquals("01-stycznia-2018 10:15:50.000", plTimeFormatter.format(localDateTime)); + Assert.assertEquals("01-Januar-2018 10:15:50.000", deTimeFormatter.format(localDateTime)); + } + + @Test + public void givenDateTimeAndTimeZone_whenFormatWithDifferentLocales_thenGettingLocalizedZonedDateTimes() { + Locale.setDefault(Locale.US); + LocalDateTime localDateTime = LocalDateTime.of(2018, 1, 1, 10, 15, 50, 500); + ZoneId losAngelesTimeZone = TimeZone.getTimeZone("America/Los_Angeles").toZoneId(); + + DateTimeFormatter localizedFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL); + DateTimeFormatter frLocalizedFormatter = + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(Locale.FRANCE); + String formattedDateTime = localizedFormatter.format(ZonedDateTime.of(localDateTime, losAngelesTimeZone)); + String frFormattedDateTime = frLocalizedFormatter.format(ZonedDateTime.of(localDateTime, losAngelesTimeZone)); + + Assert.assertEquals("Monday, January 1, 2018 10:15:50 AM PST", formattedDateTime); + Assert.assertEquals("lundi 1 janvier 2018 10 h 15 PST", frFormattedDateTime); + } + + @Test + public void shouldPrintFormattedDate() { + String europeanDatePattern = "dd.MM.yyyy"; + DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern(europeanDatePattern); + LocalDate summerDay = LocalDate.of(2016, 7, 31); + Assert.assertEquals("31.07.2016", europeanDateFormatter.format(summerDay)); + } + + @Test + public void shouldPrintFormattedTime24() { + String timeColonPattern = "HH:mm:ss"; + DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); + LocalTime colonTime = LocalTime.of(17, 35, 50); + Assert.assertEquals("17:35:50", timeColonFormatter.format(colonTime)); + } + + @Test + public void shouldPrintFormattedTimeWithMillis() { + String timeColonPattern = "HH:mm:ss SSS"; + DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); + LocalTime colonTime = LocalTime.of(17, 35, 50).plus(329, ChronoUnit.MILLIS); + Assert.assertEquals("17:35:50 329", timeColonFormatter.format(colonTime)); + } + + @Test + public void shouldPrintFormattedTimePM() { + String timeColonPattern = "hh:mm:ss a"; + DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); + LocalTime colonTime = LocalTime.of(17, 35, 50); + Assert.assertEquals("05:35:50 PM", timeColonFormatter.format(colonTime)); + } + + @Test + public void shouldPrintFormattedUTCRelatedZonedDateTime() { + String newYorkDateTimePattern = "dd.MM.yyyy HH:mm z"; + DateTimeFormatter newYorkDateFormatter = DateTimeFormatter.ofPattern(newYorkDateTimePattern); + LocalDateTime summerDay = LocalDateTime.of(2016, 7, 31, 14, 15); + Assert.assertEquals("31.07.2016 14:15 UTC-04:00", newYorkDateFormatter.format(ZonedDateTime.of(summerDay, ZoneId.of("UTC-4")))); + } + + @Test + public void shouldPrintFormattedNewYorkZonedDateTime() { + String newYorkDateTimePattern = "dd.MM.yyyy HH:mm z"; + DateTimeFormatter newYorkDateFormatter = DateTimeFormatter.ofPattern(newYorkDateTimePattern); + LocalDateTime summerDay = LocalDateTime.of(2016, 7, 31, 14, 15); + Assert.assertEquals("31.07.2016 14:15 EDT", newYorkDateFormatter.format(ZonedDateTime.of(summerDay, ZoneId.of("America/New_York")))); + } + + @Test + public void shouldPrintStyledDate() { + LocalDate anotherSummerDay = LocalDate.of(2016, 8, 23); + Assert.assertEquals("Tuesday, August 23, 2016", DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(anotherSummerDay)); + Assert.assertEquals("August 23, 2016", DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(anotherSummerDay)); + Assert.assertEquals("Aug 23, 2016", DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(anotherSummerDay)); + Assert.assertEquals("8/23/16", DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(anotherSummerDay)); + } + + @Test + public void shouldPrintStyledDateTime() { + LocalDateTime anotherSummerDay = LocalDateTime.of(2016, 8, 23, 13, 12, 45); + Assert.assertEquals("Tuesday, August 23, 2016 1:12:45 PM EET", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withZone(ZoneId.of("Europe/Helsinki")).format(anotherSummerDay)); + Assert.assertEquals("August 23, 2016 1:12:45 PM EET", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withZone(ZoneId.of("Europe/Helsinki")).format(anotherSummerDay)); + Assert.assertEquals("Aug 23, 2016 1:12:45 PM", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withZone(ZoneId.of("Europe/Helsinki")).format(anotherSummerDay)); + Assert.assertEquals("8/23/16 1:12 PM", DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withZone(ZoneId.of("Europe/Helsinki")).format(anotherSummerDay)); + } + + @Test + public void shouldPrintFormattedDateTimeWithPredefined() { + Assert.assertEquals("2018-03-09", DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.of(2018, 3, 9))); + Assert.assertEquals("2018-03-09-03:00", DateTimeFormatter.ISO_OFFSET_DATE.format(LocalDate.of(2018, 3, 9).atStartOfDay(ZoneId.of("UTC-3")))); + Assert.assertEquals("Fri, 9 Mar 2018 00:00:00 -0300", DateTimeFormatter.RFC_1123_DATE_TIME.format(LocalDate.of(2018, 3, 9).atStartOfDay(ZoneId.of("UTC-3")))); + } + + @Test + public void shouldParseDateTime() { + Assert.assertEquals(LocalDate.of(2018, 3, 12), LocalDate.from(DateTimeFormatter.ISO_LOCAL_DATE.parse("2018-03-09")).plusDays(3)); + } + + @Test + public void shouldParseFormatStyleFull() { + ZonedDateTime dateTime = ZonedDateTime.from(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).parse("Tuesday, August 23, 2016 1:12:45 PM EET")); + Assert.assertEquals(ZonedDateTime.of(LocalDateTime.of(2016, 8, 23, 22, 12, 45), ZoneId.of("Europe/Bucharest")), dateTime.plusHours(9)); + } + + @Test + public void shouldParseDateWithCustomFormatter() { + DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + Assert.assertFalse(LocalDate.from(europeanDateFormatter.parse("15.08.2014")).isLeapYear()); + } + + @Test + public void shouldParseTimeWithCustomFormatter() { + DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss a"); + Assert.assertTrue(LocalTime.from(timeFormatter.parse("12:25:30 AM")).isBefore(LocalTime.NOON)); + } + + @Test + public void shouldParseZonedDateTimeWithCustomFormatter() { + DateTimeFormatter zonedFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm z"); + Assert.assertEquals(7200, ZonedDateTime.from(zonedFormatter.parse("31.07.2016 14:15 GMT+02:00")).getOffset().getTotalSeconds()); + } + + @Test(expected = DateTimeParseException.class) + public void shouldExpectAnExceptionIfDateTimeStringNotMatchPattern() { + DateTimeFormatter zonedFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm z"); + ZonedDateTime.from(zonedFormatter.parse("31.07.2016 14:15")); + } +} diff --git a/core-java/src/test/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValuesUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValuesUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValuesUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java diff --git a/java-dates/src/test/java/com/baeldung/datetime/UseTimeZoneUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseTimeZoneUnitTest.java new file mode 100644 index 0000000000..4423ac6ce0 --- /dev/null +++ b/java-dates/src/test/java/com/baeldung/datetime/UseTimeZoneUnitTest.java @@ -0,0 +1,72 @@ +package com.baeldung.datetime; + +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.junit.Assert; +import org.junit.Test; + +public class UseTimeZoneUnitTest { + + /* https://en.wikipedia.org/wiki/List_of_tz_database_time_zones */ + + String timeZone = "Asia/Singapore"; + + private static final String PATTERN = "E yyyy-MM-dd HH:mm:ss a"; + + @Test + public void givenDateWithoutTimeZone_WhenSetTimeZoneUsingJava7_ThenTimeZoneIsSetSuccessfully() { + Date nowUtc = new Date(); + TimeZone asiaSingapore = TimeZone.getTimeZone(timeZone); + + Calendar nowAsiaSingapore = Calendar.getInstance(asiaSingapore); + nowAsiaSingapore.setTime(nowUtc); + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN); + simpleDateFormat.setTimeZone(TimeZone.getTimeZone(timeZone)); + + System.out.println(String.format("Java7: Time now in '%s' is '%s'", nowAsiaSingapore.getTimeZone() + .getID(), simpleDateFormat.format(nowAsiaSingapore.getTime()))); + + Assert.assertEquals(nowUtc.toInstant().getEpochSecond(), nowAsiaSingapore.toInstant().getEpochSecond()); + Assert.assertEquals(asiaSingapore, nowAsiaSingapore.getTimeZone()); + + } + + @Test + public void givenDateWithoutTimeZone_WhenSetTimeZoneUsingJava8_ThenTimeZoneIsSetSuccessfully() { + Instant nowUtc = Instant.now(); + ZoneId asiaSingapore = ZoneId.of(timeZone); + + ZonedDateTime nowAsiaSingapore = ZonedDateTime.ofInstant(nowUtc, asiaSingapore); + + System.out.println(String.format("Java8: Time now in '%s' is '%s'", nowAsiaSingapore.getZone(), + nowAsiaSingapore.format(DateTimeFormatter.ofPattern(PATTERN)))); + + Assert.assertEquals(nowUtc.getEpochSecond(), nowAsiaSingapore.toEpochSecond()); + Assert.assertEquals(asiaSingapore, nowAsiaSingapore.getZone()); + } + + @Test + public void givenDateWithoutTimeZone_WhenSetTimeZoneUsingJodaTime_ThenTimeZoneIsSetSuccessfully() { + org.joda.time.Instant nowUtc = org.joda.time.Instant.now(); + DateTimeZone asiaSingapore = DateTimeZone.forID(timeZone); + + DateTime nowAsiaSingapore = nowUtc.toDateTime(asiaSingapore); + + System.out.println(String.format("Joda-time: Time now in '%s' is '%s'", nowAsiaSingapore.getZone(), + nowAsiaSingapore.toString(PATTERN))); + + Assert.assertEquals(nowUtc.toInstant().getMillis(), nowAsiaSingapore.toInstant().getMillis()); + Assert.assertEquals(asiaSingapore, nowAsiaSingapore.getZone()); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest.java rename to java-dates/src/test/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest.java diff --git a/java-dates/src/test/java/com/baeldung/datetime/modify/DateIncrementerUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/modify/DateIncrementerUnitTest.java new file mode 100644 index 0000000000..e384bf4254 --- /dev/null +++ b/java-dates/src/test/java/com/baeldung/datetime/modify/DateIncrementerUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.datetime.modify; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class DateIncrementerUnitTest { + private final static String DATE_TO_INCREMENT = "2018-07-03"; + private final static String EXPECTED_DATE = "2018-07-04"; + + @Test + public void givenDate_whenUsingJava8_thenAddOneDay() throws Exception { + String incrementedDate = DateIncrementer.addOneDay(DATE_TO_INCREMENT); + assertEquals(EXPECTED_DATE, incrementedDate); + } + + @Test + public void givenDate_whenUsingJodaTime_thenAddOneDay() throws Exception { + String incrementedDate = DateIncrementer.addOneDayJodaTime(DATE_TO_INCREMENT); + assertEquals(EXPECTED_DATE, incrementedDate); + } + + @Test + public void givenDate_whenUsingCalendar_thenAddOneDay() throws Exception { + String incrementedDate = DateIncrementer.addOneDayCalendar(DATE_TO_INCREMENT); + assertEquals(EXPECTED_DATE, incrementedDate); + } + + @Test + public void givenDate_whenUsingApacheCommons_thenAddOneDay() throws Exception { + String incrementedDate = DateIncrementer.addOneDayApacheCommons(DATE_TO_INCREMENT); + assertEquals(EXPECTED_DATE, incrementedDate); + } +} diff --git a/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesUnitTest.java b/java-dates/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesUnitTest.java rename to java-dates/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesUnitTest.java b/java-dates/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesUnitTest.java rename to java-dates/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesUnitTest.java diff --git a/java-dates/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java b/java-dates/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java new file mode 100644 index 0000000000..a1d084cf9a --- /dev/null +++ b/java-dates/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java @@ -0,0 +1,228 @@ +package com.baeldung.gregorian.calendar; + +import static org.junit.Assert.*; + +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.junit.Test; + +import com.baeldung.gregorian.calendar.GregorianCalendarExample; + +public class GregorianCalendarTester { + + @Test + public void test_Calendar_Return_Type_Valid() { + Calendar calendar = Calendar.getInstance(); + assert ("gregory".equals(calendar.getCalendarType())); + } + + @Test + public void test_Calendar_Return_Type_InValid() { + Calendar calendar = Calendar.getInstance(); + assertNotEquals("gregorys", calendar.getCalendarType()); + } + + @Test(expected = ClassCastException.class) + public void test_Class_Cast_Exception() { + TimeZone tz = TimeZone.getTimeZone("GMT+9:00"); + Locale loc = new Locale("ja", "JP", "JP"); + Calendar calendar = Calendar.getInstance(loc); + GregorianCalendar gc = (GregorianCalendar) calendar; + } + + @Test + public void test_Getting_Calendar_information() { + GregorianCalendar calendar = new GregorianCalendar(2018, 5, 28); + assertTrue(false == calendar.isLeapYear(calendar.YEAR)); + assertTrue(52 == calendar.getWeeksInWeekYear()); + assertTrue(2018 == calendar.getWeekYear()); + assertTrue(30 == calendar.getActualMaximum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getActualMinimum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getGreatestMinimum(calendar.DAY_OF_MONTH)); + assertTrue(28 == calendar.getLeastMaximum(calendar.DAY_OF_MONTH)); + assertTrue(31 == calendar.getMaximum(calendar.DAY_OF_MONTH)); + assertTrue(1 == calendar.getMinimum(calendar.DAY_OF_MONTH)); + assertTrue(52 == calendar.getWeeksInWeekYear()); + } + + @Test + public void test_Compare_Date_FirstDate_Greater_SecondDate() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 6, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 5, 28); + assertTrue(1 == firstDate.compareTo(secondDate)); + } + + + @Test + public void test_Compare_Date_FirstDate_Smaller_SecondDate() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 5, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 6, 28); + assertTrue(-1 == firstDate.compareTo(secondDate)); + } + + @Test + public void test_Compare_Date_Both_Dates_Equal() { + GregorianCalendar firstDate = new GregorianCalendar(2018, 6, 28); + GregorianCalendar secondDate = new GregorianCalendar(2018, 6, 28); + assertTrue(0 == firstDate.compareTo(secondDate)); + } + + @Test + public void test_date_format() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendar = new GregorianCalendar(2018, 6, 28); + assertEquals("28 Jul 2018", calendarDemo.formatDate(calendar)); + } + + @Test + public void test_dateFormatdMMMuuuu() { + String expectedDate = new GregorianCalendar(2018, 6, 28).toZonedDateTime() + .format(DateTimeFormatter.ofPattern("d MMM uuuu")); + assertEquals("28 Jul 2018", expectedDate); + } + + @Test + public void test_addDays() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.add(Calendar.DATE, 1); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.addDays(calendarActual, 1)); + } + + @Test + public void test_whenAddOneDay_thenMonthIsChanged() { + final int finalDay1 = 1; + final int finalMonthJul = 6; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 5, 30); + calendarExpected.add(Calendar.DATE, 1); + System.out.println(calendarExpected.getTime()); + assertEquals(calendarExpected.get(Calendar.DATE), finalDay1); + assertEquals(calendarExpected.get(Calendar.MONTH), finalMonthJul); + } + + @Test + public void test_whenSubtractOneDay_thenMonthIsChanged() { + final int finalDay31 = 31; + final int finalMonthMay = 4; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 5, 1); + calendarExpected.add(Calendar.DATE, -1); + assertEquals(calendarExpected.get(Calendar.DATE), finalDay31); + assertEquals(calendarExpected.get(Calendar.MONTH), finalMonthMay); + } + + @Test + public void test_subDays() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.add(Calendar.DATE, -1); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.subtractDays(calendarActual, 1)); + } + + @Test + public void test_rollAdd() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, 8); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.rollAdd(calendarActual, 8)); + } + + @Test + public void test_whenRollUpOneMonth_thenYearIsUnchanged() { + final int rolledUpMonthJuly = 7, orginalYear2018 = 2018; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, 1); + assertEquals(calendarExpected.get(Calendar.MONTH), rolledUpMonthJuly); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + } + + @Test + public void test_whenRollDownOneMonth_thenYearIsUnchanged() { + final int rolledDownMonthJune = 5, orginalYear2018 = 2018; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, -1); + assertEquals(calendarExpected.get(Calendar.MONTH), rolledDownMonthJune); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + } + + @Test + public void test_rollSubtract() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.roll(Calendar.MONTH, -8); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.rollAdd(calendarActual, -8)); + } + + @Test + public void test_setMonth() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.set(Calendar.MONTH, 3); + Date expectedDate = calendarExpected.getTime(); + assertEquals(expectedDate, calendarDemo.setMonth(calendarActual, 3)); + } + + @Test + public void test_setMonthApril() { + final int setMonthApril = 3, orginalYear2018 = 2018, originalDate28 = 28; + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + calendarExpected.set(Calendar.MONTH, 3); + assertEquals(calendarExpected.get(Calendar.MONTH), setMonthApril); + assertEquals(calendarExpected.get(Calendar.YEAR), orginalYear2018); + assertEquals(calendarExpected.get(Calendar.DATE), originalDate28); + } + + @Test + public void test_toXMLGregorianCalendar() throws DatatypeConfigurationException { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + GregorianCalendar calendarExpected = new GregorianCalendar(2018, 6, 28); + XMLGregorianCalendar expectedXMLGregorianCalendar = datatypeFactory + .newXMLGregorianCalendar(calendarExpected); + assertEquals(expectedXMLGregorianCalendar, + calendarDemo.toXMLGregorianCalendar(calendarActual)); + } + + @Test + public void test_isLeapYear_True() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + assertEquals(true, calendarDemo.isLeapYearExample(2016)); + + } + + @Test + public void test_isLeapYear_False() { + GregorianCalendarExample calendarDemo = new GregorianCalendarExample(); + assertEquals(false, calendarDemo.isLeapYearExample(2018)); + + } + + @Test + public void test_toDate() throws DatatypeConfigurationException { + GregorianCalendar calendarActual = new GregorianCalendar(2018, 6, 28); + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + XMLGregorianCalendar expectedXMLGregorianCalendar = datatypeFactory + .newXMLGregorianCalendar(calendarActual); + expectedXMLGregorianCalendar.toGregorianCalendar().getTime(); + assertEquals(calendarActual.getTime(), + expectedXMLGregorianCalendar.toGregorianCalendar().getTime() ); + } +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java b/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java similarity index 98% rename from core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java rename to java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java index ab69bba359..f7f07500f1 100644 --- a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java +++ b/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java @@ -20,7 +20,7 @@ import com.baeldung.java9.datetime.DateToLocalDateConverter; * @author abialas * */ -public class DateToLocalDateConverterTest { +public class DateToLocalDateConverterUnitTest { @Test public void shouldReturn10thNovember2010WhenConvertViaInstant() { diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java b/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java similarity index 98% rename from core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java rename to java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java index 97c70ee5ac..9ad29ea673 100644 --- a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java +++ b/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java @@ -20,7 +20,7 @@ import com.baeldung.java9.datetime.DateToLocalDateTimeConverter; * @author abialas * */ -public class DateToLocalDateTimeConverterTest { +public class DateToLocalDateTimeConverterUnitTest { @Test public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() { diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java b/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java similarity index 97% rename from core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java rename to java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java index 2c6898381f..e5a541c546 100644 --- a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java +++ b/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java @@ -18,7 +18,7 @@ import org.junit.Test; * @author abialas * */ -public class LocalDateTimeToDateConverterTest { +public class LocalDateTimeToDateConverterUnitTest { @Test public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() { diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java b/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java similarity index 96% rename from core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java rename to java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java index 7f20d5d2d2..4e4dd20f2f 100644 --- a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java +++ b/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java @@ -18,7 +18,7 @@ import org.junit.Test; * @author abialas * */ -public class LocalDateToDateConverterTest { +public class LocalDateToDateConverterUnitTest { @Test public void shouldReturn10thNovember2010WhenConvertViaInstant() { diff --git a/core-java-9/src/test/java/com/baeldung/java9/time/TimeApiTest.java b/java-dates/src/test/java/com/baeldung/java9/time/TimeApiUnitTest.java similarity index 98% rename from core-java-9/src/test/java/com/baeldung/java9/time/TimeApiTest.java rename to java-dates/src/test/java/com/baeldung/java9/time/TimeApiUnitTest.java index a024db19a8..8813870c2b 100644 --- a/core-java-9/src/test/java/com/baeldung/java9/time/TimeApiTest.java +++ b/java-dates/src/test/java/com/baeldung/java9/time/TimeApiUnitTest.java @@ -8,7 +8,7 @@ import java.util.List; import static org.junit.Assert.assertEquals; import org.junit.Test; -public class TimeApiTest { +public class TimeApiUnitTest { @Test public void givenGetDatesBetweenWithUsingJava7_WhenStartEndDate_thenDatesList() { diff --git a/libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java rename to java-dates/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java index 3cf4f739e8..c2340e9528 100644 --- a/libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java +++ b/java-dates/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java @@ -86,7 +86,6 @@ public class JodaTimeUnitTest { DateTimeUtils.setCurrentMillisFixed(currentTimestamp); LocalDateTime currentDateAndTime = LocalDateTime.now(); - assertEquals(currentTimestamp, currentDateAndTime.toDate().getTime()); assertEquals(new DateTime(currentTimestamp), currentDateAndTime.toDateTime()); assertEquals(new LocalDate(currentTimestamp), currentDateAndTime.toLocalDate()); assertEquals(new LocalTime(currentTimestamp), currentDateAndTime.toLocalTime()); @@ -182,9 +181,6 @@ public class JodaTimeUnitTest { DateTime convertedDateTime = localDateTimeInChicago.toDateTime(DateTimeZone.forID("Europe/Bucharest")); assertEquals("2018-06-21T15:26:23.288+03:00", convertedDateTime.toString()); - - Date convertedDate = localDateTimeInChicago.toDate(TimeZone.getTimeZone("Europe/Bucharest")); - assertEquals("Thu Jun 21 15:26:23 EEST 2018", convertedDate.toString()); } } diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/FormattedDateMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/FormattedDateMatcherUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/regexp/datepattern/FormattedDateMatcherUnitTest.java rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/FormattedDateMatcherUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/RangedDateMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/RangedDateMatcherUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/regexp/datepattern/RangedDateMatcherUnitTest.java rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/RangedDateMatcherUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcherUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcherUnitTest.java rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcherUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcherUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcherUnitTest.java rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcherUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcherUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcherUnitTest.java rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcherUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcherUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcherUnitTest.java rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcherUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcherUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcherUnitTest.java rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcherUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java similarity index 100% rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java diff --git a/core-java-8/src/test/java/com/baeldung/temporaladjusters/CustomTemporalAdjusterUnitTest.java b/java-dates/src/test/java/com/baeldung/temporaladjusters/CustomTemporalAdjusterUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/temporaladjusters/CustomTemporalAdjusterUnitTest.java rename to java-dates/src/test/java/com/baeldung/temporaladjusters/CustomTemporalAdjusterUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/temporaladjusters/TemporalAdjustersUnitTest.java b/java-dates/src/test/java/com/baeldung/temporaladjusters/TemporalAdjustersUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/temporaladjusters/TemporalAdjustersUnitTest.java rename to java-dates/src/test/java/com/baeldung/temporaladjusters/TemporalAdjustersUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/time/ElapsedTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/time/ElapsedTimeUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/time/ElapsedTimeUnitTest.java rename to java-dates/src/test/java/com/baeldung/time/ElapsedTimeUnitTest.java diff --git a/java-dates/src/test/java/com/baeldung/zoneddatetime/ZonedDateTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/zoneddatetime/ZonedDateTimeUnitTest.java new file mode 100644 index 0000000000..355fef35c6 --- /dev/null +++ b/java-dates/src/test/java/com/baeldung/zoneddatetime/ZonedDateTimeUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.zoneddatetime; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.logging.Logger; + +import org.junit.Test; + +public class ZonedDateTimeUnitTest { + + private static final Logger log = Logger.getLogger(ZonedDateTimeUnitTest.class.getName()); + + @Test + public void testZonedDateTimeToString() { + + ZonedDateTime zonedDateTimeNow = ZonedDateTime.now(ZoneId.of("UTC")); + ZonedDateTime zonedDateTimeOf = ZonedDateTime.of(2018, 01, 01, 0, 0, 0, 0, ZoneId.of("UTC")); + + LocalDateTime localDateTime = LocalDateTime.now(); + ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("UTC")); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy - hh:mm:ss Z"); + String formattedString = zonedDateTime.format(formatter); + + DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/dd/yyyy - hh:mm:ss z"); + String formattedString2 = zonedDateTime.format(formatter2); + + log.info(formattedString); + log.info(formattedString2); + + } + + @Test + public void testZonedDateTimeFromString() { + + ZonedDateTime zonedDateTime = ZonedDateTime.parse("2011-12-03T10:15:30+01:00", DateTimeFormatter.ISO_ZONED_DATE_TIME); + + log.info(zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + } + +} diff --git a/spring-mvc-xml/src/test/resources/.gitignore b/java-dates/src/test/resources/.gitignore similarity index 100% rename from spring-mvc-xml/src/test/resources/.gitignore rename to java-dates/src/test/resources/.gitignore diff --git a/java-difference-date/README.md b/java-difference-date/README.md deleted file mode 100644 index 2a024c27a2..0000000000 --- a/java-difference-date/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## Relevant articles: - -- [Period and Duration in Java](http://www.baeldung.com/java-period-duration) -- [Introduction to the Java 8 Date/Time API](http://www.baeldung.com/java-8-date-time-intro) -- [Migrating to the New Java 8 Date Time API](http://www.baeldung.com/migrating-to-java-8-date-time-api) \ No newline at end of file diff --git a/java-difference-date/pom.xml b/java-difference-date/pom.xml deleted file mode 100644 index ad66623581..0000000000 --- a/java-difference-date/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - 4.0.0 - com.baeldung - java-difference-date - 0.0.1-SNAPSHOT - jar - java-difference-date - Difference between two dates in java - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - joda-time - joda-time - ${joda-time.version} - - - com.darwinsys - hirondelle-date4j - ${hirondelle-date4j.version} - - - junit - junit - ${junit.version} - test - - - - - 4.12 - 2.9.9 - 1.5.1 - - - diff --git a/java-difference-date/src/test/java/com/baeldung/DateDiffTest.java b/java-difference-date/src/test/java/com/baeldung/DateDiffTest.java deleted file mode 100644 index 4203f7ef38..0000000000 --- a/java-difference-date/src/test/java/com/baeldung/DateDiffTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.baeldung; - -import org.joda.time.DateTime; -import org.junit.Test; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.Duration; -import java.time.ZonedDateTime; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; - -public class DateDiffTest { - @Test - public void givenTwoDatesBeforeJava8_whenDifferentiating_thenWeGetSix() throws ParseException { - SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH); - Date firstDate = sdf.parse("06/24/2017"); - Date secondDate = sdf.parse("06/30/2017"); - - long diffInMillies = Math.abs(secondDate.getTime() - firstDate.getTime()); - long diff = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS); - - assertEquals(diff, 6); - } - - @Test - public void givenTwoDatesInJava8_whenDifferentiating_thenWeGetSix() { - ZonedDateTime now = ZonedDateTime.now(); - ZonedDateTime sixDaysBehind = now.minusDays(6); - - Duration duration = Duration.between(now, sixDaysBehind); - long diff = Math.abs(duration.toDays()); - - assertEquals(diff, 6); - } - - @Test - public void givenTwoDatesInJodaTime_whenDifferentiating_thenWeGetSix() { - DateTime now = DateTime.now(); - DateTime sixDaysBehind = now.minusDays(6); - - org.joda.time.Duration duration = new org.joda.time.Duration(now, sixDaysBehind); - long diff = Math.abs(duration.getStandardDays()); - - assertEquals(diff, 6); - } - - @Test - public void givenTwoDatesInDate4j_whenDifferentiating_thenWeGetSix() { - hirondelle.date4j.DateTime now = hirondelle.date4j.DateTime.now(TimeZone.getDefault()); - hirondelle.date4j.DateTime sixDaysBehind = now.minusDays(6); - - long diff = Math.abs(now.numDaysFrom(sixDaysBehind)); - - assertEquals(diff, 6); - } -} \ No newline at end of file diff --git a/java-ee-8-security-api/app-auth-basic-store-db/pom.xml b/java-ee-8-security-api/app-auth-basic-store-db/pom.xml index 7782fd0479..6ecc9f7e80 100644 --- a/java-ee-8-security-api/app-auth-basic-store-db/pom.xml +++ b/java-ee-8-security-api/app-auth-basic-store-db/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 app-auth-basic-store-db @@ -13,10 +12,6 @@ 1.0-SNAPSHOT
    - - 1.4.197 - - @@ -69,4 +64,8 @@ + + + 1.4.197 +
    diff --git a/java-ee-8-security-api/app-auth-basic-store-db/src/main/resources/logback.xml b/java-ee-8-security-api/app-auth-basic-store-db/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-ee-8-security-api/app-auth-basic-store-db/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-ee-8-security-api/app-auth-custom-form-store-custom/pom.xml b/java-ee-8-security-api/app-auth-custom-form-store-custom/pom.xml index 35a90621ae..bf5315e993 100644 --- a/java-ee-8-security-api/app-auth-custom-form-store-custom/pom.xml +++ b/java-ee-8-security-api/app-auth-custom-form-store-custom/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 app-auth-custom-form-store-custom diff --git a/java-ee-8-security-api/app-auth-custom-form-store-custom/src/main/resources/logback.xml b/java-ee-8-security-api/app-auth-custom-form-store-custom/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-ee-8-security-api/app-auth-custom-form-store-custom/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-ee-8-security-api/app-auth-custom-no-store/pom.xml b/java-ee-8-security-api/app-auth-custom-no-store/pom.xml index 32e20fb066..c05c0f19be 100644 --- a/java-ee-8-security-api/app-auth-custom-no-store/pom.xml +++ b/java-ee-8-security-api/app-auth-custom-no-store/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 app-auth-custom-no-store @@ -13,10 +12,6 @@ 1.0-SNAPSHOT - - 1.4.197 - - @@ -69,4 +64,8 @@ + + + 1.4.197 + diff --git a/java-ee-8-security-api/app-auth-custom-no-store/src/main/resources/logback.xml b/java-ee-8-security-api/app-auth-custom-no-store/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-ee-8-security-api/app-auth-custom-no-store/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-ee-8-security-api/app-auth-form-store-ldap/src/main/resources/logback.xml b/java-ee-8-security-api/app-auth-form-store-ldap/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-ee-8-security-api/app-auth-form-store-ldap/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-ee-8-security-api/pom.xml b/java-ee-8-security-api/pom.xml index cdc288f469..3d235e10a8 100644 --- a/java-ee-8-security-api/pom.xml +++ b/java-ee-8-security-api/pom.xml @@ -3,46 +3,32 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - - com.baeldung java-ee-8-security-api 1.0-SNAPSHOT pom - - 1.8 - 1.8 - UTF-8 - - 9080 - 9443 - - 8.0 - 2.3 - 18.0.0.1 - 1.4.197 - - - - app-auth-basic-store-db - app-auth-form-store-ldap - app-auth-custom-form-store-custom - app-auth-custom-no-store - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + javax javaee-web-api ${javaee-version} provided + maven-war-plugin + ${maven-war-plugin.version} false pom.xml @@ -70,4 +56,24 @@ + + + 9080 + 9443 + + 8.0 + 2.3 + 18.0.0.1 + 1.4.197 + + 3.2.2 + + + + app-auth-basic-store-db + app-auth-form-store-ldap + app-auth-custom-form-store-custom + app-auth-custom-no-store + + diff --git a/java-lite/pom.xml b/java-lite/pom.xml index 7c0ed1c780..5111cd2e7f 100644 --- a/java-lite/pom.xml +++ b/java-lite/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung java-lite @@ -41,11 +41,6 @@ test - - junit - junit - ${junit.version} - diff --git a/java-lite/src/main/resources/logback.xml b/java-lite/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-lite/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-numbers/.gitignore b/java-numbers/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/java-numbers/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/java-numbers/README.md b/java-numbers/README.md new file mode 100644 index 0000000000..6d6a279cc9 --- /dev/null +++ b/java-numbers/README.md @@ -0,0 +1,14 @@ +========= + +## Java Number Cookbooks and Examples + +### Relevant Articles: +- [Number of Digits in an Integer in Java](http://www.baeldung.com/java-number-of-digits-in-int) +- [NaN in Java](http://www.baeldung.com/java-not-a-number) +- [How to Round a Number to N Decimal Places in Java](http://www.baeldung.com/java-round-decimal-number) +- [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers) +- [Using Math.pow in Java](http://www.baeldung.com/java-math-pow) +- [Generating Prime Numbers in Java](http://www.baeldung.com/java-generate-prime-numbers) +- [BigDecimal and BigInteger in Java](http://www.baeldung.com/java-bigdecimal-biginteger) +- [Find All Pairs of Numbers in an Array That Add Up to a Given Sum](http://www.baeldung.com/java-algorithm-number-pairs-sum) +- [Java – Random Long, Float, Integer and Double](http://www.baeldung.com/java-generate-random-long-float-integer-double) diff --git a/java-numbers/pom.xml b/java-numbers/pom.xml new file mode 100644 index 0000000000..bb63c8cfe1 --- /dev/null +++ b/java-numbers/pom.xml @@ -0,0 +1,146 @@ + + 4.0.0 + java-numbers + 0.1.0-SNAPSHOT + jar + java-numbers + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + log4j + log4j + ${log4j.version} + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-generator-annprocess.version} + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.decimal4j + decimal4j + ${decimal4j.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + java-numbers + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + + true + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + 1.8 + 1.8 + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + 3.6.1 + 1.0.3 + 3.5 + + 3.6.1 + + 1.7.21 + 1.1.7 + 1.19 + 1.19 + + 2.21.0 + 3.0.0-M1 + 3.0.2 + + diff --git a/algorithms/src/main/java/com/baeldung/algorithms/primechecker/BigIntegerPrimeChecker.java b/java-numbers/src/main/java/com/baeldung/algorithms/primechecker/BigIntegerPrimeChecker.java similarity index 100% rename from algorithms/src/main/java/com/baeldung/algorithms/primechecker/BigIntegerPrimeChecker.java rename to java-numbers/src/main/java/com/baeldung/algorithms/primechecker/BigIntegerPrimeChecker.java diff --git a/algorithms/src/main/java/com/baeldung/algorithms/primechecker/BruteForcePrimeChecker.java b/java-numbers/src/main/java/com/baeldung/algorithms/primechecker/BruteForcePrimeChecker.java similarity index 83% rename from algorithms/src/main/java/com/baeldung/algorithms/primechecker/BruteForcePrimeChecker.java rename to java-numbers/src/main/java/com/baeldung/algorithms/primechecker/BruteForcePrimeChecker.java index 47ffb3e224..68382c26ea 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/primechecker/BruteForcePrimeChecker.java +++ b/java-numbers/src/main/java/com/baeldung/algorithms/primechecker/BruteForcePrimeChecker.java @@ -1,16 +1,14 @@ package com.baeldung.algorithms.primechecker; import java.util.stream.IntStream; -import java.util.stream.LongStream; -public class BruteForcePrimeChecker implements PrimeChecker{ +public class BruteForcePrimeChecker implements PrimeChecker { @Override public boolean isPrime(Integer number) { - + return number > 2 ? IntStream.range(2, number) .noneMatch(n -> (number % n == 0)) : false; } - -} +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/primechecker/OptimisedPrimeChecker.java b/java-numbers/src/main/java/com/baeldung/algorithms/primechecker/OptimisedPrimeChecker.java similarity index 88% rename from algorithms/src/main/java/com/baeldung/algorithms/primechecker/OptimisedPrimeChecker.java rename to java-numbers/src/main/java/com/baeldung/algorithms/primechecker/OptimisedPrimeChecker.java index 06ae4acc7f..3dc372ad22 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/primechecker/OptimisedPrimeChecker.java +++ b/java-numbers/src/main/java/com/baeldung/algorithms/primechecker/OptimisedPrimeChecker.java @@ -1,9 +1,8 @@ package com.baeldung.algorithms.primechecker; import java.util.stream.IntStream; -import java.util.stream.LongStream; -public class OptimisedPrimeChecker implements PrimeChecker{ +public class OptimisedPrimeChecker implements PrimeChecker { @Override public boolean isPrime(Integer number) { @@ -11,5 +10,4 @@ public class OptimisedPrimeChecker implements PrimeChecker{ .noneMatch(n -> (number % n == 0)) : false; } - } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/primechecker/PrimeChecker.java b/java-numbers/src/main/java/com/baeldung/algorithms/primechecker/PrimeChecker.java similarity index 100% rename from algorithms/src/main/java/com/baeldung/algorithms/primechecker/PrimeChecker.java rename to java-numbers/src/main/java/com/baeldung/algorithms/primechecker/PrimeChecker.java diff --git a/algorithms/src/main/java/com/baeldung/algorithms/primechecker/PrimesPrimeChecker.java b/java-numbers/src/main/java/com/baeldung/algorithms/primechecker/PrimesPrimeChecker.java similarity index 100% rename from algorithms/src/main/java/com/baeldung/algorithms/primechecker/PrimesPrimeChecker.java rename to java-numbers/src/main/java/com/baeldung/algorithms/primechecker/PrimesPrimeChecker.java diff --git a/java-numbers/src/main/java/com/baeldung/maths/BigDecimalDemo.java b/java-numbers/src/main/java/com/baeldung/maths/BigDecimalDemo.java new file mode 100644 index 0000000000..7de0197769 --- /dev/null +++ b/java-numbers/src/main/java/com/baeldung/maths/BigDecimalDemo.java @@ -0,0 +1,29 @@ +package com.baeldung.maths; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class BigDecimalDemo { + + /** Calculate total amount to be paid for an item rounded to cents.. + * @param quantity + * @param unitPrice + * @param discountRate + * @param taxRate + * @return + */ + public static BigDecimal calculateTotalAmount(BigDecimal quantity, + BigDecimal unitPrice, BigDecimal discountRate, BigDecimal taxRate) { + BigDecimal amount = quantity.multiply(unitPrice); + BigDecimal discount = amount.multiply(discountRate); + BigDecimal discountedAmount = amount.subtract(discount); + BigDecimal tax = discountedAmount.multiply(taxRate); + BigDecimal total = discountedAmount.add(tax); + + // round to 2 decimal places using HALF_EVEN + BigDecimal roundedTotal = total.setScale(2, RoundingMode.HALF_EVEN); + + return roundedTotal; + } + +} diff --git a/core-java/src/main/java/com/baeldung/maths/FloatingPointArithmetic.java b/java-numbers/src/main/java/com/baeldung/maths/FloatingPointArithmetic.java similarity index 100% rename from core-java/src/main/java/com/baeldung/maths/FloatingPointArithmetic.java rename to java-numbers/src/main/java/com/baeldung/maths/FloatingPointArithmetic.java diff --git a/core-java/src/main/java/com/baeldung/maths/Round.java b/java-numbers/src/main/java/com/baeldung/maths/Round.java similarity index 100% rename from core-java/src/main/java/com/baeldung/maths/Round.java rename to java-numbers/src/main/java/com/baeldung/maths/Round.java diff --git a/core-java/src/main/java/com/baeldung/nan/NaNExample.java b/java-numbers/src/main/java/com/baeldung/nan/NaNExample.java similarity index 100% rename from core-java/src/main/java/com/baeldung/nan/NaNExample.java rename to java-numbers/src/main/java/com/baeldung/nan/NaNExample.java diff --git a/core-java/src/main/java/com/baeldung/numberofdigits/Benchmarking.java b/java-numbers/src/main/java/com/baeldung/numberofdigits/Benchmarking.java similarity index 100% rename from core-java/src/main/java/com/baeldung/numberofdigits/Benchmarking.java rename to java-numbers/src/main/java/com/baeldung/numberofdigits/Benchmarking.java diff --git a/core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigits.java b/java-numbers/src/main/java/com/baeldung/numberofdigits/NumberOfDigits.java similarity index 100% rename from core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigits.java rename to java-numbers/src/main/java/com/baeldung/numberofdigits/NumberOfDigits.java diff --git a/core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java b/java-numbers/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java similarity index 91% rename from core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java rename to java-numbers/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java index c3cc567eaa..4f98992e98 100755 --- a/core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java +++ b/java-numbers/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java @@ -4,32 +4,32 @@ import org.apache.log4j.Logger; public class NumberOfDigitsDriver { private static NumberOfDigits numberOfDigits; - + private static Logger LOG = Logger.getLogger(NumberOfDigitsDriver.class); - + static { numberOfDigits = new NumberOfDigits(); } - + public static void main(String[] args) { LOG.info("Testing all methods..."); - + long length = numberOfDigits.stringBasedSolution(602); LOG.info("String Based Solution : " + length); - + length = numberOfDigits.logarithmicApproach(602); LOG.info("Logarithmic Approach : " + length); - + length = numberOfDigits.repeatedMultiplication(602); LOG.info("Repeated Multiplication : " + length); - + length = numberOfDigits.shiftOperators(602); LOG.info("Shift Operators : " + length); - + length = numberOfDigits.dividingWithPowersOf2(602); LOG.info("Dividing with Powers of 2 : " + length); - + length = numberOfDigits.divideAndConquer(602); LOG.info("Divide And Conquer : " + length); } -} +} \ No newline at end of file diff --git a/algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/DifferentPairs.java b/java-numbers/src/main/java/com/baeldung/pairsaddupnumber/DifferentPairs.java similarity index 93% rename from algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/DifferentPairs.java rename to java-numbers/src/main/java/com/baeldung/pairsaddupnumber/DifferentPairs.java index e86e1d5a22..b316957652 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/DifferentPairs.java +++ b/java-numbers/src/main/java/com/baeldung/pairsaddupnumber/DifferentPairs.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.pairsaddupnumber; +package com.baeldung.pairsaddupnumber; import java.util.ArrayList; @@ -23,7 +23,7 @@ public class DifferentPairs { public static List findPairsWithForLoop(int[] input, int sum) { final List allDifferentPairs = new ArrayList<>(); // Aux. hash map - final Map pairs = new HashMap(); + final Map pairs = new HashMap<>(); for (int i : input) { if (pairs.containsKey(i)) { if (pairs.get(i) != null) { @@ -51,7 +51,7 @@ public class DifferentPairs { public static List findPairsWithStreamApi(int[] input, int sum) { final List allDifferentPairs = new ArrayList<>(); // Aux. hash map - final Map pairs = new HashMap(); + final Map pairs = new HashMap<>(); IntStream.range(0, input.length).forEach(i -> { if (pairs.containsKey(input[i])) { if (pairs.get(input[i]) != null) { diff --git a/algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/ExistingPairs.java b/java-numbers/src/main/java/com/baeldung/pairsaddupnumber/ExistingPairs.java similarity index 97% rename from algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/ExistingPairs.java rename to java-numbers/src/main/java/com/baeldung/pairsaddupnumber/ExistingPairs.java index 6b10c73bcf..82c2a54ae6 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/ExistingPairs.java +++ b/java-numbers/src/main/java/com/baeldung/pairsaddupnumber/ExistingPairs.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.pairsaddupnumber; +package com.baeldung.pairsaddupnumber; import java.util.ArrayList; diff --git a/algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/FindPairs.java b/java-numbers/src/main/java/com/baeldung/pairsaddupnumber/FindPairs.java similarity index 98% rename from algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/FindPairs.java rename to java-numbers/src/main/java/com/baeldung/pairsaddupnumber/FindPairs.java index 4b309332ae..b990222b7e 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/pairsaddupnumber/FindPairs.java +++ b/java-numbers/src/main/java/com/baeldung/pairsaddupnumber/FindPairs.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.pairsaddupnumber; +package com.baeldung.pairsaddupnumber; import java.util.ArrayList; import java.util.List; diff --git a/java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java b/java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java new file mode 100644 index 0000000000..e74de2cc67 --- /dev/null +++ b/java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java @@ -0,0 +1,21 @@ +package com.baeldung.percentage; + +import java.util.Scanner; + +public class PercentageCalculator { + + public double calculatePercentage(double obtained,double total){ + return obtained*100/total; + } + + public static void main(String[] args) { + PercentageCalculator pc = new PercentageCalculator(); + Scanner in = new Scanner(System.in); + System.out.println("Enter obtained marks:"); + double obtained = in.nextDouble(); + System.out.println("Enter total marks:"); + double total =in.nextDouble(); + System.out.println("Percentage obtained :"+pc.calculatePercentage(obtained,total)); + } + +} diff --git a/core-java/src/main/java/com/baeldung/pow/PowerExample.java b/java-numbers/src/main/java/com/baeldung/pow/PowerExample.java similarity index 100% rename from core-java/src/main/java/com/baeldung/pow/PowerExample.java rename to java-numbers/src/main/java/com/baeldung/pow/PowerExample.java diff --git a/core-java-8/src/main/java/com/baeldung/prime/PrimeGenerator.java b/java-numbers/src/main/java/com/baeldung/prime/PrimeGenerator.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/prime/PrimeGenerator.java rename to java-numbers/src/main/java/com/baeldung/prime/PrimeGenerator.java diff --git a/out/production/main330/log4j.properties b/java-numbers/src/main/resources/log4j.properties similarity index 60% rename from out/production/main330/log4j.properties rename to java-numbers/src/main/resources/log4j.properties index 5fe42d854c..621cf01735 100644 --- a/out/production/main330/log4j.properties +++ b/java-numbers/src/main/resources/log4j.properties @@ -1,9 +1,6 @@ -# Set root logger level to DEBUG and its only appender to A1. log4j.rootLogger=DEBUG, A1 -# A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender -# A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file diff --git a/java-numbers/src/main/resources/logback.xml b/java-numbers/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-numbers/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/algorithms/src/test/java/com/baeldung/algorithms/primechecker/PrimeCheckerUnitTest.java b/java-numbers/src/test/java/com/baeldung/algorithms/primechecker/PrimeCheckerUnitTest.java similarity index 85% rename from algorithms/src/test/java/com/baeldung/algorithms/primechecker/PrimeCheckerUnitTest.java rename to java-numbers/src/test/java/com/baeldung/algorithms/primechecker/PrimeCheckerUnitTest.java index 9203131397..9f8ba8defd 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/primechecker/PrimeCheckerUnitTest.java +++ b/java-numbers/src/test/java/com/baeldung/algorithms/primechecker/PrimeCheckerUnitTest.java @@ -8,16 +8,16 @@ import static org.junit.Assert.assertTrue; public class PrimeCheckerUnitTest { private final BigIntegerPrimeChecker primeChecker = new BigIntegerPrimeChecker(); - + @Test - public void whenCheckIsPrime_thenTrue(){ + public void whenCheckIsPrime_thenTrue() { assertTrue(primeChecker.isPrime(13l)); assertTrue(primeChecker.isPrime(1009L)); assertTrue(primeChecker.isPrime(74207281L)); } - + @Test - public void whenCheckIsPrime_thenFalse(){ + public void whenCheckIsPrime_thenFalse() { assertTrue(!primeChecker.isPrime(50L)); assertTrue(!primeChecker.isPrime(1001L)); assertTrue(!primeChecker.isPrime(74207282L)); @@ -26,28 +26,27 @@ public class PrimeCheckerUnitTest { private final BruteForcePrimeChecker bfPrimeChecker = new BruteForcePrimeChecker(); @Test - public void whenBFCheckIsPrime_thenTrue(){ + public void whenBFCheckIsPrime_thenTrue() { assertTrue(bfPrimeChecker.isPrime(13)); assertTrue(bfPrimeChecker.isPrime(1009)); } @Test - public void whenBFCheckIsPrime_thenFalse(){ + public void whenBFCheckIsPrime_thenFalse() { assertFalse(bfPrimeChecker.isPrime(50)); assertFalse(bfPrimeChecker.isPrime(1001)); } - private final OptimisedPrimeChecker optimisedPrimeChecker = new OptimisedPrimeChecker(); @Test - public void whenOptCheckIsPrime_thenTrue(){ + public void whenOptCheckIsPrime_thenTrue() { assertTrue(optimisedPrimeChecker.isPrime(13)); assertTrue(optimisedPrimeChecker.isPrime(1009)); } @Test - public void whenOptCheckIsPrime_thenFalse(){ + public void whenOptCheckIsPrime_thenFalse() { assertFalse(optimisedPrimeChecker.isPrime(50)); assertFalse(optimisedPrimeChecker.isPrime(1001)); } @@ -65,5 +64,5 @@ public class PrimeCheckerUnitTest { assertFalse(primesPrimeChecker.isPrime(50)); assertFalse(primesPrimeChecker.isPrime(1001)); } - + } diff --git a/java-numbers/src/test/java/com/baeldung/maths/BigDecimalDemoUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/BigDecimalDemoUnitTest.java new file mode 100644 index 0000000000..2bf9872bec --- /dev/null +++ b/java-numbers/src/test/java/com/baeldung/maths/BigDecimalDemoUnitTest.java @@ -0,0 +1,120 @@ +package com.baeldung.maths; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.MathContext; +import java.math.RoundingMode; +import java.util.Random; + +import org.junit.jupiter.api.Test; + +public class BigDecimalDemoUnitTest { + + @Test + public void whenBigDecimalCreated_thenValueMatches() { + BigDecimal bdFromString = new BigDecimal("0.1"); + BigDecimal bdFromCharArray = new BigDecimal( + new char[] { '3', '.', '1', '6', '1', '5' }); + BigDecimal bdlFromInt = new BigDecimal(42); + BigDecimal bdFromLong = new BigDecimal(123412345678901L); + BigInteger bigInteger = BigInteger.probablePrime(100, new Random()); + BigDecimal bdFromBigInteger = new BigDecimal(bigInteger); + + assertEquals("0.1", bdFromString.toString()); + assertEquals("3.1615", bdFromCharArray.toString()); + assertEquals("42", bdlFromInt.toString()); + assertEquals("123412345678901", bdFromLong.toString()); + assertEquals(bigInteger.toString(), bdFromBigInteger.toString()); + } + + @Test + public void whenBigDecimalCreatedFromDouble_thenValueMayNotMatch() { + BigDecimal bdFromDouble = new BigDecimal(0.1d); + assertNotEquals("0.1", bdFromDouble.toString()); + } + + @Test + public void whenBigDecimalCreatedUsingValueOf_thenValueMatches() { + BigDecimal bdFromLong1 = BigDecimal.valueOf(123412345678901L); + BigDecimal bdFromLong2 = BigDecimal.valueOf(123412345678901L, 2); + BigDecimal bdFromDouble = BigDecimal.valueOf(0.1d); + + assertEquals("123412345678901", bdFromLong1.toString()); + assertEquals("1234123456789.01", bdFromLong2.toString()); + assertEquals("0.1", bdFromDouble.toString()); + } + + @Test + public void whenEqualsCalled_thenSizeAndScaleMatched() { + BigDecimal bd1 = new BigDecimal("1.0"); + BigDecimal bd2 = new BigDecimal("1.00"); + + assertFalse(bd1.equals(bd2)); + } + + @Test + public void whenComparingBigDecimals_thenExpectedResult() { + BigDecimal bd1 = new BigDecimal("1.0"); + BigDecimal bd2 = new BigDecimal("1.00"); + BigDecimal bd3 = new BigDecimal("2.0"); + + assertTrue(bd1.compareTo(bd3) < 0); + assertTrue(bd3.compareTo(bd1) > 0); + assertTrue(bd1.compareTo(bd2) == 0); + assertTrue(bd1.compareTo(bd3) <= 0); + assertTrue(bd1.compareTo(bd2) >= 0); + assertTrue(bd1.compareTo(bd3) != 0); + } + + @Test + public void whenPerformingArithmetic_thenExpectedResult() { + BigDecimal bd1 = new BigDecimal("4.0"); + BigDecimal bd2 = new BigDecimal("2.0"); + + BigDecimal sum = bd1.add(bd2); + BigDecimal difference = bd1.subtract(bd2); + BigDecimal quotient = bd1.divide(bd2); + BigDecimal product = bd1.multiply(bd2); + + assertTrue(sum.compareTo(new BigDecimal("6.0")) == 0); + assertTrue(difference.compareTo(new BigDecimal("2.0")) == 0); + assertTrue(quotient.compareTo(new BigDecimal("2.0")) == 0); + assertTrue(product.compareTo(new BigDecimal("8.0")) == 0); + } + + @Test + public void whenGettingAttributes_thenExpectedResult() { + BigDecimal bd = new BigDecimal("-12345.6789"); + + assertEquals(9, bd.precision()); + assertEquals(4, bd.scale()); + assertEquals(-1, bd.signum()); + } + + @Test + public void whenRoundingDecimal_thenExpectedResult() { + BigDecimal bd = new BigDecimal("2.5"); + // Round to 1 digit using HALF_EVEN + BigDecimal rounded = bd + .round(new MathContext(1, RoundingMode.HALF_EVEN)); + + assertEquals("2", rounded.toString()); + } + + @Test + public void givenPurchaseTxn_whenCalculatingTotalAmount_thenExpectedResult() { + BigDecimal quantity = new BigDecimal("4.5"); + BigDecimal unitPrice = new BigDecimal("2.69"); + BigDecimal discountRate = new BigDecimal("0.10"); + BigDecimal taxRate = new BigDecimal("0.0725"); + + BigDecimal amountToBePaid = BigDecimalDemo + .calculateTotalAmount(quantity, unitPrice, discountRate, taxRate); + assertEquals("11.68", amountToBePaid.toString()); + } +} diff --git a/core-java/src/test/java/com/baeldung/maths/BigDecimalImplUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/BigDecimalImplUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/maths/BigDecimalImplUnitTest.java rename to java-numbers/src/test/java/com/baeldung/maths/BigDecimalImplUnitTest.java diff --git a/java-numbers/src/test/java/com/baeldung/maths/BigIntegerDemoUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/BigIntegerDemoUnitTest.java new file mode 100644 index 0000000000..3537ccb3a3 --- /dev/null +++ b/java-numbers/src/test/java/com/baeldung/maths/BigIntegerDemoUnitTest.java @@ -0,0 +1,128 @@ +package com.baeldung.maths; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigInteger; +import java.util.Random; + +import org.junit.jupiter.api.Test; + +public class BigIntegerDemoUnitTest { + + @Test + public void whenBigIntegerCreatedFromConstructor_thenExpectedResult() { + BigInteger biFromString = new BigInteger("1234567890987654321"); + BigInteger biFromByteArray = new BigInteger( + new byte[] { 64, 64, 64, 64, 64, 64 }); + BigInteger biFromSignMagnitude = new BigInteger(-1, + new byte[] { 64, 64, 64, 64, 64, 64 }); + + assertEquals("1234567890987654321", biFromString.toString()); + assertEquals("70644700037184", biFromByteArray.toString()); + assertEquals("-70644700037184", biFromSignMagnitude.toString()); + } + + @Test + public void whenLongConvertedToBigInteger_thenValueMatches() { + BigInteger bi = BigInteger.valueOf(2305843009213693951L); + + assertEquals("2305843009213693951", bi.toString()); + } + + @Test + public void givenBigIntegers_whentCompared_thenExpectedResult() { + BigInteger i = new BigInteger("123456789012345678901234567890"); + BigInteger j = new BigInteger("123456789012345678901234567891"); + BigInteger k = new BigInteger("123456789012345678901234567892"); + + assertTrue(i.compareTo(i) == 0); + assertTrue(j.compareTo(i) > 0); + assertTrue(j.compareTo(k) < 0); + } + + @Test + public void givenBigIntegers_whenPerformingArithmetic_thenExpectedResult() { + BigInteger i = new BigInteger("4"); + BigInteger j = new BigInteger("2"); + + BigInteger sum = i.add(j); + BigInteger difference = i.subtract(j); + BigInteger quotient = i.divide(j); + BigInteger product = i.multiply(j); + + assertEquals(new BigInteger("6"), sum); + assertEquals(new BigInteger("2"), difference); + assertEquals(new BigInteger("2"), quotient); + assertEquals(new BigInteger("8"), product); + } + + @Test + public void givenBigIntegers_whenPerformingBitOperations_thenExpectedResult() { + BigInteger i = new BigInteger("17"); + BigInteger j = new BigInteger("7"); + + BigInteger and = i.and(j); + BigInteger or = i.or(j); + BigInteger not = j.not(); + BigInteger xor = i.xor(j); + BigInteger andNot = i.andNot(j); + BigInteger shiftLeft = i.shiftLeft(1); + BigInteger shiftRight = i.shiftRight(1); + + assertEquals(new BigInteger("1"), and); + assertEquals(new BigInteger("23"), or); + assertEquals(new BigInteger("-8"), not); + assertEquals(new BigInteger("22"), xor); + assertEquals(new BigInteger("16"), andNot); + assertEquals(new BigInteger("34"), shiftLeft); + assertEquals(new BigInteger("8"), shiftRight); + } + + @Test + public void givenBigIntegers_whenPerformingBitManipulations_thenExpectedResult() { + BigInteger i = new BigInteger("1018"); + + int bitCount = i.bitCount(); + int bitLength = i.bitLength(); + int getLowestSetBit = i.getLowestSetBit(); + boolean testBit3 = i.testBit(3); + BigInteger setBit12 = i.setBit(12); + BigInteger flipBit0 = i.flipBit(0); + BigInteger clearBit3 = i.clearBit(3); + + assertEquals(8, bitCount); + assertEquals(10, bitLength); + assertEquals(1, getLowestSetBit); + assertEquals(true, testBit3); + assertEquals(new BigInteger("5114"), setBit12); + assertEquals(new BigInteger("1019"), flipBit0); + assertEquals(new BigInteger("1010"), clearBit3); + } + + @Test + public void givenBigIntegers_whenModularCalculation_thenExpectedResult() { + BigInteger i = new BigInteger("31"); + BigInteger j = new BigInteger("24"); + BigInteger k = new BigInteger("16"); + + BigInteger gcd = j.gcd(k); + BigInteger multiplyAndmod = j.multiply(k) + .mod(i); + BigInteger modInverse = j.modInverse(i); + BigInteger modPow = j.modPow(k, i); + + assertEquals(new BigInteger("8"), gcd); + assertEquals(new BigInteger("12"), multiplyAndmod); + assertEquals(new BigInteger("22"), modInverse); + assertEquals(new BigInteger("7"), modPow); + } + + @Test + public void givenBigIntegers_whenPrimeOperations_thenExpectedResult() { + BigInteger i = BigInteger.probablePrime(100, new Random()); + + boolean isProbablePrime = i.isProbablePrime(1000); + assertEquals(true, isProbablePrime); + } +} diff --git a/core-java/src/test/java/com/baeldung/maths/BigIntegerImplUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/BigIntegerImplUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/maths/BigIntegerImplUnitTest.java rename to java-numbers/src/test/java/com/baeldung/maths/BigIntegerImplUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/maths/FloatingPointArithmeticUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/FloatingPointArithmeticUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/maths/FloatingPointArithmeticUnitTest.java rename to java-numbers/src/test/java/com/baeldung/maths/FloatingPointArithmeticUnitTest.java diff --git a/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java new file mode 100644 index 0000000000..111b2f4465 --- /dev/null +++ b/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.maths; + +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; + +public class MathSinUnitTest { + + @Test + public void givenAnAngleInDegrees_whenUsingToRadians_thenResultIsInRadians() { + double angleInDegrees = 30; + double sinForDegrees = Math.sin(Math.toRadians(angleInDegrees)); // 0.5 + + double thirtyDegreesInRadians = 1/6 * Math.PI; + double sinForRadians = Math.sin(thirtyDegreesInRadians); // 0.5 + + assertTrue(sinForDegrees == sinForRadians); + } + +} diff --git a/core-java/src/test/java/com/baeldung/maths/RoundUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/RoundUnitTest.java similarity index 95% rename from core-java/src/test/java/com/baeldung/maths/RoundUnitTest.java rename to java-numbers/src/test/java/com/baeldung/maths/RoundUnitTest.java index f3c8e6e97a..7e3f5d6c63 100644 --- a/core-java/src/test/java/com/baeldung/maths/RoundUnitTest.java +++ b/java-numbers/src/test/java/com/baeldung/maths/RoundUnitTest.java @@ -5,9 +5,6 @@ import org.decimal4j.util.DoubleRounder; import org.junit.Assert; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - public class RoundUnitTest { private double value = 2.03456d; private int places = 2; diff --git a/core-java/src/test/java/com/baeldung/numberofdigits/NumberOfDigitsIntegrationTest.java b/java-numbers/src/test/java/com/baeldung/numberofdigits/NumberOfDigitsIntegrationTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/numberofdigits/NumberOfDigitsIntegrationTest.java rename to java-numbers/src/test/java/com/baeldung/numberofdigits/NumberOfDigitsIntegrationTest.java diff --git a/algorithms/src/test/java/com/baeldung/algorithms/pairsaddupnumber/DifferentPairsUnitTest.java b/java-numbers/src/test/java/com/baeldung/pairsaddupnumber/DifferentPairsUnitTest.java similarity index 95% rename from algorithms/src/test/java/com/baeldung/algorithms/pairsaddupnumber/DifferentPairsUnitTest.java rename to java-numbers/src/test/java/com/baeldung/pairsaddupnumber/DifferentPairsUnitTest.java index 48fcfb871c..4f7c9b5a29 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/pairsaddupnumber/DifferentPairsUnitTest.java +++ b/java-numbers/src/test/java/com/baeldung/pairsaddupnumber/DifferentPairsUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.pairsaddupnumber; +package com.baeldung.pairsaddupnumber; import org.junit.Test; diff --git a/algorithms/src/test/java/com/baeldung/algorithms/pairsaddupnumber/ExistingPairsUnitTest.java b/java-numbers/src/test/java/com/baeldung/pairsaddupnumber/ExistingPairsUnitTest.java similarity index 94% rename from algorithms/src/test/java/com/baeldung/algorithms/pairsaddupnumber/ExistingPairsUnitTest.java rename to java-numbers/src/test/java/com/baeldung/pairsaddupnumber/ExistingPairsUnitTest.java index ac6d6cc885..593db5b894 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/pairsaddupnumber/ExistingPairsUnitTest.java +++ b/java-numbers/src/test/java/com/baeldung/pairsaddupnumber/ExistingPairsUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.algorithms.pairsaddupnumber; +package com.baeldung.pairsaddupnumber; import org.junit.Test; import java.util.List; diff --git a/java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java b/java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java new file mode 100644 index 0000000000..202d4f8112 --- /dev/null +++ b/java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.percentage; + +import org.junit.Assert; +import org.junit.Test; + +public class PercentageCalculatorUnitTest { + private PercentageCalculator pc = new PercentageCalculator(); + + @Test + public void whenPass2Integers_thenShouldCalculatePercentage(){ + Assert.assertEquals("Result not as expected", + 50.0,pc.calculatePercentage(50,100),0.1); + } + + @Test + public void whenPassObtainedMarksAsDouble_thenShouldCalculatePercentage(){ + Assert.assertEquals("Result not as expected",5.05, + pc.calculatePercentage(50.5,1000),0.1); + } + + @Test + public void whenPassTotalMarksAsDouble_thenShouldCalculatePercentage(){ + Assert.assertEquals("Result not as expected",19.6, + pc.calculatePercentage(5,25.5),0.1); + } + + @Test + public void whenPass2DoubleNumbers_thenShouldCalculatePercentage(){ + Assert.assertEquals("Result not as expected",20, + pc.calculatePercentage(5.5,27.5),0.1); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/prime/PrimeGeneratorUnitTest.java b/java-numbers/src/test/java/com/baeldung/prime/PrimeGeneratorUnitTest.java similarity index 97% rename from core-java-8/src/test/java/com/baeldung/prime/PrimeGeneratorUnitTest.java rename to java-numbers/src/test/java/com/baeldung/prime/PrimeGeneratorUnitTest.java index 0e7396c9dd..210bde076b 100644 --- a/core-java-8/src/test/java/com/baeldung/prime/PrimeGeneratorUnitTest.java +++ b/java-numbers/src/test/java/com/baeldung/prime/PrimeGeneratorUnitTest.java @@ -1,10 +1,10 @@ package com.baeldung.prime; -import static com.baeldung.prime.PrimeGenerator.*; - import java.util.Arrays; import java.util.List; import org.junit.Test; + +import static com.baeldung.prime.PrimeGenerator.*; import static org.junit.Assert.*; public class PrimeGeneratorUnitTest { diff --git a/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java b/java-numbers/src/test/java/com/baeldung/random/JavaRandomUnitTest.java similarity index 99% rename from core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java rename to java-numbers/src/test/java/com/baeldung/random/JavaRandomUnitTest.java index f17531e744..2273dfda13 100644 --- a/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java +++ b/java-numbers/src/test/java/com/baeldung/random/JavaRandomUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung.java; +package com.baeldung.random; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.math3.random.RandomDataGenerator; diff --git a/java-rmi/pom.xml b/java-rmi/pom.xml index 1543e24fbd..33931baedf 100644 --- a/java-rmi/pom.xml +++ b/java-rmi/pom.xml @@ -12,8 +12,4 @@ 1.0.0-SNAPSHOT - - UTF-8 - - diff --git a/java-rmi/src/main/resources/logback.xml b/java-rmi/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-rmi/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-spi/exchange-rate-api/pom.xml b/java-spi/exchange-rate-api/pom.xml index 2de650d1af..b626916b56 100644 --- a/java-spi/exchange-rate-api/pom.xml +++ b/java-spi/exchange-rate-api/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 exchange-rate-api jar @@ -10,7 +10,4 @@ 1.0.0-SNAPSHOT - - - diff --git a/java-spi/exchange-rate-api/src/main/resources/logback.xml b/java-spi/exchange-rate-api/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-spi/exchange-rate-api/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-spi/exchange-rate-app/pom.xml b/java-spi/exchange-rate-app/pom.xml index b223cf7d95..a42a30ceda 100644 --- a/java-spi/exchange-rate-app/pom.xml +++ b/java-spi/exchange-rate-app/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 exchange-rate-app jar @@ -14,8 +14,12 @@ com.baeldung exchange-rate-api - 1.0.0-SNAPSHOT + ${exchange-rate-api.version} + + 1.0.0-SNAPSHOT + + diff --git a/java-spi/exchange-rate-app/src/main/resources/logback.xml b/java-spi/exchange-rate-app/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-spi/exchange-rate-app/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-spi/exchange-rate-impl/pom.xml b/java-spi/exchange-rate-impl/pom.xml index 435f40619e..41c874c659 100644 --- a/java-spi/exchange-rate-impl/pom.xml +++ b/java-spi/exchange-rate-impl/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 exchange-rate-impl jar @@ -10,12 +10,40 @@ 1.0.0-SNAPSHOT + + + com.baeldung + exchange-rate-api + ${exchange-rate-api.version} + + + com.squareup.okhttp3 + okhttp + ${okhttp.version} + + + javax.json.bind + javax.json.bind-api + ${javax.json.bind-api.version} + + + org.eclipse + yasson + ${yasson.version} + + + org.glassfish + javax.json + ${javax.json.version} + + + org.apache.maven.plugins maven-dependency-plugin - 3.1.0 + ${maven-dependency-plugin.version} copy-dependencies @@ -31,32 +59,14 @@ - - - com.baeldung - exchange-rate-api - 1.0.0-SNAPSHOT - - - com.squareup.okhttp3 - okhttp - 3.10.0 - - - javax.json.bind - javax.json.bind-api - 1.0 - - - org.eclipse - yasson - 1.0.1 - - - org.glassfish - javax.json - 1.1.2 - - + + + 1.0.0-SNAPSHOT + 3.10.0 + 1.0 + 1.0.1 + 1.1.2 + 3.1.0 + diff --git a/java-spi/exchange-rate-impl/src/main/resources/logback.xml b/java-spi/exchange-rate-impl/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-spi/exchange-rate-impl/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-spi/pom.xml b/java-spi/pom.xml index 4b9500ffcd..9ac87bf960 100644 --- a/java-spi/pom.xml +++ b/java-spi/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 java-spi pom diff --git a/java-streams/.gitignore b/java-streams/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/java-streams/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/java-streams/README.md b/java-streams/README.md new file mode 100644 index 0000000000..2550f08650 --- /dev/null +++ b/java-streams/README.md @@ -0,0 +1,16 @@ +========= + +## Java Streams Cookbooks and Examples + +### Relevant Articles: +- [Java 8 Streams Advanced](http://www.baeldung.com/java-8-streams) +- [Introduction to Java 8 Streams](http://www.baeldung.com/java-8-streams-introduction) +- [Java 8 and Infinite Streams](http://www.baeldung.com/java-inifinite-streams) +- [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany) +- [How to Get the Last Element of a Stream in Java?](http://www.baeldung.com/java-stream-last-element) +- [”Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception) +- [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream) +- [How to Iterate Over a Stream With Indices](http://www.baeldung.com/java-stream-indices) +- [Primitive Type Streams in Java 8](http://www.baeldung.com/java-8-primitive-streams) +- [Stream Ordering in Java](https://www.baeldung.com/java-stream-ordering) +- [Introduction to Protonpack](https://www.baeldung.com/java-protonpack) diff --git a/java-streams/pom.xml b/java-streams/pom.xml new file mode 100644 index 0000000000..e4670c268d --- /dev/null +++ b/java-streams/pom.xml @@ -0,0 +1,115 @@ + + 4.0.0 + java-streams + 0.1.0-SNAPSHOT + jar + java-streams + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + provided + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + log4j + log4j + ${log4j.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + org.assertj + assertj-core + ${assertj.version} + test + + + com.codepoetics + protonpack + ${protonpack.version} + + + io.vavr + vavr + ${vavr.version} + + + one.util + streamex + ${streamex.version} + + + org.aspectj + aspectjrt + ${asspectj.version} + + + org.aspectj + aspectjweaver + ${asspectj.version} + + + + + java-streams + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + -parameters + + + + + + + + 1.21 + 3.5 + 1.16.12 + 0.9.0 + 1.15 + 0.6.5 + 2.10 + + 3.6.1 + 1.8.9 + + diff --git a/core-java-8/src/main/java/com/baeldung/java_8_features/Detail.java b/java-streams/src/main/java/com/baeldung/java_8_features/Detail.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/java_8_features/Detail.java rename to java-streams/src/main/java/com/baeldung/java_8_features/Detail.java diff --git a/core-java-8/src/main/java/com/baeldung/stream/InfiniteStreams.java b/java-streams/src/main/java/com/baeldung/stream/InfiniteStreams.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/stream/InfiniteStreams.java rename to java-streams/src/main/java/com/baeldung/stream/InfiniteStreams.java diff --git a/core-java-8/src/main/java/com/baeldung/stream/PrimitiveStreams.java b/java-streams/src/main/java/com/baeldung/stream/PrimitiveStreams.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/stream/PrimitiveStreams.java rename to java-streams/src/main/java/com/baeldung/stream/PrimitiveStreams.java diff --git a/core-java-8/src/main/java/com/baeldung/stream/Product.java b/java-streams/src/main/java/com/baeldung/stream/Product.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/stream/Product.java rename to java-streams/src/main/java/com/baeldung/stream/Product.java diff --git a/core-java-8/src/main/java/com/baeldung/stream/StreamApi.java b/java-streams/src/main/java/com/baeldung/stream/StreamApi.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/stream/StreamApi.java rename to java-streams/src/main/java/com/baeldung/stream/StreamApi.java diff --git a/core-java-8/src/main/java/com/baeldung/stream/StreamIndices.java b/java-streams/src/main/java/com/baeldung/stream/StreamIndices.java similarity index 100% rename from core-java-8/src/main/java/com/baeldung/stream/StreamIndices.java rename to java-streams/src/main/java/com/baeldung/stream/StreamIndices.java diff --git a/java-streams/src/main/resources/logback.xml b/java-streams/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-streams/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/java/conversion/IterableStreamConversionUnitTest.java b/java-streams/src/test/java/com/baeldung/java/conversion/IterableStreamConversionUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java/conversion/IterableStreamConversionUnitTest.java rename to java-streams/src/test/java/com/baeldung/java/conversion/IterableStreamConversionUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8FindAnyFindFirstUnitTest.java b/java-streams/src/test/java/com/baeldung/java8/Java8FindAnyFindFirstUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/Java8FindAnyFindFirstUnitTest.java rename to java-streams/src/test/java/com/baeldung/java8/Java8FindAnyFindFirstUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java b/java-streams/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java rename to java-streams/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamsUnitTest.java b/java-streams/src/test/java/com/baeldung/java8/Java8StreamsUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/Java8StreamsUnitTest.java rename to java-streams/src/test/java/com/baeldung/java8/Java8StreamsUnitTest.java diff --git a/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java b/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java new file mode 100644 index 0000000000..1b64c8924a --- /dev/null +++ b/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java @@ -0,0 +1,209 @@ +package com.baeldung.protonpack; + +import com.codepoetics.protonpack.Indexed; +import com.codepoetics.protonpack.StreamUtils; +import com.codepoetics.protonpack.collectors.CollectorUtils; +import com.codepoetics.protonpack.collectors.NonUniqueValueException; +import com.codepoetics.protonpack.selectors.Selector; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.util.Arrays.asList; +import static java.util.Arrays.stream; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +@SuppressWarnings("unchecked") +public class ProtonpackUnitTest { + @Test + public void whenTakeWhile_thenTakenWhile() { + Stream streamOfInt = Stream.iterate(1, i -> i + 1); + List result = StreamUtils.takeWhile(streamOfInt, i -> i < 5).collect(Collectors.toList()); + assertThat(result).contains(1, 2, 3, 4); + } + + @Test + public void whenTakeUntil_thenTakenUntil() { + Stream streamOfInt = Stream.iterate(1, i -> i + 1); + List result = StreamUtils.takeUntil(streamOfInt, i -> i > 50).collect(Collectors.toList()); + assertThat(result).contains(10, 20, 30, 40); + } + + @Test + public void givenMultipleStream_whenZipped_thenZipped() { + String[] clubs = { "Juventus", "Barcelona", "Liverpool", "PSG" }; + String[] players = { "Ronaldo", "Messi", "Salah" }; + Set zippedFrom2Sources = StreamUtils.zip(stream(clubs), stream(players), (club, player) -> club + " " + player) + .collect(Collectors.toSet()); + assertThat(zippedFrom2Sources).contains("Juventus Ronaldo", "Barcelona Messi", "Liverpool Salah"); + + String[] leagues = { "Serie A", "La Liga", "Premier League" }; + Set zippedFrom3Sources = StreamUtils.zip(stream(clubs), stream(players), stream(leagues), + (club, player, league) -> club + " " + player + " " + league).collect(Collectors.toSet()); + assertThat(zippedFrom3Sources).contains("Juventus Ronaldo Serie A", "Barcelona Messi La Liga", + "Liverpool Salah Premier League"); + } + + @Test + public void whenZippedWithIndex_thenZippedWithIndex() { + Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool"); + Set> zipsWithIndex = StreamUtils.zipWithIndex(streamOfClubs).collect(Collectors.toSet()); + assertThat(zipsWithIndex).contains(Indexed.index(0, "Juventus"), Indexed.index(1, "Barcelona"), + Indexed.index(2, "Liverpool")); + } + + @Test + public void givenMultipleStream_whenMerged_thenMerged() { + Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool", "PSG"); + Stream streamOfPlayers = Stream.of("Ronaldo", "Messi", "Salah"); + Stream streamOfLeagues = Stream.of("Serie A", "La Liga", "Premier League"); + + Set merged = StreamUtils.merge(() -> "", (valOne, valTwo) -> valOne + " " + valTwo, streamOfClubs, + streamOfPlayers, streamOfLeagues).collect(Collectors.toSet()); + + assertThat(merged).contains(" Juventus Ronaldo Serie A", " Barcelona Messi La Liga", " Liverpool Salah Premier League", + " PSG"); + } + + @Test + public void givenMultipleStream_whenMergedToList_thenMergedToList() { + Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "PSG"); + Stream streamOfPlayers = Stream.of("Ronaldo", "Messi"); + + List> mergedListOfList = StreamUtils.mergeToList(streamOfClubs, streamOfPlayers) + .collect(Collectors.toList()); + assertThat(mergedListOfList.get(0)).isInstanceOf(List.class); + assertThat(mergedListOfList.get(0)).containsExactly("Juventus", "Ronaldo"); + assertThat(mergedListOfList.get(1)).containsExactly("Barcelona", "Messi"); + assertThat(mergedListOfList.get(2)).containsExactly("PSG"); + } + + @Test + public void givenMultipleStream_whenInterleaved_thenInterleaved() { + Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool"); + Stream streamOfPlayers = Stream.of("Ronaldo", "Messi"); + Stream streamOfLeagues = Stream.of("Serie A", "La Liga"); + + AtomicInteger counter = new AtomicInteger(0); + Selector roundRobinSelector = (o) -> { + Object[] vals = (Object[]) o; + while (counter.get() >= vals.length || vals[counter.get()] == null) { + if (counter.incrementAndGet() >= vals.length) + counter.set(0); + } + return counter.getAndIncrement(); + }; + Stream interleavedStream = StreamUtils.interleave(roundRobinSelector, streamOfClubs, streamOfPlayers, + streamOfLeagues); + List interleavedList = interleavedStream.collect(Collectors.toList()); + assertThat(interleavedList).containsExactly("Juventus", "Ronaldo", "Serie A", "Barcelona", "Messi", "La Liga", + "Liverpool"); + } + + @Test + public void whenSkippedUntil_thenSkippedUntil() { + Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + List skippedUntilGreaterThan5 = StreamUtils.skipUntil(stream(numbers), i -> i > 5).collect(Collectors.toList()); + assertThat(skippedUntilGreaterThan5).containsExactly(6, 7, 8, 9, 10); + + List skippedUntilLessThanEquals5 = StreamUtils.skipUntil(stream(numbers), i -> i <= 5) + .collect(Collectors.toList()); + assertThat(skippedUntilLessThanEquals5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void whenSkippedWhile_thenSkippedWhile() { + Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + List skippedWhileLessThanEquals5 = StreamUtils.skipWhile(stream(numbers), i -> i <= 5) + .collect(Collectors.toList()); + assertThat(skippedWhileLessThanEquals5).containsExactly(6, 7, 8, 9, 10); + + List skippedWhileGreaterThan5 = StreamUtils.skipWhile(stream(numbers), i -> i > 5).collect(Collectors.toList()); + assertThat(skippedWhileGreaterThan5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void givenFibonacciGenerator_whenUnfolded_thenUnfolded() { + AtomicInteger lastValue = new AtomicInteger(0); + Function> fibonacciGenerator = (i) -> (i < 10) ? + Optional.of(i + lastValue.getAndSet(i)) : + Optional.empty(); + + List fib = StreamUtils.unfold(1, fibonacciGenerator).collect(Collectors.toList()); + assertThat(fib).containsExactly(1, 1, 2, 3, 5, 8, 13); + } + + @Test + public void whenWindowed_thenWindowed() { + Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7 }; + + List> windowedWithSkip1 = StreamUtils.windowed(stream(numbers), 3, 1).collect(Collectors.toList()); + assertThat(windowedWithSkip1).containsExactly(asList(1, 2, 3), asList(2, 3, 4), asList(3, 4, 5), asList(4, 5, 6), + asList(5, 6, 7)); + + List> windowedWithSkip2 = StreamUtils.windowed(stream(numbers), 3, 2).collect(Collectors.toList()); + assertThat(windowedWithSkip2).containsExactly(asList(1, 2, 3), asList(3, 4, 5), asList(5, 6, 7)); + } + + @Test + public void whenAggregated_thenAggregated() { + Integer[] numbers = { 1, 2, 2, 3, 4, 4, 4, 5 }; + List> aggregated = StreamUtils.aggregate(stream(numbers), (int1, int2) -> int1.compareTo(int2) == 0) + .collect(Collectors.toList()); + assertThat(aggregated).containsExactly(asList(1), asList(2, 2), asList(3), asList(4, 4, 4), asList(5)); + + List> aggregatedFixSize = StreamUtils.aggregate(stream(numbers), 5).collect(Collectors.toList()); + assertThat(aggregatedFixSize).containsExactly(asList(1, 2, 2, 3, 4), asList(4, 4, 5)); + } + + @Test + public void whenGroupedRun_thenGroupedRun() { + Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 }; + List> grouped = StreamUtils.groupRuns(stream(numbers)).collect(Collectors.toList()); + assertThat(grouped).containsExactly(asList(1, 1), asList(2), asList(3), asList(4, 4), asList(5)); + + Integer[] numbers2 = { 1, 2, 3, 1 }; + List> grouped2 = StreamUtils.groupRuns(stream(numbers2)).collect(Collectors.toList()); + assertThat(grouped2).containsExactly(asList(1), asList(2), asList(3), asList(1)); + } + + @Test + public void whenAggregatedOnListCondition_thenAggregatedOnListCondition() { + Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 }; + Stream> aggregated = StreamUtils.aggregateOnListCondition(stream(numbers), + (currentList, nextInt) -> currentList.stream().mapToInt(Integer::intValue).sum() + nextInt <= 5); + assertThat(aggregated).containsExactly(asList(1, 1, 2), asList(3), asList(4), asList(4), asList(5)); + } + + @Test + public void givenProjectionFunction_whenMaxedBy_thenMaxedBy() { + Stream clubs = Stream.of("Juventus", "Barcelona", "PSG"); + Optional longestName = clubs.collect(CollectorUtils.maxBy(String::length)); + assertThat(longestName.get()).isEqualTo("Barcelona"); + } + + @Test + public void givenStreamOfMultipleElem_whenUniqueCollector_thenValueReturned() { + Stream singleElement = Stream.of(1); + Optional unique = singleElement.collect(CollectorUtils.unique()); + assertThat(unique.get()).isEqualTo(1); + + } + + @Test + public void givenStreamOfMultipleElem_whenUniqueCollector_thenExceptionThrown() { + Stream multipleElement = Stream.of(1, 2, 3); + assertThatExceptionOfType(NonUniqueValueException.class).isThrownBy(() -> { + multipleElement.collect(CollectorUtils.unique()); + }); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/stream/InfiniteStreamUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/InfiniteStreamUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/stream/InfiniteStreamUnitTest.java rename to java-streams/src/test/java/com/baeldung/stream/InfiniteStreamUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java similarity index 87% rename from core-java-8/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java rename to java-streams/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java index 2c88dc5ec7..67954f0bba 100644 --- a/core-java-8/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java +++ b/java-streams/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java @@ -1,15 +1,14 @@ package com.baeldung.stream; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.junit.Test; public class PrimitiveStreamsUnitTest { @@ -17,7 +16,7 @@ public class PrimitiveStreamsUnitTest { @Test public void givenAnArrayOfIntegersWhenMinIsCalledThenCorrectMinIsReturned() { - int[] integers = new int[] {20, 98, 12, 7, 35}; + int[] integers = new int[] { 20, 98, 12, 7, 35 }; int min = streams.min(integers); // returns 7 assertEquals(7, min); @@ -66,19 +65,14 @@ public class PrimitiveStreamsUnitTest { @Test public void givenAnArrayWhenSumIsCalledThenTheCorrectSumIsReturned() { - int sum = Stream.of(33,45) - .mapToInt(i -> i) - .sum(); + int sum = Stream.of(33, 45).mapToInt(i -> i).sum(); assertEquals(78, sum); } @Test public void givenAnIntStreamThenGetTheEvenIntegers() { - List evenInts = IntStream.rangeClosed(1, 10) - .filter(i -> i % 2 == 0) - .boxed() - .collect(Collectors.toList()); + List evenInts = IntStream.rangeClosed(1, 10).filter(i -> i % 2 == 0).boxed().collect(Collectors.toList()); List expected = IntStream.of(2, 4, 6, 8, 10).boxed().collect(Collectors.toList()); diff --git a/core-java-8/src/test/java/com/baeldung/stream/StreamAddUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamAddUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/stream/StreamAddUnitTest.java rename to java-streams/src/test/java/com/baeldung/stream/StreamAddUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/stream/StreamApiUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamApiUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/stream/StreamApiUnitTest.java rename to java-streams/src/test/java/com/baeldung/stream/StreamApiUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/stream/StreamIndicesUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamIndicesUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/stream/StreamIndicesUnitTest.java rename to java-streams/src/test/java/com/baeldung/stream/StreamIndicesUnitTest.java diff --git a/java-streams/src/test/java/com/baeldung/stream/StreamOperateAndRemoveUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamOperateAndRemoveUnitTest.java new file mode 100644 index 0000000000..c5aa9a1651 --- /dev/null +++ b/java-streams/src/test/java/com/baeldung/stream/StreamOperateAndRemoveUnitTest.java @@ -0,0 +1,80 @@ +package com.baeldung.stream; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StreamOperateAndRemoveUnitTest { + + private List itemList; + + @Before + public void setup() { + + itemList = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + itemList.add(new Item(i)); + } + } + + @Test + public void givenAListOf10Items_whenFilteredForQualifiedItems_thenFilteredListContains5Items() { + + final List filteredList = itemList.stream().filter(item -> item.isQualified()) + .collect(Collectors.toList()); + + Assert.assertEquals(5, filteredList.size()); + } + + @Test + public void givenAListOf10Items_whenOperateAndRemoveQualifiedItemsUsingRemoveIf_thenListContains5Items() { + + final Predicate isQualified = item -> item.isQualified(); + itemList.stream().filter(isQualified).forEach(item -> item.operate()); + itemList.removeIf(isQualified); + + Assert.assertEquals(5, itemList.size()); + } + + @Test + public void givenAListOf10Items_whenOperateAndRemoveQualifiedItemsUsingRemoveAll_thenListContains5Items() { + + final List operatedList = new ArrayList<>(); + itemList.stream().filter(item -> item.isQualified()).forEach(item -> { + item.operate(); + operatedList.add(item); + }); + itemList.removeAll(operatedList); + + Assert.assertEquals(5, itemList.size()); + } + + class Item { + + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + private final int value; + + public Item(final int value) { + + this.value = value; + } + + public boolean isQualified() { + + return value % 2 == 0; + } + + public void operate() { + + logger.info("Even Number: " + this.value); + } + } +} \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/stream/StreamToImmutableUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamToImmutableUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/stream/StreamToImmutableUnitTest.java rename to java-streams/src/test/java/com/baeldung/stream/StreamToImmutableUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/stream/SupplierStreamUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/SupplierStreamUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/stream/SupplierStreamUnitTest.java rename to java-streams/src/test/java/com/baeldung/stream/SupplierStreamUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/stream/mycollectors/MyImmutableListCollector.java b/java-streams/src/test/java/com/baeldung/stream/mycollectors/MyImmutableListCollector.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/stream/mycollectors/MyImmutableListCollector.java rename to java-streams/src/test/java/com/baeldung/stream/mycollectors/MyImmutableListCollector.java diff --git a/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java new file mode 100644 index 0000000000..656a6d95f9 --- /dev/null +++ b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java @@ -0,0 +1,96 @@ +package com.baeldung.streamordering; + +import org.junit.Test; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; + + +public class BenchmarkManualTest +{ + + public void + launchBenchmark() throws Exception { + + Options opt = new OptionsBuilder() + // Specify which benchmarks to run. + // You can be more specific if you'd like to run only one benchmark per test. + .include(this.getClass().getName() + ".*") + // Set the following options as needed + .mode (Mode.AverageTime) + .timeUnit(TimeUnit.MICROSECONDS) + .warmupTime(TimeValue.seconds(1)) + .warmupIterations(2) + .measurementTime(TimeValue.seconds(1)) + .measurementIterations(2) + .threads(2) + .forks(1) + .shouldFailOnError(true) + .shouldDoGC(true) + //.jvmArgs("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining") + //.addProfiler(WinPerfAsmProfiler.class) + .build(); + + new Runner(opt).run(); + + + } + + @Benchmark + public void givenOrderedStreamInput_whenStreamFiltered_showOpsPerMS(){ + IntStream.range(1, 100_000_000).parallel().filter(i -> i % 10 == 0).toArray(); + } + + @Benchmark + public void givenUnorderedStreamInput_whenStreamFiltered_showOpsPerMS(){ + IntStream.range(1,100_000_000).unordered().parallel().filter(i -> i % 10 == 0).toArray(); + } + + @Benchmark + public void givenUnorderedStreamInput_whenStreamDistinct_showOpsPerMS(){ + IntStream.range(1, 1_000_000).unordered().parallel().distinct().toArray(); + } + + @Benchmark + public void givenOrderedStreamInput_whenStreamDistinct_showOpsPerMS() { + //section 5.1. + IntStream.range(1, 1_000_000).parallel().distinct().toArray(); + } + + + // The JMH samples are the best documentation for how to use it + // http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/ + @State(Scope.Thread) + public static class BenchmarkState + { + List list; + + @Setup(Level.Trial) public void + initialize() { + + Random rand = new Random(); + + list = new ArrayList<>(); + for (int i = 0; i < 1000; i++) + list.add (rand.nextInt()); + } + } + + @Benchmark public void + benchmark1 (BenchmarkState state, Blackhole bh) { + + List list = state.list; + + for (int i = 0; i < 1000; i++) + bh.consume (list.get (i)); + } +} diff --git a/java-streams/src/test/java/com/baeldung/streamordering/StreamsOrderingUnitTest.java b/java-streams/src/test/java/com/baeldung/streamordering/StreamsOrderingUnitTest.java new file mode 100644 index 0000000000..43a233d353 --- /dev/null +++ b/java-streams/src/test/java/com/baeldung/streamordering/StreamsOrderingUnitTest.java @@ -0,0 +1,149 @@ +package com.baeldung.streamordering; + +import org.junit.Before; +import org.junit.Test; + +import java.util.*; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.junit.Assert.assertEquals; + +public class StreamsOrderingUnitTest { + + Logger logger = Logger.getLogger( StreamsOrderingUnitTest.class.getName()); + + @Before + public void setUp() throws Exception { + logger.setLevel(Level.ALL); + } + + @Test + public void givenTwoCollections_whenStreamed_thenCheckOutputDifferent(){ + + List list = Arrays.asList("B", "A", "C", "D", "F"); + Set set = new TreeSet<>(Arrays.asList("B", "A", "C", "D", "F")); + + Object[] listOutput = list.stream().toArray(); + Object[] setOutput = set.stream().toArray(); + + assertEquals("[B, A, C, D, F]", Arrays.toString(listOutput)); + assertEquals("[A, B, C, D, F]", Arrays.toString(setOutput)); + + } + + @Test + public void givenTwoCollections_whenStreamedInParallel_thenCheckOutputDifferent(){ + + List list = Arrays.asList("B", "A", "C", "D", "F"); + Set set = new TreeSet<>(Arrays.asList("B", "A", "C", "D", "F")); + + Object[] listOutput = list.stream().parallel().toArray(); + Object[] setOutput = set.stream().parallel().toArray(); + + assertEquals("[B, A, C, D, F]", Arrays.toString(listOutput)); + assertEquals("[A, B, C, D, F]", Arrays.toString(setOutput)); + + } + + + + @Test + public void givenOrderedInput_whenUnorderedAndOrderedCompared_thenCheckUnorderedOutputChanges(){ + Set set = new TreeSet<>( + Arrays.asList(-9, -5, -4, -2, 1, 2, 4, 5, 7, 9, 12, 13, 16, 29, 23, 34, 57, 68, 90, 102, 230)); + + Object[] orderedArray = set.stream() + .parallel() + .limit(5) + .toArray(); + Object[] unorderedArray = set.stream() + .unordered() + .parallel() + .limit(5) + .toArray(); + + logger.info(Arrays.toString(orderedArray)); + logger.info(Arrays.toString(unorderedArray)); + } + + + @Test + public void givenUnsortedStreamInput_whenStreamSorted_thenCheckOrderChanged(){ + + List list = Arrays.asList(-3,10,-4,1,3); + + Object[] listOutput = list.stream().toArray(); + Object[] listOutputSorted = list.stream().sorted().toArray(); + + assertEquals("[-3, 10, -4, 1, 3]", Arrays.toString(listOutput)); + assertEquals("[-4, -3, 1, 3, 10]", Arrays.toString(listOutputSorted)); + + } + + @Test + public void givenUnsortedStreamInput_whenStreamDistinct_thenShowTimeTaken(){ + long start, end; + start = System.currentTimeMillis(); + IntStream.range(1,1_000_000).unordered().parallel().distinct().toArray(); + end = System.currentTimeMillis(); + System.out.println(String.format("Time taken when unordered: %d ms", (end - start))); + } + + + @Test + public void givenSameCollection_whenStreamTerminated_thenCheckEachVsEachOrdered(){ + + List list = Arrays.asList("B", "A", "C", "D", "F"); + + list.stream().parallel().forEach(e -> logger.log(Level.INFO, e)); + list.stream().parallel().forEachOrdered(e -> logger.log(Level.INFO, e)); + + } + + @Test + public void givenSameCollection_whenStreamCollected_thenCheckOutput(){ + + List list = Arrays.asList("B", "A", "C", "D", "F"); + + List collectionList = list.stream().parallel().collect(Collectors.toList()); + Set collectionSet = list.stream().parallel().collect(Collectors.toCollection(TreeSet::new)); + + assertEquals("[B, A, C, D, F]", collectionList.toString()); + assertEquals("[A, B, C, D, F]", collectionSet.toString()); + + } + + + @Test + public void givenListIterationOrder_whenStreamCollectedToMap_thenCeckOrderChanged() { + List list = Arrays.asList("A", "BB", "CCC"); + + Map hashMap = list.stream().collect(Collectors.toMap(Function.identity(), String::length)); + + Object[] keySet = hashMap.keySet().toArray(); + + assertEquals("[BB, A, CCC]", Arrays.toString(keySet)); + + } + + @Test + public void givenListIteration_whenStreamCollectedtoHashMap_thenCheckOrderMaintained() { + List list = Arrays.asList("A", "BB", "CCC", "CCC"); + + Map linkedHashMap = list.stream().collect(Collectors.toMap( + Function.identity(), + String::length, + (u, v) -> u, + LinkedHashMap::new + )); + + Object[] keySet = linkedHashMap.keySet().toArray(); + + assertEquals("[A, BB, CCC]", Arrays.toString(keySet)); + } + +} diff --git a/java-streams/src/test/resources/.gitignore b/java-streams/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/java-streams/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/java-strings/README.md b/java-strings/README.md new file mode 100644 index 0000000000..ff833a5cda --- /dev/null +++ b/java-strings/README.md @@ -0,0 +1,35 @@ +========= + +## Java Strings Cookbooks and Examples + +### Relevant Articles: +- [String Operations with Java Streams](http://www.baeldung.com/java-stream-operations-on-strings) +- [Converting String to Stream of chars](http://www.baeldung.com/java-string-to-stream) +- [Java 8 StringJoiner](http://www.baeldung.com/java-string-joiner) +- [Image to Base64 String Conversion](http://www.baeldung.com/java-base64-image-string) +- [Java – Generate Random String](http://www.baeldung.com/java-random-string) +- [Convert char to String in Java](http://www.baeldung.com/java-convert-char-to-string) +- [Convert String to int or Integer in Java](http://www.baeldung.com/java-convert-string-to-int-or-integer) +- [How to Convert String to different data types in Java](http://www.baeldung.com/java-string-conversions) +- [Converting Strings to Enums in Java](http://www.baeldung.com/java-string-to-enum) +- [Quick Guide to the Java StringTokenizer](http://www.baeldung.com/java-stringtokenizer) +- [Count Occurrences of a Char in a String](http://www.baeldung.com/java-count-chars) +- [Split a String in Java](http://www.baeldung.com/java-split-string) +- [How to Remove the Last Character of a String?](http://www.baeldung.com/java-remove-last-character-of-string) +- [CharSequence vs. String in Java](http://www.baeldung.com/java-char-sequence-string) +- [StringBuilder and StringBuffer in Java](http://www.baeldung.com/java-string-builder-string-buffer) +- [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) +- [Check if a String is a Palindrome](http://www.baeldung.com/java-palindrome) +- [Comparing Strings in Java](http://www.baeldung.com/java-compare-strings) +- [Check If a String Is Numeric in Java](http://www.baeldung.com/java-check-string-number) +- [Why Use char[] Array Over a String for Storing Passwords in Java?](http://www.baeldung.com/java-storing-passwords) +- [Convert a String to Title Case](http://www.baeldung.com/java-string-title-case) +- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string) +- [Java Check a String for Lowercase/Uppercase Letter, Special Character and Digit](https://www.baeldung.com/java-lowercase-uppercase-special-character-digit-regex) +- [Convert java.util.Date to String](https://www.baeldung.com/java-util-date-to-string) +- [Get Substring from String in Java](https://www.baeldung.com/java-substring) +- [Converting a Stack Trace to a String in Java](https://www.baeldung.com/java-stacktrace-to-string) +- [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically) +- [Remove Emojis from a Java String](https://www.baeldung.com/java-string-remove-emojis) +- [String Not Empty Test Assertions in Java](https://www.baeldung.com/java-assert-string-not-empty) +- [String Performance Hints](https://www.baeldung.com/java-string-performance) diff --git a/java-strings/pom.xml b/java-strings/pom.xml new file mode 100644 index 0000000000..b1ba49b33a --- /dev/null +++ b/java-strings/pom.xml @@ -0,0 +1,108 @@ + + 4.0.0 + com.baeldung + java-strings + 0.1.0-SNAPSHOT + jar + java-strings + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + commons-io + commons-io + ${commons-io.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + log4j + log4j + ${log4j.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.openjdk.jmh + jmh-core + ${jmh-core.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-core.version} + + + com.ibm.icu + icu4j + ${icu4j.version} + + + com.google.guava + guava + ${guava.version} + + + + com.vdurmont + emoji-java + 4.0.0 + + + + + + java-strings + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + -parameters + + + + + + + + 3.5 + 1.10 + + 3.6.1 + 1.19 + 61.1 + 26.0-jre + + + \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/datetime/UseLocalDateTime.java b/java-strings/src/main/java/com/baeldung/datetime/UseLocalDateTime.java similarity index 100% rename from core-java/src/main/java/com/baeldung/datetime/UseLocalDateTime.java rename to java-strings/src/main/java/com/baeldung/datetime/UseLocalDateTime.java diff --git a/java-strings/src/main/java/com/baeldung/enums/PizzaStatusEnum.java b/java-strings/src/main/java/com/baeldung/enums/PizzaStatusEnum.java new file mode 100644 index 0000000000..a84829c38d --- /dev/null +++ b/java-strings/src/main/java/com/baeldung/enums/PizzaStatusEnum.java @@ -0,0 +1,44 @@ +package com.baeldung.enums; + +public enum PizzaStatusEnum { + ORDERED(5) { + @Override + public boolean isOrdered() { + return true; + } + }, + READY(2) { + @Override + public boolean isReady() { + return true; + } + }, + DELIVERED(0) { + @Override + public boolean isDelivered() { + return true; + } + }; + + private int timeToDelivery; + + public boolean isOrdered() { + return false; + } + + public boolean isReady() { + return false; + } + + public boolean isDelivered() { + return false; + } + + public int getTimeToDelivery() { + return timeToDelivery; + } + + PizzaStatusEnum(int timeToDelivery) { + this.timeToDelivery = timeToDelivery; + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java b/java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java similarity index 100% rename from core-java-9/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java rename to java-strings/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java diff --git a/core-java-8/src/main/java/com/baeldung/string/JoinerSplitter.java b/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java similarity index 76% rename from core-java-8/src/main/java/com/baeldung/string/JoinerSplitter.java rename to java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java index 085be66801..cdbba1ef53 100644 --- a/core-java-8/src/main/java/com/baeldung/string/JoinerSplitter.java +++ b/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java @@ -2,6 +2,7 @@ package com.baeldung.string; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -32,5 +33,12 @@ public class JoinerSplitter { .mapToObj(item -> (char) item) .collect(Collectors.toList()); } + + public static Map arrayToMap(String[] arrayOfString) { + return Arrays.asList(arrayOfString) + .stream() + .map(str -> str.split(":")) + .collect(Collectors.toMap(str -> str[0], str -> str[1])); + } } diff --git a/core-java/src/main/java/com/baeldung/string/Palindrome.java b/java-strings/src/main/java/com/baeldung/string/Palindrome.java similarity index 100% rename from core-java/src/main/java/com/baeldung/string/Palindrome.java rename to java-strings/src/main/java/com/baeldung/string/Palindrome.java diff --git a/core-java/src/main/java/com/baeldung/string/StringBufferStringBuilder.java b/java-strings/src/main/java/com/baeldung/string/StringBufferStringBuilder.java similarity index 96% rename from core-java/src/main/java/com/baeldung/string/StringBufferStringBuilder.java rename to java-strings/src/main/java/com/baeldung/string/StringBufferStringBuilder.java index 74f489d57f..72af4a9aee 100644 --- a/core-java/src/main/java/com/baeldung/string/StringBufferStringBuilder.java +++ b/java-strings/src/main/java/com/baeldung/string/StringBufferStringBuilder.java @@ -1,46 +1,46 @@ -package com.baeldung.string; - -import org.openjdk.jmh.annotations.Benchmark; -import org.openjdk.jmh.annotations.Scope; -import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.RunnerException; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; - -public class StringBufferStringBuilder { - - public static void main(String[] args) throws RunnerException { - - Options opt = new OptionsBuilder() - .include(StringBufferStringBuilder.class.getSimpleName()) - .build(); - - new Runner(opt).run(); - } - - @State(Scope.Benchmark) - public static class MyState { - int iterations = 1000; - String initial = "abc"; - String suffix = "def"; - } - - @Benchmark - public StringBuffer benchmarkStringBuffer(MyState state) { - StringBuffer stringBuffer = new StringBuffer(state.initial); - for (int i = 0; i < state.iterations; i++) { - stringBuffer.append(state.suffix); - } - return stringBuffer; - } - - @Benchmark - public StringBuilder benchmarkStringBuilder(MyState state) { - StringBuilder stringBuilder = new StringBuilder(state.initial); - for (int i = 0; i < state.iterations; i++) { - stringBuilder.append(state.suffix); - } - return stringBuilder; - } +package com.baeldung.string; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +public class StringBufferStringBuilder { + + public static void main(String[] args) throws RunnerException { + + Options opt = new OptionsBuilder() + .include(StringBufferStringBuilder.class.getSimpleName()) + .build(); + + new Runner(opt).run(); + } + + @State(Scope.Benchmark) + public static class MyState { + int iterations = 1000; + String initial = "abc"; + String suffix = "def"; + } + + @Benchmark + public StringBuffer benchmarkStringBuffer(MyState state) { + StringBuffer stringBuffer = new StringBuffer(state.initial); + for (int i = 0; i < state.iterations; i++) { + stringBuffer.append(state.suffix); + } + return stringBuffer; + } + + @Benchmark + public StringBuilder benchmarkStringBuilder(MyState state) { + StringBuilder stringBuilder = new StringBuilder(state.initial); + for (int i = 0; i < state.iterations; i++) { + stringBuilder.append(state.suffix); + } + return stringBuilder; + } } \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/string/StringHelper.java b/java-strings/src/main/java/com/baeldung/string/StringHelper.java similarity index 100% rename from core-java/src/main/java/com/baeldung/string/StringHelper.java rename to java-strings/src/main/java/com/baeldung/string/StringHelper.java diff --git a/java-strings/src/main/java/com/baeldung/string/StringPerformance.java b/java-strings/src/main/java/com/baeldung/string/StringPerformance.java new file mode 100644 index 0000000000..3b0c32991c --- /dev/null +++ b/java-strings/src/main/java/com/baeldung/string/StringPerformance.java @@ -0,0 +1,196 @@ +package com.baeldung.string; + +import com.google.common.base.Splitter; +import org.apache.commons.lang3.StringUtils; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; +import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; + +@BenchmarkMode(Mode.SingleShotTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Measurement(batchSize = 100000, iterations = 10) +@Warmup(batchSize = 100000, iterations = 10) +@State(Scope.Thread) +public class StringPerformance { + + protected String baeldung = "baeldung"; + protected String longString = "Hello baeldung, I am a bit longer than other Strings"; + protected String formatString = "hello %s, nice to meet you"; + protected String formatDigit = "%d"; + protected String emptyString = " "; + protected String result = ""; + + protected int sampleNumber = 100; + + protected Pattern spacePattern = Pattern.compile(emptyString); + protected Pattern longPattern = Pattern.compile(longString); + protected List stringSplit = new ArrayList<>(); + protected List stringTokenizer = new ArrayList<>(); + + @Benchmark + public String benchmarkStringDynamicConcat() { + result += baeldung; + return result; + } + + @Benchmark + public StringBuilder benchmarkStringBuilder() { + StringBuilder stringBuilder = new StringBuilder(result); + stringBuilder.append(baeldung); + return stringBuilder; + } + + @Benchmark + public StringBuffer benchmarkStringBuffer() { + StringBuffer stringBuffer = new StringBuffer(result); + stringBuffer.append(baeldung); + return stringBuffer; + } + + @Benchmark + public String benchmarkStringConstructor() { + String result = new String("baeldung"); + return result; + } + + @Benchmark + public String benchmarkStringLiteral() { + String result = "baeldung"; + return result; + } + + @Benchmark + public String benchmarkStringFormat_s() { + return String.format(formatString, baeldung); + } + + @Benchmark + public String benchmarkStringConcat() { + result = result.concat(baeldung); + return result; + } + + @Benchmark + public String benchmarkStringIntern() { + return baeldung.intern(); + } + + @Benchmark + public String benchmarkStringReplace() { + return longString.replace("average", " average !!!"); + } + + @Benchmark + public String benchmarkStringUtilsReplace() { + return StringUtils.replace(longString, "average", " average !!!"); + } + + @Benchmark + public List benchmarkGuavaSplitter() { + return Splitter.on(" ").trimResults() + .omitEmptyStrings() + .splitToList(longString); + } + + @Benchmark + public String [] benchmarkStringSplit() { + return longString.split(emptyString); + } + + @Benchmark + public String [] benchmarkStringSplitPattern() { + return spacePattern.split(longString, 0); + } + + @Benchmark + public List benchmarkStringTokenizer() { + StringTokenizer st = new StringTokenizer(longString); + while (st.hasMoreTokens()) { + stringTokenizer.add(st.nextToken()); + } + return stringTokenizer; + } + + @Benchmark + public List benchmarkStringIndexOf() { + int pos = 0, end; + while ((end = longString.indexOf(' ', pos)) >= 0) { + stringSplit.add(longString.substring(pos, end)); + pos = end + 1; + } + return stringSplit; + } + + @Benchmark + public String benchmarkIntegerToString() { + return Integer.toString(sampleNumber); + } + + @Benchmark + public String benchmarkStringValueOf() { + return String.valueOf(sampleNumber); + } + + + @Benchmark + public String benchmarkStringConvertPlus() { + return sampleNumber + ""; + } + + @Benchmark + public String benchmarkStringFormat_d() { + return String.format(formatDigit, sampleNumber); + } + + @Benchmark + public boolean benchmarkStringEquals() { + return longString.equals(baeldung); + } + + + @Benchmark + public boolean benchmarkStringEqualsIgnoreCase() { + return longString.equalsIgnoreCase(baeldung); + } + + @Benchmark + public boolean benchmarkStringMatches() { + return longString.matches(baeldung); + } + + @Benchmark + public boolean benchmarkPrecompiledMatches() { + return longPattern.matcher(baeldung).matches(); + } + + @Benchmark + public int benchmarkStringCompareTo() { + return longString.compareTo(baeldung); + } + + @Benchmark + public boolean benchmarkStringIsEmpty() { + return longString.isEmpty(); + } + + @Benchmark + public boolean benchmarkStringLengthZero() { + return longString.length() == 0; + } + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(StringPerformance.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } +} diff --git a/core-java/src/main/java/com/baeldung/string/TitleCaseConverter.java b/java-strings/src/main/java/com/baeldung/string/TitleCaseConverter.java similarity index 97% rename from core-java/src/main/java/com/baeldung/string/TitleCaseConverter.java rename to java-strings/src/main/java/com/baeldung/string/TitleCaseConverter.java index 0fdda86f2a..81043f6dac 100644 --- a/core-java/src/main/java/com/baeldung/string/TitleCaseConverter.java +++ b/java-strings/src/main/java/com/baeldung/string/TitleCaseConverter.java @@ -1,12 +1,13 @@ package com.baeldung.string; -import com.ibm.icu.lang.UCharacter; -import com.ibm.icu.text.BreakIterator; -import org.apache.commons.lang.WordUtils; - import java.util.Arrays; import java.util.stream.Collectors; +import org.apache.commons.lang3.text.WordUtils; + +import com.ibm.icu.lang.UCharacter; +import com.ibm.icu.text.BreakIterator; + public class TitleCaseConverter { private static final String WORD_SEPARATOR = " "; diff --git a/java-strings/src/main/java/com/baeldung/string/sorting/AnagramValidator.java b/java-strings/src/main/java/com/baeldung/string/sorting/AnagramValidator.java new file mode 100644 index 0000000000..c4f684383d --- /dev/null +++ b/java-strings/src/main/java/com/baeldung/string/sorting/AnagramValidator.java @@ -0,0 +1,29 @@ +package com.baeldung.string.sorting; + +import java.util.Arrays; + +public class AnagramValidator { + + public static boolean isValid(String text, String anagram) { + text = prepare(text); + anagram = prepare(anagram); + + String sortedText = sort(text); + String sortedAnagram = sort(anagram); + + return sortedText.equals(sortedAnagram); + } + + private static String sort(String text) { + char[] chars = prepare(text).toCharArray(); + + Arrays.sort(chars); + return new String(chars); + } + + private static String prepare(String text) { + return text.toLowerCase() + .trim() + .replaceAll("\\s+", ""); + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/stringisnumeric/Benchmarking.java b/java-strings/src/main/java/com/baeldung/stringisnumeric/Benchmarking.java similarity index 100% rename from core-java/src/main/java/com/baeldung/stringisnumeric/Benchmarking.java rename to java-strings/src/main/java/com/baeldung/stringisnumeric/Benchmarking.java diff --git a/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumeric.java b/java-strings/src/main/java/com/baeldung/stringisnumeric/IsNumeric.java similarity index 100% rename from core-java/src/main/java/com/baeldung/stringisnumeric/IsNumeric.java rename to java-strings/src/main/java/com/baeldung/stringisnumeric/IsNumeric.java diff --git a/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java b/java-strings/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java similarity index 100% rename from core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java rename to java-strings/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java diff --git a/core-java/src/main/java/com/baeldung/stringtokenizer/MyTokenizer.java b/java-strings/src/main/java/com/baeldung/stringtokenizer/MyTokenizer.java similarity index 100% rename from core-java/src/main/java/com/baeldung/stringtokenizer/MyTokenizer.java rename to java-strings/src/main/java/com/baeldung/stringtokenizer/MyTokenizer.java diff --git a/core-java/src/main/resources/data.csv b/java-strings/src/main/resources/data.csv similarity index 100% rename from core-java/src/main/resources/data.csv rename to java-strings/src/main/resources/data.csv diff --git a/java-strings/src/main/resources/logback.xml b/java-strings/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-strings/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/CharArrayToStringUnitTest.java b/java-strings/src/test/java/com/baeldung/CharArrayToStringUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/CharArrayToStringUnitTest.java rename to java-strings/src/test/java/com/baeldung/CharArrayToStringUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/CharToStringUnitTest.java b/java-strings/src/test/java/com/baeldung/CharToStringUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/CharToStringUnitTest.java rename to java-strings/src/test/java/com/baeldung/CharToStringUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/StringToCharArrayUnitTest.java b/java-strings/src/test/java/com/baeldung/StringToCharArrayUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/StringToCharArrayUnitTest.java rename to java-strings/src/test/java/com/baeldung/StringToCharArrayUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/StringToIntOrIntegerUnitTest.java b/java-strings/src/test/java/com/baeldung/StringToIntOrIntegerUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/StringToIntOrIntegerUnitTest.java rename to java-strings/src/test/java/com/baeldung/StringToIntOrIntegerUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/chararraypassword/PasswordStoreExamplesUnitTest.java b/java-strings/src/test/java/com/baeldung/chararraypassword/PasswordStoreExamplesUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/chararraypassword/PasswordStoreExamplesUnitTest.java rename to java-strings/src/test/java/com/baeldung/chararraypassword/PasswordStoreExamplesUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/enums/PizzaUnitTest.java b/java-strings/src/test/java/com/baeldung/enums/PizzaUnitTest.java new file mode 100644 index 0000000000..3e52a89bad --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/enums/PizzaUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.enums; + +import static junit.framework.TestCase.assertTrue; + +import org.junit.Test; + +public class PizzaUnitTest { + + @Test + public void whenConvertedIntoEnum_thenGetsConvertedCorrectly() { + String pizzaEnumValue = "READY"; + PizzaStatusEnum pizzaStatusEnum = PizzaStatusEnum.valueOf(pizzaEnumValue); + assertTrue(pizzaStatusEnum == PizzaStatusEnum.READY); + } + + @Test(expected = IllegalArgumentException.class) + public void whenConvertedIntoEnum_thenThrowsException() { + String pizzaEnumValue = "rEAdY"; + PizzaStatusEnum pizzaStatusEnum = PizzaStatusEnum.valueOf(pizzaEnumValue); + } + + @Test(expected = IllegalArgumentException.class) + public void givenInvalidEnumValueContentWiseAsString_whenConvertedIntoEnum_thenThrowsException() { + String pizzaEnumValue = "invalid"; + PizzaStatusEnum pizzaStatusEnum = PizzaStatusEnum.valueOf(pizzaEnumValue); + } +} \ No newline at end of file diff --git a/java-strings/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java b/java-strings/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java new file mode 100644 index 0000000000..eef21a98c9 --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/fileToBase64StringConversion/FileToBase64StringConversionUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.fileToBase64StringConversion; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Base64; + +import org.apache.commons.io.FileUtils; +import org.junit.Test; + +public class FileToBase64StringConversionUnitTest { + + private String inputFilePath = "test_image.jpg"; + private String outputFilePath = "test_image_copy.jpg"; + + @Test + public void fileToBase64StringConversion() throws IOException { + //load file from /src/test/resources + ClassLoader classLoader = getClass().getClassLoader(); + File inputFile = new File(classLoader + .getResource(inputFilePath) + .getFile()); + + byte[] fileContent = FileUtils.readFileToByteArray(inputFile); + String encodedString = Base64 + .getEncoder() + .encodeToString(fileContent); + + //create output file + File outputFile = new File(inputFile + .getParentFile() + .getAbsolutePath() + File.pathSeparator + outputFilePath); + + // decode the string and write to file + byte[] decodedBytes = Base64 + .getDecoder() + .decode(encodedString); + FileUtils.writeByteArrayToFile(outputFile, decodedBytes); + + assertTrue(FileUtils.contentEquals(inputFile, outputFile)); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/conversion/README.md b/java-strings/src/test/java/com/baeldung/java/conversion/README.md similarity index 100% rename from core-java/src/test/java/com/baeldung/java/conversion/README.md rename to java-strings/src/test/java/com/baeldung/java/conversion/README.md diff --git a/core-java/src/test/java/com/baeldung/java/conversion/StringConversionUnitTest.java b/java-strings/src/test/java/com/baeldung/java/conversion/StringConversionUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/java/conversion/StringConversionUnitTest.java rename to java-strings/src/test/java/com/baeldung/java/conversion/StringConversionUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java b/java-strings/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java similarity index 98% rename from core-java/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java rename to java-strings/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java index aeb33fe875..e2dd0ac1db 100644 --- a/core-java/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java +++ b/java-strings/src/test/java/com/baeldung/java/countingChars/CountCharsExampleUnitTest.java @@ -1,13 +1,14 @@ package com.baeldung.java.countingChars; -import com.google.common.base.CharMatcher; -import org.apache.commons.lang.StringUtils; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static org.junit.Assert.assertEquals; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + +import com.google.common.base.CharMatcher; /*** diff --git a/core-java-8/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java b/java-strings/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java rename to java-strings/src/test/java/com/baeldung/java8/base64/ApacheCommonsEncodeDecodeUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java b/java-strings/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java rename to java-strings/src/test/java/com/baeldung/java8/base64/Java8EncodeDecodeUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/string/CharSequenceVsStringUnitTest.java b/java-strings/src/test/java/com/baeldung/string/CharSequenceVsStringUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/string/CharSequenceVsStringUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/CharSequenceVsStringUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java b/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java similarity index 76% rename from core-java-8/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java index 8901bcf9db..a9488e27a4 100644 --- a/core-java-8/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java +++ b/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java @@ -3,7 +3,9 @@ package com.baeldung.string; import org.junit.Test; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.junit.Assert.assertEquals; @@ -62,5 +64,20 @@ public class JoinerSplitterUnitTest { assertEquals(result, expectation); } + + @Test + public void givenStringArray_transformedToStream_convertToMap() { + + String[] programming_languages = new String[] {"language:java","os:linux","editor:emacs"}; + + Map expectation=new HashMap<>(); + expectation.put("language", "java"); + expectation.put("os", "linux"); + expectation.put("editor", "emacs"); + + Map result = JoinerSplitter.arrayToMap(programming_languages); + assertEquals(result, expectation); + + } } diff --git a/core-java/src/test/java/com/baeldung/string/PalindromeUnitTest.java b/java-strings/src/test/java/com/baeldung/string/PalindromeUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/string/PalindromeUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/PalindromeUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/RemovingEmojiFromStringUnitTest.java b/java-strings/src/test/java/com/baeldung/string/RemovingEmojiFromStringUnitTest.java new file mode 100644 index 0000000000..8688f9dcf5 --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/string/RemovingEmojiFromStringUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.string; + +import static org.junit.Assert.assertEquals; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.Test; + +import com.vdurmont.emoji.EmojiParser; + +public class RemovingEmojiFromStringUnitTest { + String text = "la conférence, commencera à 10 heures 😅"; + String regex = "[^\\p{L}\\p{N}\\p{P}\\p{Z}]"; + + @Test + public void whenRemoveEmojiUsingLibrary_thenSuccess() { + String result = EmojiParser.removeAllEmojis(text); + System.out.println(result); + assertEquals(result, "la conférence, commencera à 10 heures "); + } + + @Test + public void whenReplaceEmojiUsingLibrary_thenSuccess() { + String result = EmojiParser.parseToAliases(text); + System.out.println(result); + assertEquals(result, "la conférence, commencera à 10 heures :sweat_smile:"); + } + + @Test + public void whenRemoveEmojiUsingRegex_thenSuccess() { + String result = text.replaceAll(regex, ""); + System.out.println(result); + assertEquals(result, "la conférence, commencera à 10 heures "); + } + + @Test + public void whenRemoveEmojiUsingMatcher_thenSuccess() { + Pattern pattern = Pattern.compile(regex, Pattern.UNICODE_CHARACTER_CLASS); + Matcher matcher = pattern.matcher(text); + + String result = matcher.replaceAll(""); + System.out.println(result); + assertEquals(result, "la conférence, commencera à 10 heures "); + } + + @Test + public void whenRemoveEmojiUsingCodepoints_thenSuccess() { + String result = text.replaceAll("[\\x{0001f300}-\\x{0001f64f}]|[\\x{0001f680}-\\x{0001f6ff}]", ""); + System.out.println(result); + assertEquals(result, "la conférence, commencera à 10 heures "); + } + + @Test + public void whenRemoveEmojiUsingUnicode_thenSuccess() { + String result = text.replaceAll("[\ud83c\udf00-\ud83d\ude4f]|[\ud83d\ude80-\ud83d\udeff]", ""); + System.out.println(result); + assertEquals(result, "la conférence, commencera à 10 heures "); + } +} diff --git a/core-java/src/test/java/com/baeldung/string/SplitUnitTest.java b/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java similarity index 73% rename from core-java/src/test/java/com/baeldung/string/SplitUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java index 83fd253b97..6157640a4a 100644 --- a/core-java/src/test/java/com/baeldung/string/SplitUnitTest.java +++ b/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java @@ -1,12 +1,14 @@ package com.baeldung.string; -import com.google.common.base.Splitter; -import org.apache.commons.lang.StringUtils; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.Arrays; import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Test; + +import com.google.common.base.Splitter; public class SplitUnitTest { @@ -53,4 +55,18 @@ public class SplitUnitTest { assertThat(resultList) .containsExactly("car", "jeep", "scooter"); } + + @Test + public void givenStringContainsSpaces_whenSplitAndTrim_thenReturnsArray_using_Regex() { + assertThat(" car , jeep, scooter ".trim() + .split("\\s*,\\s*")).containsExactly("car", "jeep", "scooter"); + + } + + @Test + public void givenStringContainsSpaces_whenSplitAndTrim_thenReturnsArray_using_java_8() { + assertThat(Arrays.stream(" car , jeep, scooter ".split(",")) + .map(String::trim) + .toArray(String[]::new)).containsExactly("car", "jeep", "scooter"); + } } diff --git a/core-java/src/test/java/com/baeldung/string/StringComparisonUnitTest.java b/java-strings/src/test/java/com/baeldung/string/StringComparisonUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/string/StringComparisonUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/StringComparisonUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/StringContainingCharactersUnitTest.java b/java-strings/src/test/java/com/baeldung/string/StringContainingCharactersUnitTest.java new file mode 100644 index 0000000000..be79103e6b --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/string/StringContainingCharactersUnitTest.java @@ -0,0 +1,136 @@ +package com.baeldung.string; + +import org.junit.Test; + +import java.util.regex.Pattern; + +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertTrue; + +public class StringContainingCharactersUnitTest { + + private static final Pattern[] inputRegexes = new Pattern[4]; + + private static final String regex = "^(?=.*?\\p{Lu})(?=.*?\\p{Ll})(?=.*?\\d)(?=.*?[`~!@#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?]).*$"; + + static { + inputRegexes[0] = Pattern.compile(".*[A-Z].*"); + inputRegexes[1] = Pattern.compile(".*[a-z].*"); + inputRegexes[2] = Pattern.compile(".*\\d.*"); + inputRegexes[3] = Pattern.compile(".*[`~!@#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",<.>/?].*"); + } + + private static boolean isMatchingRegex(String input) { + boolean inputMatches = true; + for (Pattern inputRegex : inputRegexes) { + if (!inputRegex + .matcher(input) + .matches()) { + inputMatches = false; + } + } + return inputMatches; + } + + private static boolean checkString(String input) { + String specialChars = "~`!@#$%^&*()-_=+\\|[{]};:'\",<.>/?"; + char currentCharacter; + boolean numberPresent = false; + boolean upperCasePresent = false; + boolean lowerCasePresent = false; + boolean specialCharacterPresent = false; + + for (int i = 0; i < input.length(); i++) { + currentCharacter = input.charAt(i); + if (Character.isDigit(currentCharacter)) { + numberPresent = true; + } else if (Character.isUpperCase(currentCharacter)) { + upperCasePresent = true; + } else if (Character.isLowerCase(currentCharacter)) { + lowerCasePresent = true; + } else if (specialChars.contains(String.valueOf(currentCharacter))) { + specialCharacterPresent = true; + } + } + + return numberPresent && upperCasePresent && lowerCasePresent && specialCharacterPresent; + } + + @Test + public void givenRegexes_whenMatchingCorrectString_thenMatches() { + String validInput = "Ab3;"; + assertTrue(isMatchingRegex(validInput)); + } + + @Test + public void givenRegexes_whenMatchingWrongStrings_thenNotMatching() { + String invalidInput = "Ab3"; + assertFalse(isMatchingRegex(invalidInput)); + + invalidInput = "Ab;"; + assertFalse(isMatchingRegex(invalidInput)); + + invalidInput = "A3;"; + assertFalse(isMatchingRegex(invalidInput)); + + invalidInput = "b3;"; + assertFalse(isMatchingRegex(invalidInput)); + } + + @Test + public void givenValidString_whenChecking_thenCorrect() { + String validInput = "Ab3;"; + assertTrue(checkString(validInput)); + } + + @Test + public void givenInvalidStrings_whenChecking_thenNotCorrect() { + String invalidInput = "Ab3"; + assertFalse(checkString(invalidInput)); + + invalidInput = "Ab;"; + assertFalse(checkString(invalidInput)); + + invalidInput = "A3;"; + assertFalse(checkString(invalidInput)); + + invalidInput = "b3;"; + assertFalse(checkString(invalidInput)); + } + + @Test + public void givenSingleRegex_whenMatchingCorrectString_thenMatches() { + String validInput = "Ab3;"; + assertTrue(Pattern + .compile(regex) + .matcher(validInput) + .matches()); + } + + @Test + public void givenSingleRegex_whenMatchingWrongStrings_thenNotMatching() { + String invalidInput = "Ab3"; + assertFalse(Pattern + .compile(regex) + .matcher(invalidInput) + .matches()); + + invalidInput = "Ab;"; + assertFalse(Pattern + .compile(regex) + .matcher(invalidInput) + .matches()); + + invalidInput = "A3;"; + assertFalse(Pattern + .compile(regex) + .matcher(invalidInput) + .matches()); + + invalidInput = "b3;"; + assertFalse(Pattern + .compile(regex) + .matcher(invalidInput) + .matches()); + } +} diff --git a/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java b/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java new file mode 100644 index 0000000000..17b13f89de --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.string; + +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString; +import static org.hamcrest.text.IsEmptyString.isEmptyString; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import org.apache.commons.lang3.StringUtils; +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import com.google.common.base.Strings; + +public class StringEmptyUnitTest { + + private String text = "baeldung"; + + @Test + public void givenAString_whenCheckedForEmptyUsingJunit_shouldAssertSuccessfully() { + assertTrue(!text.isEmpty()); + assertFalse(text.isEmpty()); + assertNotEquals("", text); + assertNotSame("", text); + } + + @Test + public void givenAString_whenCheckedForEmptyUsingHamcrest_shouldAssertSuccessfully() { + assertThat(text, not(isEmptyString())); + assertThat(text, not(isEmptyOrNullString())); + } + + @Test + public void givenAString_whenCheckedForEmptyUsingCommonsLang_shouldAssertSuccessfully() { + assertTrue(StringUtils.isNotBlank(text)); + } + + @Test + public void givenAString_whenCheckedForEmptyUsingAssertJ_shouldAssertSuccessfully() { + Assertions.assertThat(text).isNotEmpty(); + } + + @Test + public void givenAString_whenCheckedForEmptyUsingGuava_shouldAssertSuccessfully() { + assertFalse(Strings.isNullOrEmpty(text)); + } + +} diff --git a/core-java/src/test/java/com/baeldung/string/StringHelperUnitTest.java b/java-strings/src/test/java/com/baeldung/string/StringHelperUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/string/StringHelperUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/StringHelperUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/string/StringToCharStreamUnitTest.java b/java-strings/src/test/java/com/baeldung/string/StringToCharStreamUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/string/StringToCharStreamUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/StringToCharStreamUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/string/StringUnitTest.java b/java-strings/src/test/java/com/baeldung/string/StringUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/string/StringUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/StringUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/SubstringUnitTest.java b/java-strings/src/test/java/com/baeldung/string/SubstringUnitTest.java new file mode 100644 index 0000000000..3a4e231828 --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/string/SubstringUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.string; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Assert; +import org.junit.Test; + +public class SubstringUnitTest { + + String text = "Julia Evans was born on 25-09-1984. She is currently living in the USA (United States of America)."; + + @Test + public void givenAString_whenUsedStringUtils_ShouldReturnProperSubstring() { + Assert.assertEquals("United States of America", StringUtils.substringBetween(text, "(", ")")); + Assert.assertEquals("the USA (United States of America).", StringUtils.substringAfter(text, "living in ")); + Assert.assertEquals("Julia Evans", StringUtils.substringBefore(text, " was born")); + } + + @Test + public void givenAString_whenUsedScanner_ShouldReturnProperSubstring() { + try (Scanner scanner = new Scanner(text)) { + scanner.useDelimiter("\\."); + Assert.assertEquals("Julia Evans was born on 25-09-1984", scanner.next()); + } + } + + @Test + public void givenAString_whenUsedSplit_ShouldReturnProperSubstring() { + String[] sentences = text.split("\\."); + Assert.assertEquals("Julia Evans was born on 25-09-1984", sentences[0]); + } + + @Test + public void givenAString_whenUsedRegex_ShouldReturnProperSubstring() { + Pattern pattern = Pattern.compile("\\d{2}\\-\\d{2}-\\d{4}"); + Matcher matcher = pattern.matcher(text); + + if (matcher.find()) { + Assert.assertEquals("25-09-1984", matcher.group()); + } + } + + @Test + public void givenAString_whenUsedSubSequence_ShouldReturnProperSubstring() { + Assert.assertEquals("USA (United States of America)", text.subSequence(67, text.length() - 1)); + } + + @Test + public void givenAString_whenUsedSubstring_ShouldReturnProperSubstring() { + Assert.assertEquals("USA (United States of America).", text.substring(67)); + Assert.assertEquals("USA (United States of America)", text.substring(67, text.length() - 1)); + } + + @Test + public void givenAString_whenUsedSubstringWithIndexOf_ShouldReturnProperSubstring() { + Assert.assertEquals("United States of America", text.substring(text.indexOf('(') + 1, text.indexOf(')'))); + } + +} diff --git a/core-java/src/test/java/com/baeldung/string/TitleCaseConverterUnitTest.java b/java-strings/src/test/java/com/baeldung/string/TitleCaseConverterUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/string/TitleCaseConverterUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/TitleCaseConverterUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/formatter/DateToStringFormatterUnitTest.java b/java-strings/src/test/java/com/baeldung/string/formatter/DateToStringFormatterUnitTest.java new file mode 100644 index 0000000000..f236c641c3 --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/string/formatter/DateToStringFormatterUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.string.formatter; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import static org.junit.Assert.assertEquals; + +public class DateToStringFormatterUnitTest { + + private static final String DATE_FORMAT = "MMM d, yyyy HH:mm a"; + private static final String EXPECTED_STRING_DATE = "Aug 1, 2018 12:00 PM"; + private static Date date; + + @BeforeClass + public static void setUp() { + TimeZone.setDefault(TimeZone.getTimeZone("CET")); + Calendar calendar = Calendar.getInstance(); + calendar.set(2018, Calendar.AUGUST, 1, 12, 0); + date = calendar.getTime(); + } + + @Test + public void whenDateConvertedUsingSimpleDateFormatToString_thenCorrect() { + DateFormat formatter = new SimpleDateFormat(DATE_FORMAT); + String formattedDate = formatter.format(date); + + assertEquals(EXPECTED_STRING_DATE, formattedDate); + } + + @Test + public void whenDateConvertedUsingDateFormatToString_thenCorrect() { + String formattedDate = DateFormat + .getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT) + .format(date); + + assertEquals(EXPECTED_STRING_DATE, formattedDate); + } + + @Test + public void whenDateConvertedUsingFormatterToString_thenCorrect() { + String formattedDate = String.format("%1$tb %1$te, %1$tY %1$tI:%1$tM %1$Tp", date); + + assertEquals(EXPECTED_STRING_DATE, formattedDate); + } + + @Test + public void whenDateConvertedUsingDateTimeApiToString_thenCorrect() { + DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DATE_FORMAT); + Instant instant = date.toInstant(); + LocalDateTime ldt = instant + .atZone(ZoneId.of("CET")) + .toLocalDateTime(); + String formattedDate = ldt.format(fmt); + + assertEquals(EXPECTED_STRING_DATE, formattedDate); + } +} diff --git a/core-java/src/test/java/com/baeldung/string/formatter/StringFormatterExampleUnitTest.java b/java-strings/src/test/java/com/baeldung/string/formatter/StringFormatterExampleUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/string/formatter/StringFormatterExampleUnitTest.java rename to java-strings/src/test/java/com/baeldung/string/formatter/StringFormatterExampleUnitTest.java diff --git a/java-strings/src/test/java/com/baeldung/string/sorting/AnagramValidatorUnitTest.java b/java-strings/src/test/java/com/baeldung/string/sorting/AnagramValidatorUnitTest.java new file mode 100644 index 0000000000..07d31c7187 --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/string/sorting/AnagramValidatorUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.string.sorting; + + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.Test; + +import com.baeldung.string.sorting.AnagramValidator; + +class AnagramValidatorUnitTest { + + @Test + void givenValidAnagrams_whenSorted_thenEqual() { + boolean isValidAnagram = AnagramValidator.isValid("Avida Dollars", "Salvador Dali"); + + assertTrue(isValidAnagram); + } + + @Test + void givenNotValidAnagrams_whenSorted_thenNotEqual() { + boolean isValidAnagram = AnagramValidator.isValid("abc", "def"); + + assertFalse(isValidAnagram); + } +} diff --git a/java-strings/src/test/java/com/baeldung/string/sorting/SortStringUnitTest.java b/java-strings/src/test/java/com/baeldung/string/sorting/SortStringUnitTest.java new file mode 100644 index 0000000000..90d1dad554 --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/string/sorting/SortStringUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.string.sorting; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SortStringUnitTest { + + @Test + void givenString_whenSort_thenSorted() { + String abcd = "bdca"; + char[] chars = abcd.toCharArray(); + + Arrays.sort(chars); + String sorted = new String(chars); + + assertThat(sorted).isEqualTo("abcd"); + } + + @Test + void givenString_whenSortJava8_thenSorted() { + String sorted = "bdca".chars() + .sorted() + .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) + .toString(); + + assertThat(sorted).isEqualTo("abcd"); + } +} diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java b/java-strings/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsCreatableUnitTest.java b/java-strings/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsCreatableUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsCreatableUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsCreatableUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsParsableUnitTest.java b/java-strings/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsParsableUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsParsableUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsParsableUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/RegularExpressionsUnitTest.java b/java-strings/src/test/java/com/baeldung/stringisnumeric/RegularExpressionsUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/stringisnumeric/RegularExpressionsUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringisnumeric/RegularExpressionsUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericSpaceUnitTest.java b/java-strings/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericSpaceUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericSpaceUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericSpaceUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericUnitTest.java b/java-strings/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericUnitTest.java diff --git a/core-java-8/src/test/java/com/baeldung/stringjoiner/StringJoinerUnitTest.java b/java-strings/src/test/java/com/baeldung/stringjoiner/StringJoinerUnitTest.java similarity index 100% rename from core-java-8/src/test/java/com/baeldung/stringjoiner/StringJoinerUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringjoiner/StringJoinerUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java b/java-strings/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringpool/StringPoolUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/stringtokenizer/TokenizerUnitTest.java b/java-strings/src/test/java/com/baeldung/stringtokenizer/TokenizerUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/stringtokenizer/TokenizerUnitTest.java rename to java-strings/src/test/java/com/baeldung/stringtokenizer/TokenizerUnitTest.java diff --git a/java-strings/src/test/resources/.gitignore b/java-strings/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/java-strings/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/java-strings/src/test/resources/test_image.jpg b/java-strings/src/test/resources/test_image.jpg new file mode 100644 index 0000000000..d0db1627c9 Binary files /dev/null and b/java-strings/src/test/resources/test_image.jpg differ diff --git a/java-vavr-stream/pom.xml b/java-vavr-stream/pom.xml index 093d8763e3..395d2c81ba 100644 --- a/java-vavr-stream/pom.xml +++ b/java-vavr-stream/pom.xml @@ -1,6 +1,6 @@ + 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.samples java-vavr-stream @@ -22,7 +22,6 @@ - UTF-8 0.9.2 diff --git a/java-vavr-stream/src/main/resources/logback.xml b/java-vavr-stream/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-vavr-stream/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/java-websocket/pom.xml b/java-websocket/pom.xml index 85078bd696..e8ff8dfc36 100644 --- a/java-websocket/pom.xml +++ b/java-websocket/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung java-websocket @@ -27,7 +27,6 @@ - UTF-8 1.1 2.8.0 diff --git a/java-websocket/src/main/resources/logback.xml b/java-websocket/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/java-websocket/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/javafx/pom.xml b/javafx/pom.xml index b2de708be1..c9c5bc294e 100644 --- a/javafx/pom.xml +++ b/javafx/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 javafx diff --git a/javafx/src/main/resources/logback.xml b/javafx/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/javafx/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/javax-servlet-init-params/pom.xml b/javax-servlet-init-params/pom.xml deleted file mode 100644 index 4f766a7e2c..0000000000 --- a/javax-servlet-init-params/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - 4.0.0 - com.baeldung.javax-servlet-init-params - javax-servlet-init-params - 1.0 - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - junit - junit - 4.12 - test - - - org.assertj - assertj-core - 3.9.1 - test - - - org.hamcrest - hamcrest-core - 1.3 - test - - - org.mockito - mockito-core - 2.18.3 - test - - - javax - javaee-web-api - 7.0 - provided - - - jstl - jstl - 1.2 - - - javax.el - el-api - 2.2 - - - \ No newline at end of file diff --git a/javax-servlet-init-params/src/main/webapp/WEB-INF/web.xml b/javax-servlet-init-params/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 1b801171b3..0000000000 --- a/javax-servlet-init-params/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - province - Mendoza - - - country - Argentina - - diff --git a/javax-servlets/README.md b/javax-servlets/README.md index 55ca1116aa..3c3b17996b 100644 --- a/javax-servlets/README.md +++ b/javax-servlets/README.md @@ -5,3 +5,5 @@ - [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) +- [Java EE Servlet Exception Handling](http://www.baeldung.com/servlet-exceptions) +- [Context and Servlet Initialization Parameters](http://www.baeldung.com/context-servlet-initialization-param) diff --git a/javax-servlets/pom.xml b/javax-servlets/pom.xml index f64ce67a1f..7b4eecd880 100644 --- a/javax-servlets/pom.xml +++ b/javax-servlets/pom.xml @@ -1,79 +1,94 @@ - 4.0.0 - javax-servlets - 1.0-SNAPSHOT + 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.javax-servlets + javax-servlets + 1.0-SNAPSHOT + war + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + org.assertj + assertj-core + ${assertj.version} + test + - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + commons-io + commons-io + ${commons-io.version} + - - - - commons-fileupload - commons-fileupload - 1.3.3 - - - commons-io - commons-io - 2.6 - + + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + + + javax.servlet.jsp.jstl + jstl-api + ${jstl.version} + + + javax.servlet.jsp + javax.servlet.jsp-api + ${jsp.version} + + + javax.servlet + jstl + ${jstl.version} + - - - javax.servlet - javax.servlet-api - 4.0.1 - - - javax.servlet.jsp.jstl - jstl-api - 1.2 - - - javax.servlet.jsp - javax.servlet.jsp-api - 2.3.1 - - - javax.servlet - jstl - 1.2 - - - - org.apache.httpcomponents - httpclient - ${org.apache.httpcomponents.version} - test - - - commons-logging - commons-logging - - - - - com.google.code.gson - gson - ${gson.version} - - - org.springframework - spring-test - ${spring-test.version} - test - - - - - 4.5.3 - 5.0.5.RELEASE - 2.8.2 - - \ No newline at end of file + + org.apache.httpcomponents + httpclient + ${org.apache.httpcomponents.version} + test + + + commons-logging + commons-logging + + + + + com.google.code.gson + gson + ${gson.version} + + + org.springframework + spring-test + ${spring-test.version} + test + + + + 4.5.3 + 5.0.5.RELEASE + 2.8.2 + 3.9.1 + 2.21.0 + 1.3.3 + 2.6 + 4.0.1 + 1.2 + 2.3.1 + + diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/DownloadServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/DownloadServlet.java index 9bbf8f4095..b1a6621b24 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/DownloadServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/DownloadServlet.java @@ -4,7 +4,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -15,21 +14,19 @@ public class DownloadServlet extends HttpServlet { private final int ARBITARY_SIZE = 1048; @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType("text/plain"); resp.setHeader("Content-disposition", "attachment; filename=sample.txt"); - - OutputStream out = resp.getOutputStream(); - InputStream in = req.getServletContext().getResourceAsStream("/WEB-INF/sample.txt"); - byte[] buffer = new byte[ARBITARY_SIZE]; - - int numBytesRead; - while ((numBytesRead = in.read(buffer)) > 0) { - out.write(buffer, 0, numBytesRead); + try (InputStream in = req.getServletContext().getResourceAsStream("/WEB-INF/sample.txt"); + OutputStream out = resp.getOutputStream()) { + + byte[] buffer = new byte[ARBITARY_SIZE]; + + int numBytesRead; + while ((numBytesRead = in.read(buffer)) > 0) { + out.write(buffer, 0, numBytesRead); + } } - - in.close(); - out.flush(); } } diff --git a/javax-servlet-init-params/src/main/java/com/baeldung/servlets/UserServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java similarity index 97% rename from javax-servlet-init-params/src/main/java/com/baeldung/servlets/UserServlet.java rename to javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java index e195aa092a..269cee3922 100644 --- a/javax-servlet-init-params/src/main/java/com/baeldung/servlets/UserServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/UserServlet.java @@ -1,49 +1,49 @@ -package com.baeldung.servlets; - -import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.annotation.WebInitParam; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"}, initParams={ - @WebInitParam(name="name", value="Not provided"), - @WebInitParam(name="email", value="Not provided")}) -public class UserServlet extends HttpServlet { - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - processRequest(request, response); - forwardRequest(request, response, "/WEB-INF/jsp/result.jsp"); - } - - protected void processRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - request.setAttribute("name", getRequestParameter(request, "name")); - request.setAttribute("email", getRequestParameter(request, "email")); - request.setAttribute("province", getContextParameter("province")); - request.setAttribute("country", getContextParameter("country")); - } - - protected String getRequestParameter(HttpServletRequest request, String name) { - String param = request.getParameter(name); - return !param.isEmpty() ? param : getInitParameter(name); - } - - protected String getContextParameter(String name) { - return getServletContext().getInitParameter(name); - } - - protected void forwardRequest(HttpServletRequest request, HttpServletResponse response, String path) - throws ServletException, IOException { - request.getRequestDispatcher(path).forward(request, response); - } +package com.baeldung.servlets; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebInitParam; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "UserServlet", urlPatterns = {"/userServlet"}, initParams={ + @WebInitParam(name="name", value="Not provided"), + @WebInitParam(name="email", value="Not provided")}) +public class UserServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + processRequest(request, response); + forwardRequest(request, response, "/WEB-INF/jsp/result.jsp"); + } + + protected void processRequest(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + request.setAttribute("name", getRequestParameter(request, "name")); + request.setAttribute("email", getRequestParameter(request, "email")); + request.setAttribute("province", getContextParameter("province")); + request.setAttribute("country", getContextParameter("country")); + } + + protected String getRequestParameter(HttpServletRequest request, String name) { + String param = request.getParameter(name); + return !param.isEmpty() ? param : getInitParameter(name); + } + + protected String getContextParameter(String name) { + return getServletContext().getInitParameter(name); + } + + protected void forwardRequest(HttpServletRequest request, HttpServletResponse response, String path) + throws ServletException, IOException { + request.getRequestDispatcher(path).forward(request, response); + } } \ No newline at end of file diff --git a/javax-servlets/src/main/resources/logback.xml b/javax-servlets/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/javax-servlets/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/javax-servlet-init-params/src/main/webapp/WEB-INF/jsp/result.jsp b/javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp similarity index 100% rename from javax-servlet-init-params/src/main/webapp/WEB-INF/jsp/result.jsp rename to javax-servlets/src/main/webapp/WEB-INF/jsp/result.jsp diff --git a/javax-servlets/src/main/webapp/WEB-INF/web.xml b/javax-servlets/src/main/webapp/WEB-INF/web.xml index c9a06ac52d..383be7ff25 100644 --- a/javax-servlets/src/main/webapp/WEB-INF/web.xml +++ b/javax-servlets/src/main/webapp/WEB-INF/web.xml @@ -1,9 +1,17 @@ + - + + province + Mendoza + + + country + Argentina + 404 /error-404.html diff --git a/javax-servlet-init-params/src/main/webapp/index.jsp b/javax-servlets/src/main/webapp/user.jsp similarity index 90% rename from javax-servlet-init-params/src/main/webapp/index.jsp rename to javax-servlets/src/main/webapp/user.jsp index ca41942e5d..c6e1bb69f9 100644 --- a/javax-servlet-init-params/src/main/webapp/index.jsp +++ b/javax-servlets/src/main/webapp/user.jsp @@ -3,7 +3,7 @@ - Context and Initialization Servlet Parameters + Context and Servlet Initialization Parameters diff --git a/javax-servlets/src/test/java/com/baeldung/servlets/FormServletLiveTest.java b/javax-servlets/src/test/java/com/baeldung/test/FormServletLiveTest.java similarity index 100% rename from javax-servlets/src/test/java/com/baeldung/servlets/FormServletLiveTest.java rename to javax-servlets/src/test/java/com/baeldung/test/FormServletLiveTest.java diff --git a/javax-servlet-init-params/src/test/java/com/baeldung/test/UserServletUnitTest.java b/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java similarity index 95% rename from javax-servlet-init-params/src/test/java/com/baeldung/test/UserServletUnitTest.java rename to javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java index ef3d877dd7..d4c93791d2 100644 --- a/javax-servlet-init-params/src/test/java/com/baeldung/test/UserServletUnitTest.java +++ b/javax-servlets/src/test/java/com/baeldung/test/UserServletUnitTest.java @@ -1,52 +1,52 @@ -package com.baeldung.test; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import static org.assertj.core.api.Assertions.assertThat; -import org.junit.BeforeClass; -import org.junit.Test; -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class UserServletUnitTest { - - private static HttpServletRequest request; - private static HttpServletResponse response; - - - @BeforeClass - public static void setUpHttpServletRequestMockInstance() { - request = mock(HttpServletRequest.class); - } - - @BeforeClass - public static void setUpHttpServletResponsetMockInstance() { - response = mock(HttpServletResponse.class); - } - - @Test - public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenCalledAtLeastOnce() { - request.getParameter("name"); - verify(request, atLeast(1)).getParameter("name"); - } - - @Test - public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenOneAssertion() { - when(request.getParameter("name")).thenReturn("username"); - assertThat(request.getParameter("name")).isEqualTo("username"); - } - - @Test - public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenCalledAtLeastOnce() { - response.getContentType(); - verify(response, atLeast(1)).getContentType(); - } - - @Test - public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenOneAssertion() { - when(response.getContentType()).thenReturn("text/html"); - assertThat(response.getContentType()).isEqualTo("text/html"); - } +package com.baeldung.servlets; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class UserServletUnitTest { + + private static HttpServletRequest request; + private static HttpServletResponse response; + + + @BeforeClass + public static void setUpHttpServletRequestMockInstance() { + request = mock(HttpServletRequest.class); + } + + @BeforeClass + public static void setUpHttpServletResponsetMockInstance() { + response = mock(HttpServletResponse.class); + } + + @Test + public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenCalledAtLeastOnce() { + request.getParameter("name"); + verify(request, atLeast(1)).getParameter("name"); + } + + @Test + public void givenHttpServletRequestMockInstance_whenCalledgetParameter_thenOneAssertion() { + when(request.getParameter("name")).thenReturn("username"); + assertThat(request.getParameter("name")).isEqualTo("username"); + } + + @Test + public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenCalledAtLeastOnce() { + response.getContentType(); + verify(response, atLeast(1)).getContentType(); + } + + @Test + public void givenHttpServletResponseMockInstance_whenCalledgetContentType_thenOneAssertion() { + when(response.getContentType()).thenReturn("text/html"); + assertThat(response.getContentType()).isEqualTo("text/html"); + } } \ No newline at end of file diff --git a/javaxval/README.md b/javaxval/README.md index 3153546c7d..3a975022ad 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -9,3 +9,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Java Bean Validation Basics](http://www.baeldung.com/javax-validation) - [Validating Container Elements with Bean Validation 2.0](http://www.baeldung.com/bean-validation-container-elements) - [Method Constraints with Bean Validation 2.0](http://www.baeldung.com/javax-validation-method-constraints) +- [Difference Between @NotNull, @NotEmpty, and @NotBlank Constraints in Bean Validation](https://www.baeldung.com/java-bean-validation-not-null-empty-blank) diff --git a/javaxval/bin/pom.xml b/javaxval/bin/pom.xml deleted file mode 100644 index a16072bb1a..0000000000 --- a/javaxval/bin/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ - - 4.0.0 - com.baeldung - javaxval - 0.1-SNAPSHOT - - - - - - javax.validation - validation-api - 1.1.0.Final - - - - org.hibernate - hibernate-validator - 5.2.1.Final - - - - org.hibernate - hibernate-validator-annotation-processor - 5.2.1.Final - - - - javax.el - javax.el-api - 2.2.4 - - - - org.glassfish.web - javax.el - 2.2.4 - - - - - - \ No newline at end of file diff --git a/javaxval/pom.xml b/javaxval/pom.xml index 5de77ed26b..0263fb68af 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -1,55 +1,73 @@ - - 4.0.0 - com.baeldung - javaxval - 0.1-SNAPSHOT - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - org.hibernate - hibernate-validator - ${hibernate-validator.version} - - - org.hibernate - hibernate-validator-annotation-processor - ${hibernate-validator.version} - - - javax.el - javax.el-api - ${javax.el-api.version} - - - org.glassfish.web - javax.el - ${javax.el.version} - - - org.springframework - spring-context - ${org.springframework.version} - - - org.springframework - spring-test - ${org.springframework.version} - - - - - 2.0.1.Final - 6.0.7.Final - 3.0.0 - 2.2.6 - 5.0.2.RELEASE - - - \ No newline at end of file + + 4.0.0 + com.baeldung + javaxval + 0.1-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + javax.validation + validation-api + ${validation-api.version} + + + org.hibernate + hibernate-validator + ${hibernate-validator.version} + + + org.hibernate + hibernate-validator-annotation-processor + ${hibernate-validator.version} + + + javax.el + javax.el-api + ${javax.el-api.version} + + + org.glassfish + javax.el + ${javax.el.version} + + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework + spring-test + ${org.springframework.version} + + + junit + junit + ${junit.version} + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + + + 2.0.1.Final + 6.0.13.Final + 3.0.0 + 3.0.0 + 5.0.2.RELEASE + 4.12 + 3.11.1 + + diff --git a/javaxval/src/main/java/org/baeldung/javabeanconstraints/appplication/Application.java b/javaxval/src/main/java/org/baeldung/javabeanconstraints/appplication/Application.java new file mode 100644 index 0000000000..c9f2ab6f98 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javabeanconstraints/appplication/Application.java @@ -0,0 +1,14 @@ +package org.baeldung.javabeanconstraints.appplication; + +import javax.validation.Validation; +import javax.validation.Validator; +import org.baeldung.javabeanconstraints.entities.UserNotBlank; + +public class Application { + + public static void main(String[] args) throws Exception { + Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); + UserNotBlank user = new UserNotBlank(" "); + validator.validate(user).stream().forEach(violation -> System.out.println(violation.getMessage())); + } +} diff --git a/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotBlank.java b/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotBlank.java new file mode 100644 index 0000000000..2ea6a3af56 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotBlank.java @@ -0,0 +1,22 @@ +package org.baeldung.javabeanconstraints.entities; + +import javax.validation.constraints.NotBlank; + +public class UserNotBlank { + + @NotBlank(message = "Name is mandatory") + private final String name; + + public UserNotBlank(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "User{" + "name=" + name + "}"; + } +} diff --git a/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotEmpty.java b/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotEmpty.java new file mode 100644 index 0000000000..39e34b63d3 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotEmpty.java @@ -0,0 +1,22 @@ +package org.baeldung.javabeanconstraints.entities; + +import javax.validation.constraints.NotEmpty; + +public class UserNotEmpty { + + @NotEmpty(message = "Name is mandatory") + private final String name; + + public UserNotEmpty(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "User{" + "name=" + name + "}"; + } +} diff --git a/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotNull.java b/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotNull.java new file mode 100644 index 0000000000..598c9ba9f9 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/javabeanconstraints/entities/UserNotNull.java @@ -0,0 +1,22 @@ +package org.baeldung.javabeanconstraints.entities; + +import javax.validation.constraints.NotNull; + +public class UserNotNull { + + @NotNull(message = "Name is mandatory") + private final String name; + + public UserNotNull(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "User{" + "name=" + name + "}"; + } +} diff --git a/javaxval/src/main/resources/logback.xml b/javaxval/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/javaxval/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotBlankUnitTest.java b/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotBlankUnitTest.java new file mode 100644 index 0000000000..954833fef1 --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotBlankUnitTest.java @@ -0,0 +1,63 @@ +package org.baeldung.javabeanconstraints.test; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import static org.assertj.core.api.Assertions.assertThat; +import org.baeldung.javabeanconstraints.entities.UserNotBlank; +import org.junit.BeforeClass; +import org.junit.Test; + +public class UserNotBlankUnitTest { + + private static Validator validator; + + @BeforeClass + public static void setupValidatorInstance() { + validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + + @Test + public void whenNotBlankName_thenNoConstraintViolations() { + UserNotBlank user = new UserNotBlank("John"); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(0); + } + + @Test + public void whenBlankName_thenOneConstraintViolation() { + UserNotBlank user = new UserNotBlank(" "); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(1); + } + + @Test + public void whenEmptyName_thenOneConstraintViolation() { + UserNotBlank user = new UserNotBlank(""); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(1); + } + + @Test + public void whenNullName_thenOneConstraintViolation() { + UserNotBlank user = new UserNotBlank(null); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(1); + } + + @Test + public void whenToString_thenCorrect() { + UserNotBlank user = new UserNotBlank("John"); + + assertThat(user.toString()).isEqualTo("User{name=John}"); + } +} diff --git a/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotEmptyUnitTest.java b/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotEmptyUnitTest.java new file mode 100644 index 0000000000..c2675ed8b6 --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotEmptyUnitTest.java @@ -0,0 +1,54 @@ +package org.baeldung.javabeanconstraints.test; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import static org.assertj.core.api.Assertions.assertThat; +import org.baeldung.javabeanconstraints.entities.UserNotEmpty; +import org.junit.BeforeClass; +import org.junit.Test; + +public class UserNotEmptyUnitTest { + + private static Validator validator; + + @BeforeClass + public static void setupValidatorInstance() { + validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + + @Test + public void whenNotEmptyName_thenNoConstraintViolations() { + UserNotEmpty user = new UserNotEmpty("John"); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(0); + } + + @Test + public void whenEmptyName_thenOneConstraintViolation() { + UserNotEmpty user = new UserNotEmpty(""); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(1); + } + + @Test + public void whenNullName_thenOneConstraintViolation() { + UserNotEmpty user = new UserNotEmpty(null); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(1); + } + + @Test + public void whenToString_thenCorrect() { + UserNotEmpty user = new UserNotEmpty("John"); + + assertThat(user.toString()).isEqualTo("User{name=John}"); + } +} diff --git a/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotNullUnitTest.java b/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotNullUnitTest.java new file mode 100644 index 0000000000..3dd1811947 --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/javabeanconstraints/test/UserNotNullUnitTest.java @@ -0,0 +1,54 @@ +package org.baeldung.javabeanconstraints.test; + +import java.util.Set; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import static org.assertj.core.api.Assertions.assertThat; +import org.baeldung.javabeanconstraints.entities.UserNotNull; +import org.junit.BeforeClass; +import org.junit.Test; + +public class UserNotNullUnitTest { + + private static Validator validator; + + @BeforeClass + public static void setupValidatorInstance() { + validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + + @Test + public void whenNotNullName_thenNoConstraintViolations() { + UserNotNull user = new UserNotNull("John"); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(0); + } + + @Test + public void whenNullName_thenOneConstraintViolation() { + UserNotNull user = new UserNotNull(null); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(1); + } + + @Test + public void whenEmptyName_thenNoConstraintViolations() { + UserNotNull user = new UserNotNull(""); + + Set> violations = validator.validate(user); + + assertThat(violations.size()).isEqualTo(0); + } + + @Test + public void whenToString_thenCorrect() { + UserNotNull user = new UserNotNull("John"); + + assertThat(user.toString()).isEqualTo("User{name=John}"); + } +} diff --git a/jaxb/pom.xml b/jaxb/pom.xml index f8e5ec0977..3ed6d9b21a 100644 --- a/jaxb/pom.xml +++ b/jaxb/pom.xml @@ -1,5 +1,5 @@ + 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 jaxb @@ -42,7 +42,7 @@ javax.activation activation - 1.1 + ${javax.activation.version} @@ -75,7 +75,7 @@ - + @@ -116,13 +116,9 @@
    - @@ -137,6 +133,8 @@ 2.5 3.5 1.0.0 + + 1.1 \ No newline at end of file diff --git a/jaxb/src/main/resources/logback.xml b/jaxb/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/jaxb/src/main/resources/logback.xml +++ b/jaxb/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/jee-7-security/README.md b/jee-7-security/README.md new file mode 100644 index 0000000000..314de6d957 --- /dev/null +++ b/jee-7-security/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Securing Java EE with Spring Security](http://www.baeldung.com/java-ee-spring-security) diff --git a/jee-7-security/pom.xml b/jee-7-security/pom.xml new file mode 100644 index 0000000000..622ca19903 --- /dev/null +++ b/jee-7-security/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + jee-7-security + 1.0-SNAPSHOT + war + jee-7-security + JavaEE 7 Spring Security Application + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + javax + javaee-api + ${javaee_api.version} + provided + + + com.sun.faces + jsf-api + ${com.sun.faces.jsf.version} + + + com.sun.faces + jsf-impl + ${com.sun.faces.jsf.version} + + + javax.servlet + jstl + ${jstl.version} + + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + + + javax.servlet.jsp + jsp-api + ${jsp-api.version} + provided + + + taglibs + standard + ${taglibs.standard.version} + + + + javax.mvc + javax.mvc-api + 1.0-pr + + + + org.springframework.security + spring-security-web + ${org.springframework.security.version} + + + + org.springframework.security + spring-security-config + ${org.springframework.security.version} + + + org.springframework.security + spring-security-taglibs + ${org.springframework.security.version} + + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + src/main/webapp + false + + + + + + + 7.0 + 2.2.14 + 2.2 + 1.1.2 + 4.2.3.RELEASE + + + diff --git a/jee-7/src/main/java/com/baeldung/springSecurity/SecurityWebApplicationInitializer.java b/jee-7-security/src/main/java/com/baeldung/springsecurity/SecurityWebApplicationInitializer.java similarity index 88% rename from jee-7/src/main/java/com/baeldung/springSecurity/SecurityWebApplicationInitializer.java rename to jee-7-security/src/main/java/com/baeldung/springsecurity/SecurityWebApplicationInitializer.java index e6a05f7b71..e3e2ed80e6 100644 --- a/jee-7/src/main/java/com/baeldung/springSecurity/SecurityWebApplicationInitializer.java +++ b/jee-7-security/src/main/java/com/baeldung/springsecurity/SecurityWebApplicationInitializer.java @@ -1,4 +1,4 @@ -package com.baeldung.springSecurity; +package com.baeldung.springsecurity; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; diff --git a/jee-7/src/main/java/com/baeldung/springSecurity/SpringSecurityConfig.java b/jee-7-security/src/main/java/com/baeldung/springsecurity/SpringSecurityConfig.java similarity index 97% rename from jee-7/src/main/java/com/baeldung/springSecurity/SpringSecurityConfig.java rename to jee-7-security/src/main/java/com/baeldung/springsecurity/SpringSecurityConfig.java index bda8930f36..70be1f91ce 100644 --- a/jee-7/src/main/java/com/baeldung/springSecurity/SpringSecurityConfig.java +++ b/jee-7-security/src/main/java/com/baeldung/springsecurity/SpringSecurityConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.springSecurity; +package com.baeldung.springsecurity; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; diff --git a/jee-7/src/main/java/com/baeldung/springSecurity/controller/HomeController.java b/jee-7-security/src/main/java/com/baeldung/springsecurity/controller/HomeController.java similarity index 89% rename from jee-7/src/main/java/com/baeldung/springSecurity/controller/HomeController.java rename to jee-7-security/src/main/java/com/baeldung/springsecurity/controller/HomeController.java index 53fd9f4b81..1662f38609 100644 --- a/jee-7/src/main/java/com/baeldung/springSecurity/controller/HomeController.java +++ b/jee-7-security/src/main/java/com/baeldung/springsecurity/controller/HomeController.java @@ -1,4 +1,4 @@ -package com.baeldung.springSecurity.controller; +package com.baeldung.springsecurity.controller; import javax.mvc.annotation.Controller; import javax.ws.rs.GET; diff --git a/jee-7/src/main/java/com/baeldung/springSecurity/controller/LoginController.java b/jee-7-security/src/main/java/com/baeldung/springsecurity/controller/LoginController.java similarity index 82% rename from jee-7/src/main/java/com/baeldung/springSecurity/controller/LoginController.java rename to jee-7-security/src/main/java/com/baeldung/springsecurity/controller/LoginController.java index a7e7bb471d..45d7ff3d2c 100644 --- a/jee-7/src/main/java/com/baeldung/springSecurity/controller/LoginController.java +++ b/jee-7-security/src/main/java/com/baeldung/springsecurity/controller/LoginController.java @@ -1,4 +1,4 @@ -package com.baeldung.springSecurity.controller; +package com.baeldung.springsecurity.controller; import javax.mvc.annotation.Controller; import javax.ws.rs.GET; diff --git a/jee-7-security/src/main/resources/logback.xml b/jee-7-security/src/main/resources/logback.xml new file mode 100644 index 0000000000..c8c077ba1d --- /dev/null +++ b/jee-7-security/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/styles/style.css b/jee-7-security/src/main/webapp/WEB-INF/beans.xml similarity index 100% rename from spring-security-mvc-socket/src/main/webapp/resources/styles/style.css rename to jee-7-security/src/main/webapp/WEB-INF/beans.xml diff --git a/jee-7-security/src/main/webapp/WEB-INF/faces-config.xml b/jee-7-security/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 0000000000..1f4085458f --- /dev/null +++ b/jee-7-security/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/jee-7/src/main/webapp/WEB-INF/spring/security.xml b/jee-7-security/src/main/webapp/WEB-INF/spring/security.xml similarity index 100% rename from jee-7/src/main/webapp/WEB-INF/spring/security.xml rename to jee-7-security/src/main/webapp/WEB-INF/spring/security.xml diff --git a/jee-7/src/main/webapp/WEB-INF/views/admin.jsp b/jee-7-security/src/main/webapp/WEB-INF/views/admin.jsp similarity index 100% rename from jee-7/src/main/webapp/WEB-INF/views/admin.jsp rename to jee-7-security/src/main/webapp/WEB-INF/views/admin.jsp diff --git a/jee-7/src/main/webapp/WEB-INF/views/home.jsp b/jee-7-security/src/main/webapp/WEB-INF/views/home.jsp similarity index 100% rename from jee-7/src/main/webapp/WEB-INF/views/home.jsp rename to jee-7-security/src/main/webapp/WEB-INF/views/home.jsp diff --git a/jee-7/src/main/webapp/WEB-INF/views/login.jsp b/jee-7-security/src/main/webapp/WEB-INF/views/login.jsp similarity index 100% rename from jee-7/src/main/webapp/WEB-INF/views/login.jsp rename to jee-7-security/src/main/webapp/WEB-INF/views/login.jsp diff --git a/jee-7/src/main/webapp/WEB-INF/views/user.jsp b/jee-7-security/src/main/webapp/WEB-INF/views/user.jsp similarity index 100% rename from jee-7/src/main/webapp/WEB-INF/views/user.jsp rename to jee-7-security/src/main/webapp/WEB-INF/views/user.jsp diff --git a/jee-7-security/src/main/webapp/WEB-INF/web.xml b/jee-7-security/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..e656ffc5be --- /dev/null +++ b/jee-7-security/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,71 @@ + + + + + Faces Servlet + javax.faces.webapp.FacesServlet + + + Faces Servlet + *.jsf + + + javax.faces.PROJECT_STAGE + Development + + + State saving method: 'client' or 'server' (default). See JSF Specification section 2.5.2 + javax.faces.STATE_SAVING_METHOD + client + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + index.jsf + welcome.jsf + index.html + index.jsp + + \ No newline at end of file diff --git a/jee-7/src/main/webapp/index.jsp b/jee-7-security/src/main/webapp/index.jsp similarity index 100% rename from jee-7/src/main/webapp/index.jsp rename to jee-7-security/src/main/webapp/index.jsp diff --git a/jee-7/src/main/webapp/secure.jsp b/jee-7-security/src/main/webapp/secure.jsp similarity index 100% rename from jee-7/src/main/webapp/secure.jsp rename to jee-7-security/src/main/webapp/secure.jsp diff --git a/jee-7/README.md b/jee-7/README.md index 08a180cfa3..a2493e561b 100644 --- a/jee-7/README.md +++ b/jee-7/README.md @@ -5,4 +5,3 @@ - [Introduction to JAX-WS](http://www.baeldung.com/jax-ws) - [A Guide to Java EE Web-Related Annotations](http://www.baeldung.com/javaee-web-annotations) - [Introduction to Testing with Arquillian](http://www.baeldung.com/arquillian) -- [Securing Java EE with Spring Security](http://www.baeldung.com/java-ee-spring-security) diff --git a/jee-7/pom.xml b/jee-7/pom.xml index 62e2132de5..4f6e6a20fb 100644 --- a/jee-7/pom.xml +++ b/jee-7/pom.xml @@ -1,8 +1,7 @@ + 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 jee-7 1.0-SNAPSHOT war @@ -14,29 +13,6 @@ 1.0.0-SNAPSHOT - - ${maven.min.version} - - - - - - org.jboss.arquillian - arquillian-bom - ${arquillian_core.version} - import - pom - - - org.jboss.arquillian.extension - arquillian-drone-bom - ${arquillian-drone-bom.version} - pom - import - - - - javax @@ -154,13 +130,32 @@ maven-war-plugin ${maven-war-plugin.version} - webapp + src/main/webapp false
    + + + + org.jboss.arquillian + arquillian-bom + ${arquillian_core.version} + import + pom + + + org.jboss.arquillian.extension + arquillian-drone-bom + ${arquillian-drone-bom.version} + pom + import + + + + wildfly-managed-arquillian @@ -418,7 +413,7 @@ 1.0.0.Final 2.6 4.2.3.RELEASE - 2.17 + 2.21.0 1.1.2 2.4 2.2.14 diff --git a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java b/jee-7/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java similarity index 94% rename from jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java rename to jee-7/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java index a487d4c3b1..30dc82aa58 100644 --- a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java +++ b/jee-7/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java @@ -1,4 +1,4 @@ -package com.baeldung.javaeeannotations.JavaEEAnnotationsSample.src.main.java.com.baeldung.javaeeannotations; +package com.baeldung.javaeeannotations; import java.io.IOException; import java.io.PrintWriter; diff --git a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java b/jee-7/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java similarity index 82% rename from jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java rename to jee-7/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java index dc9a91d059..ee1b624cd1 100644 --- a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java +++ b/jee-7/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java @@ -1,4 +1,4 @@ -package com.baeldung.javaeeannotations.JavaEEAnnotationsSample.src.main.java.com.baeldung.javaeeannotations; +package com.baeldung.javaeeannotations; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; diff --git a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt deleted file mode 100644 index 0f95e588b8..0000000000 --- a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt +++ /dev/null @@ -1,76 +0,0 @@ -About the application ---------------------- -This application demonstrates the usage of JavaEE Web Annotations. - - -Contents of the application ---------------------------- -1. AccountServlet.java - Demonstrates the @WebServlet and @ServletSecurity annotation. - -NOTES: @WebServlet annotation designates the AccountServlet class as a Servlet component. - The usage of its parameters 'urlPatterns' & 'initParams' can be observed. - An initialization parameter 'type' is being set to denote the type of the bank account. - - @ServletSecurity annotation imposes security constraints on the AccountServlet based on - the tomcat-users.xml. -   - This code assumes that your tomcat-users.xml looks as follows: - - - - - - - -   -N.B : To see @ServletSecurity annotation in action, please uncomment the annotation code - for @ServletSecurity. - - -2. BankAppServletContextListener.java - Demonstrates the @WebListener annotation for denoting a class as a ServletContextListener. - -NOTES: Sets a Servlet context attribute ATTR_DEFAULT_LANGUAGE to 'english' on web application start up, - which can then be used throughout the application. - - -3. LogInFilter.java - Demonstrates the @WebFilter annotation. - -NOTES: @WebFilter annotation designates the LogInFilter class as a Filter component. - It filters all requests to the bank account servlet and redirects them to - the login page. - -N.B : To see @WebFilter annotation in action, please uncomment the annotation code for @WebFilter. - - -4. UploadCustomerDocumentsServlet.java - Demonstrates the @MultipartConfig annotation. - -NOTES: @MultipartConfig anotation designates the UploadCustomerDocumentsServlet Servlet component, - to handle multipart/form-data requests. - To see it in action, deploy the web application an access the url: http://:/JavaEEAnnotationsSample/upload.jsp - Once you upload a file from here, it will get uploaded to D:/custDocs (assuming such a folder exists). - - -5. index.jsp - This is the welcome page. - -NOTES: You can enter a deposit amount here and click on the 'Deposit' button to see the AccountServlet in action. - -6. login.jsp - All requests to the AccountServlet are redirected to this page, if the LogInFilter is imposed. - -7. upload.jsp - Demonstrates the usage of handling multipart/form-data requests by the UploadCustomerDocumentsServlet. - - -Building and Running the application ------------------------------------- -To build the application: - -1. Open the project in eclipse -2. Right click on it in eclispe and choose Run As > Maven build -3. Give 'clean install' under Goals -4. This should build the WAR file of the application - -To run the application: - -1. Right click on the project -2. Run as > Run on Server -3. This will start you Tomcat server and deploy the application (Provided that you have configured Tomcat in your eclipse) -4. You should now be able to access the url : http://:/JavaEEAnnotationsSample diff --git a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml deleted file mode 100644 index 6a0dd05180..0000000000 --- a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml +++ /dev/null @@ -1,52 +0,0 @@ - - 4.0.0 - com.baeldung.javaeeannotations - JavaEEAnnotationsSample - 0.0.1-SNAPSHOT - war - JavaEEAnnotationsSample - JavaEEAnnotationsSample - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - javax.annotation - javax.annotation-api - 1.3 - - - - javax.servlet - javax.servlet-api - 3.1.0 - - - - javax.servlet.jsp - jsp-api - 2.1 - - - - - - - - org.apache.maven.plugins - maven-war-plugin - 2.4 - - src/main/webapp - SpringFieldConstructorInjection - false - - - - - JavaEEAnnotationsSample - - \ No newline at end of file diff --git a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index a92885ec11..0000000000 --- a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - BASIC - default - - diff --git a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp deleted file mode 100644 index 6892cb0420..0000000000 --- a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp +++ /dev/null @@ -1,12 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> - - - - -Login - - -Login Here... - - \ No newline at end of file diff --git a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java b/jee-7/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java similarity index 90% rename from jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java rename to jee-7/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java index bfe1a39377..5ee420f6a2 100644 --- a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java +++ b/jee-7/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java @@ -1,4 +1,4 @@ -package com.baeldung.javaeeannotations.JavaEEAnnotationsSample.src.main.java.com.baeldung.javaeeannotations; +package com.baeldung.javaeeannotations; import java.io.IOException; diff --git a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java b/jee-7/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java similarity index 90% rename from jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java rename to jee-7/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java index 6945f663bb..28922dba46 100644 --- a/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java +++ b/jee-7/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java @@ -1,4 +1,4 @@ -package com.baeldung.javaeeannotations.JavaEEAnnotationsSample.src.main.java.com.baeldung.javaeeannotations; +package com.baeldung.javaeeannotations; import java.io.IOException; import java.io.PrintWriter; diff --git a/jee-7/src/main/java/com/baeldung/springSecurity/ApplicationConfig.java b/jee-7/src/main/java/com/baeldung/springSecurity/ApplicationConfig.java deleted file mode 100755 index f8e7982253..0000000000 --- a/jee-7/src/main/java/com/baeldung/springSecurity/ApplicationConfig.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.springSecurity; - -import javax.ws.rs.ApplicationPath; -import javax.ws.rs.core.Application; - -/** - * Application class required by JAX-RS. If you don't want to have any - * prefix in the URL, you can set the application path to "/". - */ -@ApplicationPath("/") -public class ApplicationConfig extends Application { - -} diff --git a/jee-7/src/main/resources/logback.xml b/jee-7/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jee-7/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jee-7/src/main/webapp/WEB-INF/web.xml b/jee-7/src/main/webapp/WEB-INF/web.xml index 1bcbb96e24..e656ffc5be 100644 --- a/jee-7/src/main/webapp/WEB-INF/web.xml +++ b/jee-7/src/main/webapp/WEB-INF/web.xml @@ -1,5 +1,8 @@ - + - 2.7.3 - - Hello World Plugin - A sample Jenkins Hello World plugin - https://wiki.jenkins-ci.org/display/JENKINS/TODO+Plugin - - - MIT License - http://opensource.org/licenses/MIT - - + org.jenkins-ci.plugins structs - 1.7 + ${structs.version} org.jenkins-ci.plugins.workflow workflow-step-api - 2.12 + ${workflow-step-api.version} test org.jenkins-ci.plugins.workflow workflow-cps - 2.39 + ${workflow-cps.version} test org.jenkins-ci.plugins.workflow workflow-job - 2.11.2 + ${workflow-job.version} test org.jenkins-ci.plugins.workflow workflow-basic-steps - 2.6 + ${workflow-basic-steps.version} test org.jenkins-ci.plugins.workflow workflow-durable-task-step - 2.13 + ${workflow-durable-task-step.version} test org.jenkins-ci.plugins.workflow workflow-api - 2.20 + ${workflow-api.version} test org.jenkins-ci.plugins.workflow workflow-support - 2.14 + ${workflow-support.version} test @@ -86,4 +78,19 @@ https://repo.jenkins-ci.org/public/ + + + + 2.7.3 + + 1.7 + 2.12 + 2.39 + 2.11.2 + 2.6 + 2.13 + 2.20 + 2.14 + + diff --git a/jenkins/hello-world/src/main/resources/logback.xml b/jenkins/hello-world/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jenkins/hello-world/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jersey/README.md b/jersey/README.md index a4c8c52d68..c548a79c6d 100644 --- a/jersey/README.md +++ b/jersey/README.md @@ -1 +1,4 @@ -- [Jersey Filters and Interceptors] (http://www.baeldung.com/jersey-filters-interceptors) +- [Jersey Filters and Interceptors](http://www.baeldung.com/jersey-filters-interceptors) +- [Jersey MVC Support](https://www.baeldung.com/jersey-mvc) +- [Bean Validation in Jersey](https://www.baeldung.com/jersey-bean-validation) +- [Set a Response Body in JAX-RS](https://www.baeldung.com/jax-rs-response) diff --git a/jersey/pom.xml b/jersey/pom.xml index b41ea1f340..b55bdc5330 100644 --- a/jersey/pom.xml +++ b/jersey/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung jersey @@ -31,9 +30,31 @@ ${jersey.version} - org.slf4j - slf4j-api - ${slf4j.version} + org.glassfish.jersey.containers + jersey-container-grizzly2-servlet + ${jersey.version} + + + org.glassfish.jersey.ext + jersey-mvc-freemarker + ${jersey.version} + + + org.glassfish.jersey.ext + jersey-bean-validation + ${jersey.version} + + + org.glassfish.jersey.test-framework + jersey-test-framework-core + ${jersey.version} + test + + + org.glassfish.jersey.test-framework.providers + jersey-test-framework-provider-grizzly2 + ${jersey.version} + test @@ -47,12 +68,18 @@ false
    + + org.codehaus.mojo + exec-maven-plugin + + com.baeldung.jersey.server.http.EmbeddedHttpServer + + 2.26 - 1.7.25 3.2.0 diff --git a/jersey/src/main/java/com/baeldung/jersey/server/Responder.java b/jersey/src/main/java/com/baeldung/jersey/server/Responder.java new file mode 100644 index 0000000000..cb0c976fe3 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/Responder.java @@ -0,0 +1,102 @@ +package com.baeldung.jersey.server; + +import com.baeldung.jersey.server.model.Person; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Path("/response") +public class Responder { + + @GET + @Path("/ok") + public Response getOkResponse() { + + String message = "This is a text response"; + + return Response + .status(Response.Status.OK) + .entity(message) + .build(); + } + + @GET + @Path("/not_ok") + public Response getNOkTextResponse() { + + String message = "There was an internal server error"; + + return Response + .status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(message) + .build(); + } + + @GET + @Path("/text_plain") + public Response getTextResponseTypeDefined() { + + String message = "This is a plain text response"; + + return Response + .status(Response.Status.OK) + .entity(message) + .type(MediaType.TEXT_PLAIN) + .build(); + } + + @GET + @Path("/text_plain_annotation") + @Produces({ MediaType.TEXT_PLAIN }) + public Response getTextResponseTypeAnnotated() { + + String message = "This is a plain text response via annotation"; + + return Response + .status(Response.Status.OK) + .entity(message) + .build(); + } + + @GET + @Path("/pojo") + public Response getPojoResponse() { + + Person person = new Person("Abh", "Nepal"); + + return Response + .status(Response.Status.OK) + .entity(person) + .build(); + } + + @GET + @Path("/json") + public Response getJsonResponse() { + + String message = "{\"hello\": \"This is a JSON response\"}"; + + return Response + .status(Response.Status.OK) + .entity(message) + .type(MediaType.APPLICATION_JSON) + .build(); + } + + @GET + @Path("/xml") + @Produces(MediaType.TEXT_XML) + public String sayXMLHello() { + return "" + " This is a xml response "; + } + + @GET + @Path("/html") + @Produces(MediaType.TEXT_HTML) + public String sayHtmlHello() { + return " " + "" + " This is a html title " + "

    " + " This is a html response body " + "

    " + " "; + } +} \ No newline at end of file diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java b/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java new file mode 100644 index 0000000000..b6b9853aae --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java @@ -0,0 +1,16 @@ +package com.baeldung.jersey.server.config; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.ServerProperties; +import org.glassfish.jersey.server.mvc.freemarker.FreemarkerMvcFeature; + +public class ViewApplicationConfig extends ResourceConfig { + + public ViewApplicationConfig() { + packages("com.baeldung.jersey.server"); + property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true); + property(FreemarkerMvcFeature.TEMPLATE_BASE_PATH, "templates/freemarker"); + register(FreemarkerMvcFeature.class);; + } + +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java b/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java new file mode 100644 index 0000000000..ca49797e31 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java @@ -0,0 +1,35 @@ +package com.baeldung.jersey.server.constraints; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.regex.Pattern; + +import javax.validation.Constraint; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import javax.validation.Payload; + +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = { SerialNumber.Validator.class }) +public @interface SerialNumber { + + String message() + + default "Fruit serial number is not valid"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + public class Validator implements ConstraintValidator { + @Override + public void initialize(final SerialNumber serial) { + } + + @Override + public boolean isValid(final String serial, final ConstraintValidatorContext constraintValidatorContext) { + final String serialNumRegex = "^\\d{3}-\\d{3}-\\d{4}$"; + return Pattern.matches(serialNumRegex, serial); + } + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java b/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java new file mode 100644 index 0000000000..4afa086858 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java @@ -0,0 +1,35 @@ +package com.baeldung.jersey.server.http; + +import java.io.IOException; +import java.net.URI; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.glassfish.grizzly.http.server.HttpServer; +import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; + +import com.baeldung.jersey.server.config.ViewApplicationConfig; + +public class EmbeddedHttpServer { + + private static final URI BASE_URI = URI.create("http://localhost:8082/"); + + public static void main(String[] args) { + try { + final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, new ViewApplicationConfig(), false); + + Runtime.getRuntime() + .addShutdownHook(new Thread(() -> { + server.shutdownNow(); + })); + + server.start(); + + System.out.println(String.format("Application started.\nTry out %s\nStop the application using CTRL+C", BASE_URI + "fruit")); + } catch (IOException ex) { + Logger.getLogger(EmbeddedHttpServer.class.getName()) + .log(Level.SEVERE, null, ex); + } + + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java b/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java new file mode 100644 index 0000000000..1a648290a3 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java @@ -0,0 +1,62 @@ +package com.baeldung.jersey.server.model; + +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Fruit { + + @Min(value = 10, message = "Fruit weight must be 10 or greater") + private Integer weight; + @Size(min = 5, max = 200) + private String name; + @Size(min = 5, max = 200) + private String colour; + private String serial; + + public Fruit() { + } + + public Fruit(String name, String colour) { + this.name = name; + this.colour = colour; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setColour(String colour) { + this.colour = colour; + } + + public String getColour() { + return colour; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getSerial() { + return serial; + } + + public void setSerial(String serial) { + this.serial = serial; + } + + @Override + public String toString() { + return "Fruit [name: " + getName() + " colour: " + getColour() + "]"; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/model/Person.java b/jersey/src/main/java/com/baeldung/jersey/server/model/Person.java new file mode 100644 index 0000000000..98c86bbc3d --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/model/Person.java @@ -0,0 +1,32 @@ +package com.baeldung.jersey.server.model; + +public class Person { + String name; + String address; + + public Person(String name, String address) { + this.name = name; + this.address = address; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + @Override + public String toString() { + return "Person [name: " + getName() + " address: " + getAddress() + "]"; + } +} \ No newline at end of file diff --git a/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java b/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java new file mode 100644 index 0000000000..cea61c897b --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java @@ -0,0 +1,26 @@ +package com.baeldung.jersey.server.providers; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +public class FruitExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(final ConstraintViolationException exception) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(prepareMessage(exception)) + .type("text/plain") + .build(); + } + + private String prepareMessage(ConstraintViolationException exception) { + final StringBuilder message = new StringBuilder(); + for (ConstraintViolation cv : exception.getConstraintViolations()) { + message.append(cv.getPropertyPath() + " " + cv.getMessage() + "\n"); + } + return message.toString(); + } + +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java b/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java new file mode 100644 index 0000000000..88692dcc55 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java @@ -0,0 +1,120 @@ +package com.baeldung.jersey.server.rest; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +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.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.glassfish.jersey.server.mvc.ErrorTemplate; +import org.glassfish.jersey.server.mvc.Template; +import org.glassfish.jersey.server.mvc.Viewable; + +import com.baeldung.jersey.server.constraints.SerialNumber; +import com.baeldung.jersey.server.model.Fruit; +import com.baeldung.jersey.service.SimpleStorageService; + +@Path("/fruit") +public class FruitResource { + + @GET + public Viewable get() { + return new Viewable("/index.ftl", "Fruit Index Page"); + } + + @GET + @Template(name = "/all.ftl") + @Path("/all") + @Produces(MediaType.TEXT_HTML) + public Map getAllFruit() { + final List fruits = new ArrayList<>(); + fruits.add(new Fruit("banana", "yellow")); + fruits.add(new Fruit("apple", "red")); + fruits.add(new Fruit("kiwi", "green")); + + final Map model = new HashMap(); + model.put("items", fruits); + return model; + } + + @GET + @ErrorTemplate(name = "/error.ftl") + @Template(name = "/named.ftl") + @Path("{name}") + @Produces(MediaType.TEXT_HTML) + public String getFruitByName(@PathParam("name") String name) { + if (!"banana".equalsIgnoreCase(name)) { + throw new IllegalArgumentException("Fruit not found: " + name); + } + return name; + } + + @POST + @Path("/create") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public void createFruit( + @NotNull(message = "Fruit name must not be null") @FormParam("name") String name, + @NotNull(message = "Fruit colour must not be null") @FormParam("colour") String colour) { + + Fruit fruit = new Fruit(name, colour); + SimpleStorageService.storeFruit(fruit); + } + + @PUT + @Path("/update") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public void updateFruit(@SerialNumber @FormParam("serial") String serial) { + Fruit fruit = new Fruit(); + fruit.setSerial(serial); + SimpleStorageService.storeFruit(fruit); + } + + @POST + @Path("/create") + @Consumes(MediaType.APPLICATION_JSON) + public void createFruit(@Valid Fruit fruit) { + SimpleStorageService.storeFruit(fruit); + } + + @POST + @Path("/created") + @Consumes(MediaType.APPLICATION_JSON) + public Response createNewFruit(@Valid Fruit fruit) { + String result = "Fruit saved : " + fruit; + return Response.status(Status.CREATED.getStatusCode()) + .entity(result) + .build(); + } + + @GET + @Valid + @Produces(MediaType.APPLICATION_JSON) + @Path("/search/{name}") + public Fruit findFruitByName(@PathParam("name") String name) { + return SimpleStorageService.findByName(name); + } + + @GET + @Produces(MediaType.TEXT_HTML) + @Path("/exception") + @Valid + public Fruit exception() { + Fruit fruit = new Fruit(); + fruit.setName("a"); + fruit.setColour("b"); + return fruit; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java b/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java new file mode 100644 index 0000000000..e21dd584a1 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java @@ -0,0 +1,25 @@ +package com.baeldung.jersey.service; + +import java.util.HashMap; +import java.util.Map; + +import com.baeldung.jersey.server.model.Fruit; + +public class SimpleStorageService { + + private static final Map fruits = new HashMap(); + + public static void storeFruit(final Fruit fruit) { + fruits.put(fruit.getName(), fruit); + } + + public static Fruit findByName(final String name) { + return fruits.entrySet() + .stream() + .filter(map -> name.equals(map.getKey())) + .map(map -> map.getValue()) + .findFirst() + .get(); + } + +} diff --git a/jersey/src/main/resources/logback.xml b/jersey/src/main/resources/logback.xml index d87a87bf53..7d900d8ea8 100644 --- a/jersey/src/main/resources/logback.xml +++ b/jersey/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/jersey/src/main/resources/templates/freemarker/all.ftl b/jersey/src/main/resources/templates/freemarker/all.ftl new file mode 100644 index 0000000000..59406a60ca --- /dev/null +++ b/jersey/src/main/resources/templates/freemarker/all.ftl @@ -0,0 +1,14 @@ + + + All fruit! + + +

    All fruit!

    +

    Fruits:

    +
      + <#list items as fruit> +
    • ${fruit.name}
    • + +
    + + \ No newline at end of file diff --git a/jersey/src/main/resources/templates/freemarker/error.ftl b/jersey/src/main/resources/templates/freemarker/error.ftl new file mode 100644 index 0000000000..8ea6828ba5 --- /dev/null +++ b/jersey/src/main/resources/templates/freemarker/error.ftl @@ -0,0 +1,8 @@ + + + Welcome! + + +

    Error - ${model.message}!

    + + \ No newline at end of file diff --git a/jersey/src/main/resources/templates/freemarker/index.ftl b/jersey/src/main/resources/templates/freemarker/index.ftl new file mode 100644 index 0000000000..01447f24e8 --- /dev/null +++ b/jersey/src/main/resources/templates/freemarker/index.ftl @@ -0,0 +1,8 @@ + + + Welcome! + + +

    Welcome ${model}!

    + + \ No newline at end of file diff --git a/jersey/src/main/resources/templates/freemarker/named.ftl b/jersey/src/main/resources/templates/freemarker/named.ftl new file mode 100644 index 0000000000..ccde3307e6 --- /dev/null +++ b/jersey/src/main/resources/templates/freemarker/named.ftl @@ -0,0 +1,8 @@ + + + Welcome! + + +

    Found fruit - ${model}!

    + + \ No newline at end of file diff --git a/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java b/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java new file mode 100644 index 0000000000..8953f4161c --- /dev/null +++ b/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.jersey.server; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.core.Application; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.test.JerseyTest; +import org.junit.Test; + +public class GreetingsResourceIntegrationTest extends JerseyTest { + + @Override + protected Application configure() { + return new ResourceConfig(Greetings.class); + } + + @Test + public void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() { + Response response = target("/greetings/hi").request() + .get(); + + assertEquals("Http Response should be 200: ", Status.OK.getStatusCode(), response.getStatus()); + assertEquals("Http Content-Type should be: ", MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE)); + + String content = response.readEntity(String.class); + assertEquals("Content of ressponse is: ", "hi", content); + } +} diff --git a/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java b/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java new file mode 100644 index 0000000000..376c8c1e75 --- /dev/null +++ b/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java @@ -0,0 +1,144 @@ +package com.baeldung.jersey.server.rest; + +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.TestProperties; +import org.junit.Test; + +import com.baeldung.jersey.server.config.ViewApplicationConfig; +import com.baeldung.jersey.server.model.Fruit; +import com.baeldung.jersey.server.providers.FruitExceptionMapper; + +public class FruitResourceIntegrationTest extends JerseyTest { + + @Override + protected Application configure() { + enable(TestProperties.LOG_TRAFFIC); + enable(TestProperties.DUMP_ENTITY); + + ViewApplicationConfig config = new ViewApplicationConfig(); + config.register(FruitExceptionMapper.class); + return config; + } + + @Test + public void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() { + final String response = target("/fruit/all").request() + .get(String.class); + assertThat(response, allOf(containsString("banana"), containsString("apple"), containsString("kiwi"))); + } + + @Test + public void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() { + final String response = target("/fruit").request() + .get(String.class); + assertThat(response, containsString("Welcome Fruit Index Page!")); + } + + @Test + public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() { + final String response = target("/fruit/orange").request() + .get(String.class); + assertThat(response, containsString("Error - Fruit not found: orange!")); + } + + @Test + public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() { + Form form = new Form(); + form.param("name", "apple"); + form.param("colour", null); + Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED) + .post(Entity.form(form)); + + assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null")); + } + + @Test + public void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() { + Response response = target("fruit/created").request() + .post(Entity.json("{\"name\":\"strawberry\",\"weight\":20}")); + + assertEquals("Http Response should be 201 ", Status.CREATED.getStatusCode(), response.getStatus()); + assertThat(response.readEntity(String.class), containsString("Fruit saved : Fruit [name: strawberry colour: null]")); + } + + @Test + public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() { + Form form = new Form(); + form.param("serial", "2345-2345"); + + Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED) + .put(Entity.form(form)); + + assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid")); + } + + @Test + public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() { + Fruit fruit = new Fruit("Blueberry", "purple"); + fruit.setWeight(1); + + Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); + + assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater")); + } + + @Test + public void givenFruitExists_whenSearching_thenResponseContainsFruit() { + Fruit fruit = new Fruit(); + fruit.setName("strawberry"); + fruit.setWeight(20); + Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); + + assertEquals("Http Response should be 204 ", 204, response.getStatus()); + + final String json = target("fruit/search/strawberry").request() + .get(String.class); + assertThat(json, containsString("{\"name\":\"strawberry\",\"weight\":20}")); + } + + @Test + public void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() { + Fruit fruit = new Fruit(); + fruit.setName("strawberry"); + fruit.setWeight(20); + Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); + + assertEquals("Http Response should be 204 ", 204, response.getStatus()); + + final Fruit entity = target("fruit/search/strawberry").request() + .get(Fruit.class); + + assertEquals("Fruit name: ", "strawberry", entity.getName()); + assertEquals("Fruit weight: ", Integer.valueOf(20), entity.getWeight()); + } + + @Test + public void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() { + final Response response = target("fruit/exception").request() + .get(); + + assertEquals("Http Response should be 400 ", 400, response.getStatus()); + String responseString = response.readEntity(String.class); + assertThat(responseString, containsString("exception..colour size must be between 5 and 200")); + assertThat(responseString, containsString("exception..name size must be between 5 and 200")); + } + +} diff --git a/jgroups/pom.xml b/jgroups/pom.xml index 6340e41565..34bdd59919 100644 --- a/jgroups/pom.xml +++ b/jgroups/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jgroups 0.1-SNAPSHOT @@ -28,7 +28,6 @@ - UTF-8 4.0.10.Final diff --git a/jgroups/src/main/resources/logback.xml b/jgroups/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jgroups/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jhipster/jhipster-microservice/car-app/pom.xml b/jhipster/jhipster-microservice/car-app/pom.xml index e5593bdbb9..b05979b9c5 100644 --- a/jhipster/jhipster-microservice/car-app/pom.xml +++ b/jhipster/jhipster-microservice/car-app/pom.xml @@ -3,17 +3,15 @@ 4.0.0 - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../../parent-boot-1 + jhipster-microservice + com.baeldung.jhipster + 1.0.0-SNAPSHOT com.car.app - carapp - 0.0.1-SNAPSHOT + car-app war - Carapp + car-app ${maven.version} @@ -37,9 +35,11 @@ 0.7.0 3.6 2.0.0 + 3.6.2 4.8 jdt_apt 1.1.0.Final + 2.10 1.4.1 3.0.1 yyyyMMddHHmmss @@ -47,8 +47,8 @@ 3.1.3 v6.10.0 - - + + ${project.build.directory}/test-results 0.0.20 @@ -61,13 +61,15 @@ S3437,UndocumentedApi,BoldAndItalicTagsCheck - + src/main/webapp/app/**/*.* Web:BoldAndItalicTagsCheck src/main/java/**/* squid:S3437 - + src/main/java/**/* squid:UndocumentedApi @@ -184,12 +186,10 @@ commons-io commons-io - ${commons-io.version} io.dropwizard.metrics metrics-annotation - ${dropwizard-metrics.version} io.dropwizard.metrics @@ -198,17 +198,14 @@ io.dropwizard.metrics metrics-json - ${dropwizard-metrics.version} io.dropwizard.metrics metrics-jvm - ${dropwizard-metrics.version} io.dropwizard.metrics metrics-servlet - ${dropwizard-metrics.version} io.dropwizard.metrics @@ -399,8 +396,7 @@ org.springframework.cloud spring-cloud-starter-ribbon - + netty-transport-native-epoll @@ -428,15 +424,13 @@ + spring-boot:run - + org.eclipse.m2e lifecycle-mapping @@ -454,7 +448,7 @@ - + @@ -506,8 +500,6 @@ maven-compiler-plugin ${maven-compiler-plugin.version} - 1.8 - 1.8 org.mapstruct @@ -520,6 +512,7 @@ org.apache.maven.plugins maven-eclipse-plugin + ${maven-eclipse-plugin.version} true true @@ -657,9 +650,9 @@ src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml org.h2.Driver jdbc:h2:file:./target/h2db/db/carapp - + carapp - + hibernate:spring:com.car.app.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy true debug @@ -676,15 +669,13 @@ true true - + + no-liquibase @@ -708,7 +699,7 @@ org.apache.maven.plugins maven-war-plugin - + @@ -747,7 +738,7 @@ org.apache.maven.plugins maven-war-plugin - + org.springframework.boot @@ -779,15 +770,9 @@ - + cc @@ -847,10 +832,7 @@ true true true - +
    @@ -874,9 +856,7 @@ - + graphite @@ -886,9 +866,7 @@ - + prometheus @@ -909,11 +887,7 @@ - + IDE diff --git a/jhipster/jhipster-microservice/dealer-app/pom.xml b/jhipster/jhipster-microservice/dealer-app/pom.xml index 3c21e0042f..803a0f62e6 100644 --- a/jhipster/jhipster-microservice/dealer-app/pom.xml +++ b/jhipster/jhipster-microservice/dealer-app/pom.xml @@ -3,17 +3,15 @@ 4.0.0 - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../../parent-boot-1 + jhipster-microservice + com.baeldung.jhipster + 1.0.0-SNAPSHOT com.dealer.app - dealerapp - 0.0.1-SNAPSHOT + dealer-app war - Dealerapp + dealer-app ${maven.version} @@ -30,16 +28,17 @@ 5.2.8.Final 2.6.0 0.7.9 - 1.8 3.21.0-GA 1.0.0 1.1.0 0.7.0 3.6 2.0.0 + 3.6.2 4.8 jdt_apt 1.1.0.Final + 2.10 1.4.1 3.0.1 yyyyMMddHHmmss @@ -47,11 +46,11 @@ 3.1.3 v6.10.0 - - - 0.0.20 + + ${project.build.directory}/test-results + 0.0.20 false 3.2.2 2.12.1 @@ -61,13 +60,15 @@ S3437,UndocumentedApi,BoldAndItalicTagsCheck - + src/main/webapp/app/**/*.* Web:BoldAndItalicTagsCheck src/main/java/**/* squid:S3437 - + src/main/java/**/* squid:UndocumentedApi @@ -107,39 +108,6 @@ - - io.github.jhipster - jhipster - ${jhipster.server.version} - - - io.dropwizard.metrics - metrics-core - - - io.dropwizard.metrics - metrics-annotation - ${dropwizard-metrics.version} - - - io.dropwizard.metrics - metrics-json - ${dropwizard-metrics.version} - - - io.dropwizard.metrics - metrics-jvm - ${dropwizard-metrics.version} - - - io.dropwizard.metrics - metrics-servlet - ${dropwizard-metrics.version} - - - io.dropwizard.metrics - metrics-servlets - com.fasterxml.jackson.datatype jackson-datatype-hibernate5 @@ -150,11 +118,11 @@ com.fasterxml.jackson.datatype - jackson-datatype-jsr310 + jackson-datatype-json-org com.fasterxml.jackson.datatype - jackson-datatype-json-org + jackson-datatype-jsr310 com.h2database @@ -173,34 +141,12 @@ com.hazelcast hazelcast-spring - - org.awaitility - awaitility - ${awaitility.version} - test - com.jayway.jsonpath json-path test - - io.springfox - springfox-swagger2 - ${springfox.version} - - - org.mapstruct - mapstruct - - - - - io.springfox - springfox-bean-validators - ${springfox.version} - com.mattbertolini liquibase-slf4j @@ -212,16 +158,16 @@ ${metrics-spring.version} - com.codahale.metrics metrics-annotation + com.codahale.metrics - com.codahale.metrics metrics-core + com.codahale.metrics - com.codahale.metrics metrics-healthchecks + com.codahale.metrics @@ -239,12 +185,56 @@ commons-io commons-io - ${commons-io.version} - org.apache.commons - commons-lang3 - ${commons-lang.version} + io.dropwizard.metrics + metrics-annotation + + + io.dropwizard.metrics + metrics-core + + + io.dropwizard.metrics + metrics-json + + + io.dropwizard.metrics + metrics-jvm + + + io.dropwizard.metrics + metrics-servlet + + + io.dropwizard.metrics + metrics-servlets + + + io.github.jhipster + jhipster + ${jhipster.server.version} + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + io.springfox + springfox-bean-validators + ${springfox.version} + + + io.springfox + springfox-swagger2 + ${springfox.version} + + + mapstruct + org.mapstruct + + javax.cache @@ -254,11 +244,41 @@ mysql mysql-connector-java + + net.logstash.logback + logstash-logback-encoder + ${logstash-logback-encoder.version} + + + logback-core + ch.qos.logback + + + logback-classic + ch.qos.logback + + + logback-access + ch.qos.logback + + + + + org.apache.commons + commons-lang3 + ${commons-lang.version} + org.assertj assertj-core test + + org.awaitility + awaitility + ${awaitility.version} + test + org.hibernate hibernate-envers @@ -307,6 +327,10 @@ org.springframework.boot spring-boot-starter-aop + + org.springframework.boot + spring-boot-starter-cloud-connectors + org.springframework.boot spring-boot-starter-data-jpa @@ -323,16 +347,6 @@ org.springframework.boot spring-boot-starter-security - - org.springframework.security - spring-security-test - test - - - org.springframework.boot - spring-boot-test - test - org.springframework.boot spring-boot-starter-thymeleaf @@ -342,15 +356,15 @@ spring-boot-starter-web - org.springframework.boot spring-boot-starter-tomcat + org.springframework.boot - io.jsonwebtoken - jjwt - ${jjwt.version} + org.springframework.boot + spring-boot-test + test @@ -359,20 +373,31 @@ org.springframework.cloud - spring-cloud-starter-ribbon - - - - io.netty - netty-transport-native-epoll - - + spring-cloud-starter-config + + + org.springframework.cloud + spring-cloud-starter-eureka + + + org.springframework.cloud + spring-cloud-starter-feign org.springframework.cloud spring-cloud-starter-hystrix + + org.springframework.cloud + spring-cloud-starter-ribbon + + + + netty-transport-native-epoll + io.netty + + + org.springframework.cloud spring-cloud-starter-spectator @@ -381,50 +406,51 @@ org.springframework.retry spring-retry - - org.springframework.cloud - spring-cloud-starter-eureka - - - org.springframework.cloud - spring-cloud-starter-config - - - org.springframework.cloud - spring-cloud-starter-feign - - - net.logstash.logback - logstash-logback-encoder - ${logstash-logback-encoder.version} - - - ch.qos.logback - logback-core - - - ch.qos.logback - logback-classic - - - ch.qos.logback - logback-access - - - - - org.springframework.boot - spring-boot-starter-cloud-connectors - org.springframework.security spring-security-data + + org.springframework.security + spring-security-test + test + + spring-boot:run + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + prepare-agent + + + + + + + + + + + + com.github.ekryd.sortpom @@ -447,6 +473,22 @@ false + + com.spotify + docker-maven-plugin + ${docker-maven-plugin.version} + + dealerapp + src/main/docker + + + / + ${project.build.directory} + ${project.build.finalName}.war + + + + org.apache.maven.plugins maven-compiler-plugin @@ -464,6 +506,7 @@ org.apache.maven.plugins maven-eclipse-plugin + ${maven-eclipse-plugin.version} true true @@ -570,28 +613,16 @@ - - org.sonarsource.scanner.maven - sonar-maven-plugin - ${sonar-maven-plugin.version} - org.liquibase liquibase-maven-plugin ${liquibase.version} - - src/main/resources/config/liquibase/master.xml - src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml - org.h2.Driver - jdbc:h2:file:./target/h2db/db/dealerapp - - dealerapp - - hibernate:spring:com.dealer.app.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy - true - debug - + + javax.validation + validation-api + ${validation-api.version} + org.javassist javassist @@ -607,12 +638,24 @@ spring-boot-starter-data-jpa ${project.parent.version} - - javax.validation - validation-api - ${validation-api.version} - + + src/main/resources/config/liquibase/master.xml + src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml + org.h2.Driver + jdbc:h2:file:./target/h2db/db/dealerapp + + dealerapp + + hibernate:spring:com.dealer.app.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy + true + debug + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + ${sonar-maven-plugin.version} org.springframework.boot @@ -620,68 +663,13 @@ true true - - - - - com.spotify - docker-maven-plugin - ${docker-maven-plugin.version} - - dealerapp - src/main/docker - - - / - ${project.build.directory} - ${project.build.finalName}.war - - + - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.jacoco - - jacoco-maven-plugin - - - ${jacoco-maven-plugin.version} - - - prepare-agent - - - - - - - - - - - - + no-liquibase @@ -700,24 +688,12 @@ true - - - org.springframework.boot - spring-boot-starter-undertow - - - org.springframework.boot - spring-boot-devtools - true - - org.apache.maven.plugins maven-war-plugin - - + @@ -727,15 +703,20 @@ dev${profile.no-liquibase} - - - prod + + org.springframework.boot + spring-boot-devtools + true + org.springframework.boot spring-boot-starter-undertow + + + prod @@ -751,15 +732,11 @@ org.apache.maven.plugins maven-war-plugin - - + org.springframework.boot spring-boot-maven-plugin - - true - @@ -767,6 +744,9 @@ + + true + @@ -776,65 +756,20 @@ prod${profile.swagger}${profile.no-liquibase} - - - - cc org.springframework.boot spring-boot-starter-undertow - - org.springframework.boot - spring-boot-devtools - true - + + + + cc - - org.apache.maven.plugins - maven-war-plugin - - src/main/webapp/ - - - - org.springframework.boot - spring-boot-maven-plugin - - true - true - true - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - default-compile - none - - - default-testCompile - none - - - net.alchim31.maven scala-maven-plugin @@ -863,6 +798,37 @@ ${scala.version} + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + none + + + default-testCompile + none + + + + + org.apache.maven.plugins + maven-war-plugin + + src/main/webapp/ + + + + org.springframework.boot + spring-boot-maven-plugin + + true + true + true + + + @@ -871,11 +837,20 @@ dev,swagger + + + org.springframework.boot + spring-boot-devtools + true + + + org.springframework.boot + spring-boot-starter-undertow + + - + graphite @@ -885,9 +860,7 @@ - + prometheus @@ -897,22 +870,18 @@ io.prometheus - simpleclient_servlet + simpleclient_dropwizard ${prometheus-simpleclient.version} io.prometheus - simpleclient_dropwizard + simpleclient_servlet ${prometheus-simpleclient.version} - + IDE @@ -923,4 +892,5 @@ + diff --git a/jhipster/jhipster-microservice/gateway-app/package.json b/jhipster/jhipster-microservice/gateway-app/package.json index ece70314ab..abdff9ffe3 100644 --- a/jhipster/jhipster-microservice/gateway-app/package.json +++ b/jhipster/jhipster-microservice/gateway-app/package.json @@ -49,7 +49,7 @@ "karma-phantomjs-launcher": "1.0.2", "karma-script-launcher": "1.0.0", "lazypipe": "1.0.1", - "lodash": "4.15.0", + "lodash": "4.17.10", "main-bower-files": "2.13.1", "map-stream": "0.0.6", "phantomjs-prebuilt": "2.1.12", diff --git a/jhipster/jhipster-microservice/gateway-app/pom.xml b/jhipster/jhipster-microservice/gateway-app/pom.xml index 42808e26ce..ed0c929027 100644 --- a/jhipster/jhipster-microservice/gateway-app/pom.xml +++ b/jhipster/jhipster-microservice/gateway-app/pom.xml @@ -3,17 +3,15 @@ 4.0.0 - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../../parent-boot-1 + jhipster-microservice + com.baeldung.jhipster + 1.0.0-SNAPSHOT com.gateway - gateway - 0.0.1-SNAPSHOT + gateway-app war - Gateway + gateway-app ${maven.version} @@ -23,6 +21,7 @@ -Djava.security.egd=file:/dev/./urandom -Xmx256m 3.6.2 2.0.0 + 3.6.0 1.10 2.5 3.5 @@ -38,10 +37,12 @@ 0.7.0 3.6 2.0.0 + 3.6.2 4.8 1.3.0 jdt_apt 1.1.0.Final + 2.10 1.4.1 3.0.1 yyyyMMddHHmmss @@ -49,11 +50,11 @@ 3.1.3 v6.10.0 - - - 0.0.20 + + ${project.build.directory}/test-results + 0.0.20 false 3.2.2 2.12.1 @@ -63,13 +64,15 @@ S3437,UndocumentedApi,BoldAndItalicTagsCheck - + src/main/webapp/app/**/*.* Web:BoldAndItalicTagsCheck src/main/java/**/* squid:S3437 - + src/main/java/**/* squid:UndocumentedApi @@ -109,38 +112,25 @@ + - io.github.jhipster - jhipster - ${jhipster.server.version} + com.datastax.cassandra + cassandra-driver-core + + + metrics-core + com.codahale.metrics + + - io.dropwizard.metrics - metrics-core + com.datastax.cassandra + cassandra-driver-extras + ${cassandra-driver.version} - io.dropwizard.metrics - metrics-annotation - ${dropwizard-metrics.version} - - - io.dropwizard.metrics - metrics-json - ${dropwizard-metrics.version} - - - io.dropwizard.metrics - metrics-jvm - ${dropwizard-metrics.version} - - - io.dropwizard.metrics - metrics-servlet - ${dropwizard-metrics.version} - - - io.dropwizard.metrics - metrics-servlets + com.datastax.cassandra + cassandra-driver-mapping com.fasterxml.jackson.datatype @@ -152,11 +142,11 @@ com.fasterxml.jackson.datatype - jackson-datatype-jsr310 + jackson-datatype-json-org com.fasterxml.jackson.datatype - jackson-datatype-json-org + jackson-datatype-jsr310 com.h2database @@ -175,34 +165,12 @@ com.hazelcast hazelcast-spring - - org.awaitility - awaitility - ${awaitility.version} - test - com.jayway.jsonpath json-path test - - io.springfox - springfox-swagger2 - ${springfox.version} - - - org.mapstruct - mapstruct - - - - - io.springfox - springfox-bean-validators - ${springfox.version} - com.mattbertolini liquibase-slf4j @@ -214,16 +182,16 @@ ${metrics-spring.version} - com.codahale.metrics metrics-annotation + com.codahale.metrics - com.codahale.metrics metrics-core + com.codahale.metrics - com.codahale.metrics metrics-healthchecks + com.codahale.metrics @@ -241,17 +209,60 @@ commons-codec commons-codec - ${commons-codec.version} commons-io commons-io - ${commons-io.version} - org.apache.commons - commons-lang3 - ${commons-lang.version} + io.dropwizard.metrics + metrics-annotation + + + io.dropwizard.metrics + metrics-core + + + io.dropwizard.metrics + metrics-json + + + io.dropwizard.metrics + metrics-jvm + + + io.dropwizard.metrics + metrics-servlet + + + io.dropwizard.metrics + metrics-servlets + + + io.github.jhipster + jhipster + ${jhipster.server.version} + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + io.springfox + springfox-bean-validators + ${springfox.version} + + + io.springfox + springfox-swagger2 + ${springfox.version} + + + mapstruct + org.mapstruct + + javax.cache @@ -266,11 +277,41 @@ lz4 ${lz4.version} + + net.logstash.logback + logstash-logback-encoder + ${logstash-logback-encoder.version} + + + logback-core + ch.qos.logback + + + logback-classic + ch.qos.logback + + + logback-access + ch.qos.logback + + + + + org.apache.commons + commons-lang3 + ${commons-lang.version} + org.assertj assertj-core test + + org.awaitility + awaitility + ${awaitility.version} + test + org.hibernate hibernate-envers @@ -319,6 +360,10 @@ org.springframework.boot spring-boot-starter-aop + + org.springframework.boot + spring-boot-starter-cloud-connectors + org.springframework.boot spring-boot-starter-data-jpa @@ -340,16 +385,6 @@ spring-boot-starter-test test - - org.springframework.security - spring-security-test - test - - - org.springframework.boot - spring-boot-test - test - org.springframework.boot spring-boot-starter-thymeleaf @@ -359,40 +394,15 @@ spring-boot-starter-web - org.springframework.boot spring-boot-starter-tomcat + org.springframework.boot - io.jsonwebtoken - jjwt - ${jjwt.version} - - - - com.datastax.cassandra - cassandra-driver-core - - - com.codahale.metrics - metrics-core - - - - - com.datastax.cassandra - cassandra-driver-extras - ${cassandra-driver.version} - - - com.datastax.cassandra - cassandra-driver-mapping - - - - org.springframework.cloud - spring-cloud-starter-zuul + org.springframework.boot + spring-boot-test + test org.springframework.cloud @@ -400,72 +410,105 @@ org.springframework.cloud - spring-cloud-starter-ribbon - - - - io.netty - netty-transport-native-epoll - - - - - org.springframework.cloud - spring-cloud-starter-hystrix - - - org.springframework.cloud - spring-cloud-starter-spectator - - - org.springframework.retry - spring-retry + spring-cloud-starter-config org.springframework.cloud spring-cloud-starter-eureka - - org.springframework.cloud - spring-cloud-starter-config - org.springframework.cloud spring-cloud-starter-feign - net.logstash.logback - logstash-logback-encoder - ${logstash-logback-encoder.version} + org.springframework.cloud + spring-cloud-starter-hystrix + + + org.springframework.cloud + spring-cloud-starter-ribbon + - ch.qos.logback - logback-core - - - ch.qos.logback - logback-classic - - - ch.qos.logback - logback-access + netty-transport-native-epoll + io.netty - org.springframework.boot - spring-boot-starter-cloud-connectors + org.springframework.cloud + spring-cloud-starter-spectator + + + + org.springframework.cloud + spring-cloud-starter-zuul + + + org.springframework.retry + spring-retry org.springframework.security spring-security-data + + org.springframework.security + spring-security-test + test + + spring-boot:run + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + prepare-agent + + + + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + install-node-and-yarn + yarn + bower + gulp + + + + + + + + + + + + com.github.ekryd.sortpom @@ -488,6 +531,22 @@ false + + com.spotify + docker-maven-plugin + ${docker-maven-plugin.version} + + gateway + src/main/docker + + + / + ${project.build.directory} + ${project.build.finalName}.war + + + + org.apache.maven.plugins maven-compiler-plugin @@ -505,6 +564,7 @@ org.apache.maven.plugins maven-eclipse-plugin + ${maven-eclipse-plugin.version} true true @@ -611,28 +671,16 @@ - - org.sonarsource.scanner.maven - sonar-maven-plugin - ${sonar-maven-plugin.version} - org.liquibase liquibase-maven-plugin ${liquibase.version} - - src/main/resources/config/liquibase/master.xml - src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml - org.h2.Driver - jdbc:h2:file:./target/h2db/db/gateway - - gateway - - hibernate:spring:com.gateway.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy - true - debug - + + javax.validation + validation-api + ${validation-api.version} + org.javassist javassist @@ -648,12 +696,24 @@ spring-boot-starter-data-jpa ${project.parent.version} - - javax.validation - validation-api - ${validation-api.version} - + + src/main/resources/config/liquibase/master.xml + src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml + org.h2.Driver + jdbc:h2:file:./target/h2db/db/gateway + + gateway + + hibernate:spring:com.gateway.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy + true + debug + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + ${sonar-maven-plugin.version} org.springframework.boot @@ -661,84 +721,13 @@ true true - - - - - com.spotify - docker-maven-plugin - ${docker-maven-plugin.version} - - gateway - src/main/docker - - - / - ${project.build.directory} - ${project.build.finalName}.war - - + - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.jacoco - - jacoco-maven-plugin - - - ${jacoco-maven-plugin.version} - - - prepare-agent - - - - - - - - - com.github.eirslett - frontend-maven-plugin - ${frontend-maven-plugin.version} - - install-node-and-yarn - yarn - bower - gulp - - - - - - - - - - - - + no-liquibase @@ -757,17 +746,6 @@ true - - - org.springframework.boot - spring-boot-starter-undertow - - - org.springframework.boot - spring-boot-devtools - true - - @@ -785,48 +763,22 @@ dev${profile.no-liquibase} - - - prod + + org.springframework.boot + spring-boot-devtools + true + org.springframework.boot spring-boot-starter-undertow + + + prod - - maven-clean-plugin - - - - target/www/ - - - - - - org.apache.maven.plugins - maven-war-plugin - - target/www/ - - - - org.springframework.boot - spring-boot-maven-plugin - - true - - - - - build-info - - - - com.github.eirslett frontend-maven-plugin @@ -871,16 +823,47 @@ gulp test + test gulp - test test --no-notification + + maven-clean-plugin + + + + target/www/ + + + + + + org.apache.maven.plugins + maven-war-plugin + + target/www/ + + + + org.springframework.boot + spring-boot-maven-plugin + + + + build-info + + + + + true + + @@ -889,65 +872,20 @@ prod${profile.swagger}${profile.no-liquibase} - - - - cc org.springframework.boot spring-boot-starter-undertow - - org.springframework.boot - spring-boot-devtools - true - + + + + cc - - org.apache.maven.plugins - maven-war-plugin - - src/main/webapp/ - - - - org.springframework.boot - spring-boot-maven-plugin - - true - true - true - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - default-compile - none - - - default-testCompile - none - - - net.alchim31.maven scala-maven-plugin @@ -976,6 +914,37 @@ ${scala.version} + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + none + + + default-testCompile + none + + + + + org.apache.maven.plugins + maven-war-plugin + + src/main/webapp/ + + + + org.springframework.boot + spring-boot-maven-plugin + + true + true + true + + + @@ -984,11 +953,20 @@ dev,swagger + + + org.springframework.boot + spring-boot-devtools + true + + + org.springframework.boot + spring-boot-starter-undertow + + - + graphite @@ -998,9 +976,7 @@ - + prometheus @@ -1010,22 +986,18 @@ io.prometheus - simpleclient_servlet + simpleclient_dropwizard ${prometheus-simpleclient.version} io.prometheus - simpleclient_dropwizard + simpleclient_servlet ${prometheus-simpleclient.version} - + IDE @@ -1036,4 +1008,5 @@ + diff --git a/jhipster/jhipster-microservice/gateway-app/src/test/java/com/gateway/service/UserServiceIntIntegrationTest.java b/jhipster/jhipster-microservice/gateway-app/src/test/java/com/gateway/service/UserServiceIntegrationTest.java similarity index 100% rename from jhipster/jhipster-microservice/gateway-app/src/test/java/com/gateway/service/UserServiceIntIntegrationTest.java rename to jhipster/jhipster-microservice/gateway-app/src/test/java/com/gateway/service/UserServiceIntegrationTest.java diff --git a/jhipster/jhipster-microservice/gateway-app/src/test/java/com/gateway/web/rest/UserResourceIntIntegrationTest.java b/jhipster/jhipster-microservice/gateway-app/src/test/java/com/gateway/web/rest/UserResourceIntegrationTest.java similarity index 100% rename from jhipster/jhipster-microservice/gateway-app/src/test/java/com/gateway/web/rest/UserResourceIntIntegrationTest.java rename to jhipster/jhipster-microservice/gateway-app/src/test/java/com/gateway/web/rest/UserResourceIntegrationTest.java diff --git a/jhipster/jhipster-microservice/pom.xml b/jhipster/jhipster-microservice/pom.xml new file mode 100644 index 0000000000..4a60e47f87 --- /dev/null +++ b/jhipster/jhipster-microservice/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + jhipster-microservice + pom + JHipster Microservice + + + jhipster + com.baeldung.jhipster + 1.0.0-SNAPSHOT + + + + car-app + dealer-app + gateway-app + + diff --git a/jhipster/jhipster-monolithic/package.json b/jhipster/jhipster-monolithic/package.json index 40bbd28799..5f72047fb3 100644 --- a/jhipster/jhipster-monolithic/package.json +++ b/jhipster/jhipster-monolithic/package.json @@ -64,7 +64,7 @@ "karma-sourcemap-loader": "0.3.7", "karma-webpack": "2.0.2", "lazypipe": "1.0.1", - "lodash": "4.17.4", + "lodash": "4.17.10", "map-stream": "0.0.6", "phantomjs-prebuilt": "2.1.14", "protractor": "5.1.1", diff --git a/jhipster/jhipster-monolithic/pom.xml b/jhipster/jhipster-monolithic/pom.xml index c8c9578fd6..e242668759 100644 --- a/jhipster/jhipster-monolithic/pom.xml +++ b/jhipster/jhipster-monolithic/pom.xml @@ -1,109 +1,16 @@ - - + 4.0.0 + jhipster-monolithic + war + JHipster Monolithic Application - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-1 + jhipster + com.baeldung.jhipster + 1.0.0-SNAPSHOT - com.baeldung - jhipster-monolithic - 0.0.1-SNAPSHOT - war - JHipster Monolithic Application - - - ${maven.version} - - - - -Djava.security.egd=file:/dev/./urandom -Xmx256m - 3.6.2 - 2.0.0 - 2.5 - 3.5 - 0.4.13 - 1.3 - 2.2.1 - 2.2.3 - 5.2.8.Final - 2.6.0 - 0.7.9 - 1.8 - 3.21.0-GA - 1.0.0 - 1.1.0 - 0.7.0 - 1.1.3 - 3.6 - 2.0.0 - 4.8 - jdt_apt - 1.1.0.Final - 1.4.1 - 3.0.1 - yyyyMMddHHmmss - 3.0.0 - 3.1.3 - v6.10.0 - 4.3.0 - - - - - ${project.build.directory}/test-results - 0.0.20 - false - 3.2.2 - 2.12.1 - 3.2 - - src/main/webapp/content/**/*.*, - src/main/webapp/bower_components/**/*.*, - src/main/webapp/i18n/*.js, target/www/**/*.* - - - S3437,UndocumentedApi,BoldAndItalicTagsCheck - - - src/main/webapp/app/**/*.* - Web:BoldAndItalicTagsCheck - - src/main/java/**/* - squid:S3437 - - src/main/java/**/* - squid:UndocumentedApi - - ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec - ${project.testresult.directory}/coverage/jacoco/jacoco.exec - jacoco - - ${project.testresult.directory}/karma - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.basedir}/src/main/ - ${project.testresult.directory}/surefire-reports - ${project.basedir}/src/test/ - - 2.5.0 - - 2.6.1 - 1.4.10.Final - 1.1.0.Final - - com.fasterxml.jackson.datatype @@ -129,8 +36,7 @@ com.jayway.jsonpath json-path test - + com.jcraft @@ -180,8 +86,7 @@ io.dropwizard.metrics metrics-annotation - ${dropwizard-metrics.version} - + io.dropwizard.metrics metrics-core @@ -189,18 +94,15 @@ io.dropwizard.metrics metrics-json - ${dropwizard-metrics.version} - + io.dropwizard.metrics metrics-jvm - ${dropwizard-metrics.version} - + io.dropwizard.metrics metrics-servlet - ${dropwizard-metrics.version} - + io.dropwizard.metrics metrics-servlets @@ -389,13 +291,13 @@ + spring-boot:run - + org.eclipse.m2e lifecycle-mapping @@ -413,7 +315,7 @@ - + @@ -427,7 +329,7 @@ - + @@ -437,7 +339,7 @@ - + com.spotify docker-maven-plugin @@ -484,12 +386,9 @@ target/gatling/results src/test/gatling/bodies src/test/gatling/simulations - + true - + @@ -512,6 +411,7 @@ org.apache.maven.plugins maven-eclipse-plugin + ${maven-eclipse-plugin.version} true true @@ -587,19 +487,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - - alphabetical - - **/*IntTest.java - - - - org.jacoco jacoco-maven-plugin @@ -611,13 +498,11 @@ prepare-agent - + ${project.testresult.directory}/coverage/jacoco/jacoco.exec - + post-unit-test test @@ -634,7 +519,7 @@ org.liquibase liquibase-maven-plugin - ${liquibase.version} + ${liquibase-maven-plugin.version} javax.validation @@ -662,9 +547,9 @@ src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml org.h2.Driver jdbc:h2:file:./target/h2db/db/baeldung - + baeldung - + hibernate:spring:com.baeldung.domain?dialect=org.hibernate.dialect.H2Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy true debug @@ -681,13 +566,13 @@ true true - + + no-liquibase @@ -865,12 +750,9 @@ - + cc @@ -930,8 +812,7 @@ true true true - + @@ -986,8 +867,7 @@ - + IDE @@ -998,4 +878,88 @@ + + + -Djava.security.egd=file:/dev/./urandom -Xmx256m + 3.6.2 + 2.0.0 + 2.5 + 3.5 + 0.4.13 + 1.3 + 2.2.1 + 2.2.3 + 5.2.8.Final + 2.6.0 + 0.7.9 + 3.21.0-GA + 1.0.0 + 1.1.0 + 0.7.0 + 1.1.3 + 3.6 + 2.0.0 + 3.6.2 + 4.8 + jdt_apt + 1.1.0.Final + 1.4.1 + 3.0.1 + 2.10 + yyyyMMddHHmmss + 3.0.0 + 3.1.3 + v6.10.0 + 4.3.0 + + + + + ${project.build.directory}/test-results + 0.0.20 + false + 3.2.2 + 2.12.1 + 3.2 + + src/main/webapp/content/**/*.*, + src/main/webapp/bower_components/**/*.*, + src/main/webapp/i18n/*.js, target/www/**/*.* + + + S3437,UndocumentedApi,BoldAndItalicTagsCheck + + + src/main/webapp/app/**/*.* + Web:BoldAndItalicTagsCheck + + src/main/java/**/* + squid:S3437 + + src/main/java/**/* + squid:UndocumentedApi + + ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + jacoco + + ${project.testresult.directory}/karma + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.basedir}/src/main/ + ${project.testresult.directory}/surefire-reports + ${project.basedir}/src/test/ + + 2.5.0 + + 2.6.1 + 1.4.10.Final + 1.1.0.Final + + diff --git a/jhipster/jhipster-monolithic/src/main/resources/logback-spring.xml b/jhipster/jhipster-monolithic/src/main/resources/logback-spring.xml index 3c62a70c31..2fda7cc968 100644 --- a/jhipster/jhipster-monolithic/src/main/resources/logback-spring.xml +++ b/jhipster/jhipster-monolithic/src/main/resources/logback-spring.xml @@ -3,28 +3,9 @@ - - - - - - + diff --git a/jhipster/jhipster-monolithic/src/test/java/com/baeldung/service/UserServiceIntIntegrationTest.java b/jhipster/jhipster-monolithic/src/test/java/com/baeldung/service/UserServiceIntIntegrationTest.java deleted file mode 100644 index 8b4825453e..0000000000 --- a/jhipster/jhipster-monolithic/src/test/java/com/baeldung/service/UserServiceIntIntegrationTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.baeldung.service; - -import com.baeldung.BaeldungApp; -import com.baeldung.domain.User; -import com.baeldung.config.Constants; -import com.baeldung.repository.UserRepository; -import com.baeldung.service.dto.UserDTO; -import java.time.ZonedDateTime; -import com.baeldung.service.util.RandomUtil; -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.transaction.annotation.Transactional; -import org.springframework.test.context.junit4.SpringRunner; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import java.util.Optional; -import java.util.List; - -import static org.assertj.core.api.Assertions.*; - -/** - * Test class for the UserResource REST controller. - * - * @see UserService - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = BaeldungApp.class) -@Transactional -public class UserServiceIntegrationTest { - - @Autowired - private UserRepository userRepository; - - @Autowired - private UserService userService; - - @Test - public void assertThatUserMustExistToResetPassword() { - Optional maybeUser = userService.requestPasswordReset("john.doe@localhost"); - assertThat(maybeUser.isPresent()).isFalse(); - - maybeUser = userService.requestPasswordReset("admin@localhost"); - assertThat(maybeUser.isPresent()).isTrue(); - - assertThat(maybeUser.get().getEmail()).isEqualTo("admin@localhost"); - assertThat(maybeUser.get().getResetDate()).isNotNull(); - assertThat(maybeUser.get().getResetKey()).isNotNull(); - } - - @Test - public void assertThatOnlyActivatedUserCanRequestPasswordReset() { - User user = userService.createUser("johndoe", "johndoe", "John", "Doe", "john.doe@localhost", "http://placehold.it/50x50", "en-US"); - Optional maybeUser = userService.requestPasswordReset("john.doe@localhost"); - assertThat(maybeUser.isPresent()).isFalse(); - userRepository.delete(user); - } - - @Test - public void assertThatResetKeyMustNotBeOlderThan24Hours() { - User user = userService.createUser("johndoe", "johndoe", "John", "Doe", "john.doe@localhost", "http://placehold.it/50x50", "en-US"); - - ZonedDateTime daysAgo = ZonedDateTime.now().minusHours(25); - String resetKey = RandomUtil.generateResetKey(); - user.setActivated(true); - user.setResetDate(daysAgo); - user.setResetKey(resetKey); - - userRepository.save(user); - - Optional maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); - - assertThat(maybeUser.isPresent()).isFalse(); - - userRepository.delete(user); - } - - @Test - public void assertThatResetKeyMustBeValid() { - User user = userService.createUser("johndoe", "johndoe", "John", "Doe", "john.doe@localhost", "http://placehold.it/50x50", "en-US"); - - ZonedDateTime daysAgo = ZonedDateTime.now().minusHours(25); - user.setActivated(true); - user.setResetDate(daysAgo); - user.setResetKey("1234"); - userRepository.save(user); - Optional maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); - assertThat(maybeUser.isPresent()).isFalse(); - userRepository.delete(user); - } - - @Test - public void assertThatUserCanResetPassword() { - User user = userService.createUser("johndoe", "johndoe", "John", "Doe", "john.doe@localhost", "http://placehold.it/50x50", "en-US"); - String oldPassword = user.getPassword(); - ZonedDateTime daysAgo = ZonedDateTime.now().minusHours(2); - String resetKey = RandomUtil.generateResetKey(); - user.setActivated(true); - user.setResetDate(daysAgo); - user.setResetKey(resetKey); - userRepository.save(user); - Optional maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey()); - assertThat(maybeUser.isPresent()).isTrue(); - assertThat(maybeUser.get().getResetDate()).isNull(); - assertThat(maybeUser.get().getResetKey()).isNull(); - assertThat(maybeUser.get().getPassword()).isNotEqualTo(oldPassword); - - userRepository.delete(user); - } - - @Test - public void testFindNotActivatedUsersByCreationDateBefore() { - userService.removeNotActivatedUsers(); - ZonedDateTime now = ZonedDateTime.now(); - List users = userRepository.findAllByActivatedIsFalseAndCreatedDateBefore(now.minusDays(3)); - assertThat(users).isEmpty(); - } - - @Test - public void assertThatAnonymousUserIsNotGet() { - final PageRequest pageable = new PageRequest(0, (int) userRepository.count()); - final Page allManagedUsers = userService.getAllManagedUsers(pageable); - assertThat(allManagedUsers.getContent().stream() - .noneMatch(user -> Constants.ANONYMOUS_USER.equals(user.getLogin()))) - .isTrue(); - } -} diff --git a/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/CommentResourceIntegrationTest.java b/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/CommentResourceIntegrationTest.java index 4f544d9eeb..1d4e7126d6 100644 --- a/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/CommentResourceIntegrationTest.java +++ b/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/CommentResourceIntegrationTest.java @@ -86,7 +86,7 @@ public class CommentResourceIntegrationTest { .text(DEFAULT_TEXT) .creationDate(DEFAULT_CREATION_DATE); // Add required entity - Post post = PostResourceIntTest.createEntity(em); + Post post = PostResourceIntegrationTest.createEntity(em); em.persist(post); em.flush(); comment.setPost(post); diff --git a/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/PostResourceIntegrationTest.java b/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/PostResourceIntegrationTest.java index a9a4bc74b9..a37f901f7a 100644 --- a/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/PostResourceIntegrationTest.java +++ b/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/PostResourceIntegrationTest.java @@ -90,7 +90,7 @@ public class PostResourceIntegrationTest { .content(DEFAULT_CONTENT) .creationDate(DEFAULT_CREATION_DATE); // Add required entity - User creator = UserResourceIntTest.createEntity(em); + User creator = UserResourceIntegrationTest.createEntity(em); em.persist(creator); em.flush(); post.setCreator(creator); diff --git a/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/UserResourceIntIntegrationTest.java b/jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/UserResourceIntegrationTest.java similarity index 100% rename from jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/UserResourceIntIntegrationTest.java rename to jhipster/jhipster-monolithic/src/test/java/com/baeldung/web/rest/UserResourceIntegrationTest.java diff --git a/jhipster/pom.xml b/jhipster/pom.xml new file mode 100644 index 0000000000..2bf7bcb233 --- /dev/null +++ b/jhipster/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + com.baeldung.jhipster + jhipster + 1.0.0-SNAPSHOT + pom + JHipster + + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 + + + + jhipster-monolithic + jhipster-microservice + + + diff --git a/jjwt/pom.xml b/jjwt/pom.xml index 2aa52b8818..6bf9f4426a 100644 --- a/jjwt/pom.xml +++ b/jjwt/pom.xml @@ -1,12 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 io.jsonwebtoken - jjwtfun + jjwt 0.0.1-SNAPSHOT jar - jjwtfun + jjwt Exercising the JJWT diff --git a/jjwt/src/main/resources/logback.xml b/jjwt/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jjwt/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jmeter/pom.xml b/jmeter/pom.xml index 5f9509f0be..943b75e03b 100644 --- a/jmeter/pom.xml +++ b/jmeter/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jmeter 0.0.1-SNAPSHOT @@ -59,9 +59,6 @@ - UTF-8 - UTF-8 - 1.8 2.6.0 diff --git a/jmeter/src/main/resources/logback.xml b/jmeter/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jmeter/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jmh/README.md b/jmh/README.md index 2a2c6a173a..9c5a70e3c2 100644 --- a/jmh/README.md +++ b/jmh/README.md @@ -1,3 +1,4 @@ ## Relevant articles: - [Microbenchmarking with Java](http://www.baeldung.com/java-microbenchmark-harness) + diff --git a/jmh/pom.xml b/jmh/pom.xml index 60b59262b4..1e01809fe6 100644 --- a/jmh/pom.xml +++ b/jmh/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung jmh @@ -11,8 +11,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java @@ -33,6 +33,7 @@ org.apache.maven.plugins maven-jar-plugin + ${maven-jar-plugin.version} @@ -45,10 +46,8 @@ - UTF-8 - UTF-8 - 21.0 1.19 + 3.0.2 \ No newline at end of file diff --git a/jmh/src/main/resources/logback.xml b/jmh/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jmh/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jni/pom.xml b/jni/pom.xml index 752277f526..d4cc409d33 100644 --- a/jni/pom.xml +++ b/jni/pom.xml @@ -1,15 +1,12 @@ - - 4.0.0 - com.baeldung - jni - 0.0.1-SNAPSHOT - - - - junit - junit - 4.8.1 - test - - + + 4.0.0 + jni + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + \ No newline at end of file diff --git a/jni/src/main/resources/logback.xml b/jni/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jni/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jni/src/test/java/com/baeldung/jni/JNINativeTests.java b/jni/src/test/java/com/baeldung/jni/JNINativeManualTest.java similarity index 98% rename from jni/src/test/java/com/baeldung/jni/JNINativeTests.java rename to jni/src/test/java/com/baeldung/jni/JNINativeManualTest.java index 42e572d41b..8201945644 100644 --- a/jni/src/test/java/com/baeldung/jni/JNINativeTests.java +++ b/jni/src/test/java/com/baeldung/jni/JNINativeManualTest.java @@ -7,7 +7,7 @@ import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; -public class JNINativeTests { +public class JNINativeManualTest { @Before public void setup() { diff --git a/jnosql/README.md b/jnosql/README.md new file mode 100644 index 0000000000..d580cbc920 --- /dev/null +++ b/jnosql/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [A Guide to Eclipse JNoSQL](http://www.baeldung.com/eclipse-jnosql) diff --git a/jnosql/jnosql-artemis/pom.xml b/jnosql/jnosql-artemis/pom.xml new file mode 100644 index 0000000000..9c2bfd1ba0 --- /dev/null +++ b/jnosql/jnosql-artemis/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + + com.baeldung.jnosql + jnosql + 1.0-SNAPSHOT + + + jnosql-artemis + war + + + 2.4.2 + false + + + + ${project.artifactId} + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + ${liberty-maven-plugin.version} + + + io.openliberty + openliberty-webProfile8 + RELEASE + zip + + project + true + src/main/liberty/config/server.xml + + + + install-server + prepare-package + + install-server + create-server + install-feature + + + + install-apps + package + + install-apps + + + + + + + + + + + javax + javaee-web-api + 8.0 + provided + + + + org.jnosql.artemis + artemis-configuration + ${jnosql.version} + + + org.jnosql.artemis + artemis-document + ${jnosql.version} + + + org.jnosql.diana + mongodb-driver + ${jnosql.version} + + + + + diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/AppConfig.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/AppConfig.java new file mode 100644 index 0000000000..bf445d9d01 --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/AppConfig.java @@ -0,0 +1,10 @@ +package com.baeldung.jnosql.artemis; + +import javax.enterprise.context.Initialized; +import javax.enterprise.event.Observes; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +@ApplicationPath("") +public class AppConfig extends Application { +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/EmbeddedMongoDBSetup.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/EmbeddedMongoDBSetup.java new file mode 100644 index 0000000000..8b3e161f85 --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/EmbeddedMongoDBSetup.java @@ -0,0 +1,52 @@ +package com.baeldung.jnosql.artemis; + +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodProcess; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.MongodConfigBuilder; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Destroyed; +import javax.enterprise.context.Initialized; +import javax.enterprise.event.Observes; +import java.io.IOException; + +@ApplicationScoped +public class EmbeddedMongoDBSetup { + + private static final String MONGODB_HOST = "localhost"; + private static final int MONGODB_PORT = 27019; + + private static final MongodStarter starter = MongodStarter.getDefaultInstance(); + private static MongodExecutable _mongodExe; + private static MongodProcess _mongod; + + public void init(@Observes @Initialized(ApplicationScoped.class) Object init) { + try { + System.out.println("Starting Embedded MongoDB"); + initdb(); + System.out.println("Embedded MongoDB started"); + } catch (IOException e) { + System.out.println("Embedded MongoDB starting error !!"); + e.printStackTrace(); + } + } + + private void initdb() throws IOException { + _mongodExe = starter.prepare(new MongodConfigBuilder() + .version(Version.Main.DEVELOPMENT) + .net(new Net(MONGODB_HOST, MONGODB_PORT, Network.localhostIsIPv6())) + .build()); + _mongod = _mongodExe.start(); + } + + public void destroy(@Observes @Destroyed(ApplicationScoped.class) Object init) { + System.out.println("Stopping Embedded MongoDB"); + _mongod.stop(); + _mongodExe.stop(); + System.out.println("Embedded MongoDB stopped !"); + } +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/EntityManagerProducer.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/EntityManagerProducer.java new file mode 100644 index 0000000000..c51868886b --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/EntityManagerProducer.java @@ -0,0 +1,33 @@ +package com.baeldung.jnosql.artemis; + +import org.jnosql.artemis.ConfigurationUnit; +import org.jnosql.diana.api.document.DocumentCollectionManager; +import org.jnosql.diana.api.document.DocumentCollectionManagerFactory; +import org.jnosql.diana.mongodb.document.MongoDBDocumentCollectionManager; +import org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration; + +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Disposes; +import javax.enterprise.inject.Produces; +import javax.inject.Inject; + +@ApplicationScoped +public class EntityManagerProducer { + + private static final String DATABASE = "todos"; + + @Inject + @ConfigurationUnit(name = "document") + private DocumentCollectionManagerFactory managerFactory; + + @Produces + public DocumentCollectionManager getEntityManager() { + return managerFactory.get(DATABASE); + } + + public void close(@Disposes DocumentCollectionManager entityManager) { + entityManager.close(); + } + +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/RepositoryTodoManager.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/RepositoryTodoManager.java new file mode 100644 index 0000000000..2b19858f6d --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/RepositoryTodoManager.java @@ -0,0 +1,41 @@ +package com.baeldung.jnosql.artemis; + +import com.baeldung.jnosql.artemis.qualifier.Repo; +import org.jnosql.artemis.Database; +import org.jnosql.artemis.DatabaseType; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import java.util.List; +import java.util.Optional; + +@ApplicationScoped +@Repo +public class RepositoryTodoManager implements TodoManager { + + @Inject + @Database(DatabaseType.DOCUMENT) + private TodoRepository repository; + + @Override + public Todo add(Todo todo) { + return repository.save(todo); + } + + @Override + public Todo get(String id) { + Optional todo = repository.findById(id); + return todo.get(); + } + + @Override + public List getAll() { + return repository.findAll(); + } + + @Override + public void delete(String id) { + repository.deleteById(id); + } + +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TemplateTodoManager.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TemplateTodoManager.java new file mode 100644 index 0000000000..8c9ce745f7 --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TemplateTodoManager.java @@ -0,0 +1,43 @@ +package com.baeldung.jnosql.artemis; + +import com.baeldung.jnosql.artemis.qualifier.Template; +import org.jnosql.artemis.document.DocumentTemplate; +import org.jnosql.diana.api.document.DocumentQuery; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import java.util.List; +import java.util.Optional; + +import static org.jnosql.diana.api.document.query.DocumentQueryBuilder.select; + +@ApplicationScoped +@Template +public class TemplateTodoManager implements TodoManager { + + @Inject + private DocumentTemplate documentTemplate; + + @Override + public Todo add(Todo todo) { + return documentTemplate.insert(todo); + } + + @Override + public Todo get(String id) { + Optional todo = documentTemplate.find(Todo.class, id); + return todo.get(); + } + + @Override + public List getAll() { + DocumentQuery query = select().from("Todo").build(); + return documentTemplate.select(query); + } + + @Override + public void delete(String id) { + documentTemplate.delete(Todo.class, id); + } + +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/Todo.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/Todo.java new file mode 100644 index 0000000000..f250ddfa66 --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/Todo.java @@ -0,0 +1,51 @@ +package com.baeldung.jnosql.artemis; + +import org.jnosql.artemis.Column; +import org.jnosql.artemis.Entity; +import org.jnosql.artemis.Id; + +import java.io.Serializable; + +@Entity +public class Todo implements Serializable { + + @Id("id") + public String id; + @Column + public String name; + @Column + public String description; + + public Todo() { + } + + public Todo(String id, String name, String description) { + this.id = id; + this.name = name; + this.description = description; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoManager.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoManager.java new file mode 100644 index 0000000000..cdcfea5b40 --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoManager.java @@ -0,0 +1,14 @@ +package com.baeldung.jnosql.artemis; + +import java.util.List; + +public interface TodoManager { + + Todo add(Todo todo); + + Todo get(String id); + + List getAll(); + + void delete(String id); +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoRepository.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoRepository.java new file mode 100644 index 0000000000..52381d1757 --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.jnosql.artemis; + +import org.jnosql.artemis.Repository; + +import java.util.List; + +public interface TodoRepository extends Repository { + List findByName(String name); + List findAll(); +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoResource.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoResource.java new file mode 100644 index 0000000000..42149af3cc --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/TodoResource.java @@ -0,0 +1,48 @@ +package com.baeldung.jnosql.artemis; + +import com.baeldung.jnosql.artemis.qualifier.Repo; +import com.baeldung.jnosql.artemis.qualifier.Template; + +import javax.inject.Inject; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriBuilder; + +@Path("todos") +public class TodoResource { + + /* + Use eiher @Template or @Repo + */ + @Inject + @Template + //@Repo + private TodoManager todoManager; + + @GET + @Path("") + @Produces(MediaType.APPLICATION_JSON) + public Response all() { + return Response.ok(todoManager.getAll()).build(); + } + + @GET + @Path("{id}") + @Produces(MediaType.APPLICATION_JSON) + public Response get(@PathParam("id") String id) { + Todo todo = todoManager.get(id); + return Response.ok(todo).build(); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response add(Todo todo) { + Todo savedTodo = todoManager.add(todo); + System.out.println(savedTodo.id); + return Response.created( + UriBuilder.fromResource(this.getClass()).path(String.valueOf(savedTodo.id)).build()) + .build(); + } + +} diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/qualifier/Repo.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/qualifier/Repo.java new file mode 100644 index 0000000000..a5883946db --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/qualifier/Repo.java @@ -0,0 +1,13 @@ +package com.baeldung.jnosql.artemis.qualifier; + +import javax.inject.Qualifier; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.TYPE}) +@Qualifier +public @interface Repo { +} \ No newline at end of file diff --git a/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/qualifier/Template.java b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/qualifier/Template.java new file mode 100644 index 0000000000..81fbbe5271 --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/java/com/baeldung/jnosql/artemis/qualifier/Template.java @@ -0,0 +1,13 @@ +package com.baeldung.jnosql.artemis.qualifier; + +import javax.inject.Qualifier; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.TYPE}) +@Qualifier +public @interface Template { +} \ No newline at end of file diff --git a/jnosql/jnosql-artemis/src/main/liberty/config/server.xml b/jnosql/jnosql-artemis/src/main/liberty/config/server.xml new file mode 100644 index 0000000000..897aca853a --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/liberty/config/server.xml @@ -0,0 +1,6 @@ + + + webProfile-8.0 + + + diff --git a/jnosql/jnosql-artemis/src/main/resources/META-INF/beans.xml b/jnosql/jnosql-artemis/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..4f0b3cdeeb --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/jnosql/jnosql-artemis/src/main/resources/META-INF/jnosql.json b/jnosql/jnosql-artemis/src/main/resources/META-INF/jnosql.json new file mode 100644 index 0000000000..b8e26cf54a --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/resources/META-INF/jnosql.json @@ -0,0 +1,10 @@ +[ + { + "description": "The mongodb document configuration", + "name": "document", + "provider": "org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration", + "settings": { + "mongodb-server-host-1":"localhost:27019" + } + } +] \ No newline at end of file diff --git a/jnosql/jnosql-artemis/src/main/resources/logback.xml b/jnosql/jnosql-artemis/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jnosql/jnosql-artemis/src/main/webapp/WEB-INF/jnosql.json b/jnosql/jnosql-artemis/src/main/webapp/WEB-INF/jnosql.json new file mode 100644 index 0000000000..b8e26cf54a --- /dev/null +++ b/jnosql/jnosql-artemis/src/main/webapp/WEB-INF/jnosql.json @@ -0,0 +1,10 @@ +[ + { + "description": "The mongodb document configuration", + "name": "document", + "provider": "org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration", + "settings": { + "mongodb-server-host-1":"localhost:27019" + } + } +] \ No newline at end of file diff --git a/jnosql/jnosql-diana/pom.xml b/jnosql/jnosql-diana/pom.xml new file mode 100644 index 0000000000..767defb2a8 --- /dev/null +++ b/jnosql/jnosql-diana/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + + com.baeldung.jnosql + jnosql + 1.0-SNAPSHOT + + + jnosql-diana + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + document + + java + + + com.baeldung.jnosql.diana.document.DocumentApp + + + + column + + java + + + com.baeldung.jnosql.diana.column.ColumnFamilyApp + + + + key + + java + + + com.baeldung.jnosql.diana.key.KeyValueApp + + + + + + + + + + + + org.jnosql.diana + diana-document + 0.0.5 + + + org.jnosql.diana + mongodb-driver + 0.0.5 + + + + + org.jnosql.diana + diana-column + 0.0.5 + + + org.jnosql.diana + cassandra-driver + 0.0.5 + + + + + org.jnosql.diana + diana-key-value + 0.0.5 + + + org.jnosql.diana + hazelcast-driver + 0.0.5 + + + + \ No newline at end of file diff --git a/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/column/ColumnFamilyApp.java b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/column/ColumnFamilyApp.java new file mode 100644 index 0000000000..5b65f9ad73 --- /dev/null +++ b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/column/ColumnFamilyApp.java @@ -0,0 +1,32 @@ +package com.baeldung.jnosql.diana.column; + +import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +import org.jnosql.diana.api.column.*; +import org.jnosql.diana.cassandra.column.CassandraConfiguration; + +public class ColumnFamilyApp { + + private static final String KEY_SPACE = "myKeySpace"; + private static final String COLUMN_FAMILY = "books"; + + public static void main(String... args) throws Exception { + + EmbeddedCassandraServerHelper.startEmbeddedCassandra(); + + ColumnConfiguration configuration = new CassandraConfiguration(); + try(ColumnFamilyManagerFactory entityManagerFactory = configuration.get()) { + ColumnFamilyManager entityManager = entityManagerFactory.get(KEY_SPACE); + ColumnEntity columnEntity = ColumnEntity.of(COLUMN_FAMILY); + Column key = Columns.of("id", 10L); + Column name = Columns.of("name", "JNoSQL in Acion"); + columnEntity.add(key); + columnEntity.add(name); + ColumnEntity saved = entityManager.insert(columnEntity); + System.out.println(saved); + } + + EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); + EmbeddedCassandraServerHelper.stopEmbeddedCassandra(); + } + +} diff --git a/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/document/DocumentApp.java b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/document/DocumentApp.java new file mode 100644 index 0000000000..258c812a31 --- /dev/null +++ b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/document/DocumentApp.java @@ -0,0 +1,67 @@ +package com.baeldung.jnosql.diana.document; + +import org.jnosql.diana.api.Settings; +import org.jnosql.diana.api.document.*; +import org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.jnosql.diana.api.document.query.DocumentQueryBuilder.delete; +import static org.jnosql.diana.api.document.query.DocumentQueryBuilder.select; + +public class DocumentApp { + + private static final String DB_NAME = "my-db"; + private static final String DOCUMENT_COLLECTION = "books"; + + public static final String KEY_NAME = "_id"; + + DocumentConfiguration configuration = new MongoDBDocumentConfiguration(); + + public static void main(String... args) throws Exception { + MongoDbInit.startMongoDb(); + + DocumentApp app = new DocumentApp(); + app.process(); + + MongoDbInit.stopMongoDb(); + } + + public void process() { + + Map map = new HashMap<>(); + map.put("mongodb-server-host-1", "localhost:27017"); + + try (DocumentCollectionManagerFactory managerFactory = configuration.get(Settings.of(map)); + DocumentCollectionManager manager = managerFactory.get(DB_NAME);) { + + DocumentEntity documentEntity = DocumentEntity.of(DOCUMENT_COLLECTION); + documentEntity.add(Document.of(KEY_NAME, "100")); + documentEntity.add(Document.of("name", "JNoSQL in Action")); + documentEntity.add(Document.of("pages", 620)); + + //CREATE + DocumentEntity saved = manager.insert(documentEntity); + + //READ + DocumentQuery query = select().from(DOCUMENT_COLLECTION).where(KEY_NAME).eq("100").build(); + List entities = manager.select(query); + System.out.println(entities.get(0)); + + //UPDATE + saved.add(Document.of("author", "baeldung")); + DocumentEntity updated = manager.update(saved); + System.out.println(updated); + + //DELETE + DocumentDeleteQuery deleteQuery = delete().from(DOCUMENT_COLLECTION).where(KEY_NAME).eq("100").build(); + manager.delete(deleteQuery); + + List documentEntityList = manager.select(select().from(DOCUMENT_COLLECTION).build()); + System.out.println(documentEntityList); + } + } + +} diff --git a/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/document/MongoDbInit.java b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/document/MongoDbInit.java new file mode 100644 index 0000000000..19bb347581 --- /dev/null +++ b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/document/MongoDbInit.java @@ -0,0 +1,32 @@ +package com.baeldung.jnosql.diana.document; + +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodProcess; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.MongodConfigBuilder; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; + +import java.io.IOException; + +public abstract class MongoDbInit { + + private static final MongodStarter starter = MongodStarter.getDefaultInstance(); + private static MongodExecutable _mongodExe; + private static MongodProcess _mongod; + + public static void startMongoDb() throws IOException { + _mongodExe = starter.prepare(new MongodConfigBuilder() + .version(Version.Main.DEVELOPMENT) + .net(new Net("localhost", 27017, Network.localhostIsIPv6())) + .build()); + _mongod = _mongodExe.start(); + } + + public static void stopMongoDb(){ + _mongod.stop(); + _mongodExe.stop(); + } + +} \ No newline at end of file diff --git a/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/key/Book.java b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/key/Book.java new file mode 100644 index 0000000000..afa20e66b1 --- /dev/null +++ b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/key/Book.java @@ -0,0 +1,63 @@ +package com.baeldung.jnosql.diana.key; + +import java.io.Serializable; + +public class Book implements Serializable { + + private String isbn; + private String name; + private String author; + private int pages; + + public Book() { + } + + public Book(String isbn, String name, String author, int pages) { + this.isbn = isbn; + this.name = name; + this.author = author; + this.pages = pages; + } + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public int getPages() { + return pages; + } + + public void setPages(int pages) { + this.pages = pages; + } + + @Override + public String toString() { + return "Book{" + + "isbn='" + isbn + '\'' + + ", name='" + name + '\'' + + ", author='" + author + '\'' + + ", pages=" + pages + + '}'; + } +} diff --git a/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/key/KeyValueApp.java b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/key/KeyValueApp.java new file mode 100644 index 0000000000..ab51bfa4fc --- /dev/null +++ b/jnosql/jnosql-diana/src/main/java/com/baeldung/jnosql/diana/key/KeyValueApp.java @@ -0,0 +1,33 @@ +package com.baeldung.jnosql.diana.key; + +import com.hazelcast.core.Hazelcast; +import org.jnosql.diana.api.Value; +import org.jnosql.diana.api.key.BucketManager; +import org.jnosql.diana.api.key.BucketManagerFactory; +import org.jnosql.diana.api.key.KeyValueConfiguration; +import org.jnosql.diana.api.key.KeyValueEntity; +import org.jnosql.diana.hazelcast.key.HazelcastKeyValueConfiguration; + +import java.util.Optional; + +public class KeyValueApp { + + private static final String BUCKET_NAME = "books"; + + public static void main(String... args) throws Exception { + KeyValueConfiguration configuration = new HazelcastKeyValueConfiguration(); + try (BucketManagerFactory managerFactory = configuration.get()) { + BucketManager manager = managerFactory.getBucketManager(BUCKET_NAME); + + Book book = new Book("12345", "JNoSQL in Action", "baeldung", 420); + KeyValueEntity keyValueEntity = KeyValueEntity.of(book.getIsbn(), book); + manager.put(keyValueEntity); + + Optional optionalValue = manager.get("12345"); + Value value = optionalValue.get(); + Book savedBook = value.get(Book.class); + System.out.println(savedBook); + } + Hazelcast.shutdownAll(); + } +} diff --git a/jnosql/jnosql-diana/src/main/resources/diana-cassandra.properties b/jnosql/jnosql-diana/src/main/resources/diana-cassandra.properties new file mode 100644 index 0000000000..5d7d840d65 --- /dev/null +++ b/jnosql/jnosql-diana/src/main/resources/diana-cassandra.properties @@ -0,0 +1,5 @@ +cassandra-host-1=localhost +cassandra-port=9142 +#cassandra-threads-number=2 +cassandra-query-1=CREATE KEYSPACE IF NOT EXISTS myKeySpace WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3}; +cassandra-query-2=CREATE COLUMNFAMILY IF NOT EXISTS myKeySpace.books (id bigint PRIMARY KEY, name text); diff --git a/jnosql/jnosql-diana/src/main/resources/diana-hazelcast.properties b/jnosql/jnosql-diana/src/main/resources/diana-hazelcast.properties new file mode 100644 index 0000000000..010b4a6e47 --- /dev/null +++ b/jnosql/jnosql-diana/src/main/resources/diana-hazelcast.properties @@ -0,0 +1 @@ +hazelcast-instanceName=hazelcast \ No newline at end of file diff --git a/jnosql/jnosql-diana/src/main/resources/diana-mongodb.properties b/jnosql/jnosql-diana/src/main/resources/diana-mongodb.properties new file mode 100644 index 0000000000..5b425bd7bf --- /dev/null +++ b/jnosql/jnosql-diana/src/main/resources/diana-mongodb.properties @@ -0,0 +1,2 @@ +#Define Host and Port +mongodb-server-host-1=localhost:27017 diff --git a/jnosql/jnosql-diana/src/main/resources/logback.xml b/jnosql/jnosql-diana/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jnosql/jnosql-diana/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jnosql/pom.xml b/jnosql/pom.xml new file mode 100644 index 0000000000..c87ad3cf4b --- /dev/null +++ b/jnosql/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + com.baeldung.jnosql + jnosql + 1.0-SNAPSHOT + pom + + + 1.8 + 1.8 + 0.0.5 + + + + jnosql-diana + jnosql-artemis + + + diff --git a/jooby/pom.xml b/jooby/pom.xml index 8d4ed186aa..83dd650701 100644 --- a/jooby/pom.xml +++ b/jooby/pom.xml @@ -1,58 +1,63 @@ - 4.0.0 - jooby - com.baeldung.jooby - 1.0 - jooby + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + jooby + com.baeldung.jooby + 1.0 + jooby - - org.jooby - modules - ${jooby.modules.version} - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + - - - org.jooby - jooby-netty - - - org.jooby - jooby-jedis - ${jooby-jedis.version} - - - ch.qos.logback - logback-classic - - - junit - junit - test - - - io.rest-assured - rest-assured - test - - + + + + org.jooby + modules + ${jooby.version} + pom + + + - - - - org.apache.maven.plugins - maven-shade-plugin - - - + + + org.jooby + jooby-netty + ${jooby.version} + + + org.jooby + jooby-jedis + ${jooby.version} + + + io.rest-assured + rest-assured + test + ${rest-assured.version} + + - - 1.1.3 - com.baeldung.jooby.App - 1.1.3 - 1.1.3 - + + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + + + + + 1.1.3 + 3.1.1 + com.baeldung.jooby.App + 2.4.3 + diff --git a/jooby/src/main/resources/logback.xml b/jooby/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jooby/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jooby/src/test/java/com/baeldung/jooby/AppTest.java b/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java similarity index 96% rename from jooby/src/test/java/com/baeldung/jooby/AppTest.java rename to jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java index af2626c046..ab7388f5f4 100644 --- a/jooby/src/test/java/com/baeldung/jooby/AppTest.java +++ b/jooby/src/test/java/com/baeldung/jooby/AppUnitTest.java @@ -9,7 +9,7 @@ import org.jooby.test.MockRouter; import org.junit.ClassRule; import org.junit.Test; -public class AppTest { +public class AppUnitTest { @ClassRule public static JoobyRule app = new JoobyRule(new App()); diff --git a/jpa-storedprocedure/README.md b/jpa-storedprocedure/README.md deleted file mode 100644 index 39d6784d8b..0000000000 --- a/jpa-storedprocedure/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) diff --git a/jpa-storedprocedure/pom.xml b/jpa-storedprocedure/pom.xml deleted file mode 100644 index e6cfe153d5..0000000000 --- a/jpa-storedprocedure/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - 4.0.0 - com.baeldung - jpa-storedprocedure - 1.0 - jar - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - JpaStoredProcedure - - - maven-assembly-plugin - - ${project.basedir} - - - jar-with-dependencies - - - - - - - - - - javax - javaee-api - ${jee.version} - provided - - - org.hibernate - hibernate-entitymanager - ${hibernate.version} - - - - mysql - mysql-connector-java - ${mysql.version} - - - commons-io - commons-io - ${commons-io.version} - - - - - 7.0 - 5.2.5.Final - 6.0.5 - 2.5 - - - \ No newline at end of file diff --git a/jpa-storedprocedure/src/main/resources/META-INF/persistence.xml b/jpa-storedprocedure/src/main/resources/META-INF/persistence.xml deleted file mode 100644 index 4c443cb7cf..0000000000 --- a/jpa-storedprocedure/src/main/resources/META-INF/persistence.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.model.Car - - - - - - - - - - \ No newline at end of file diff --git a/jsf/pom.xml b/jsf/pom.xml index e58e61de7f..2ac8a9f7c2 100644 --- a/jsf/pom.xml +++ b/jsf/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jsf 0.1-SNAPSHOT @@ -36,11 +36,6 @@ ${jstl.version} - - org.springframework - spring-web - ${org.springframework.version} - org.springframework spring-webmvc @@ -73,13 +68,13 @@ provided ${javax.servlet.version} - - + + - org.primefaces - primefaces - 6.2 - + org.primefaces + primefaces + ${primefaces.version} + @@ -111,5 +106,7 @@ 2.6 + 6.2 + \ No newline at end of file diff --git a/jsf/src/main/resources/logback.xml b/jsf/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/jsf/src/main/resources/logback.xml +++ b/jsf/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/json-path/README.md b/json-path/README.md index 3563dcf880..7a84ea7bde 100644 --- a/json-path/README.md +++ b/json-path/README.md @@ -1,3 +1,4 @@ ## Relevant articles: - [Introduction to JsonPath](http://www.baeldung.com/guide-to-jayway-jsonpath) +- [Count with JsonPath](http://www.baeldung.com/jsonpath-count) diff --git a/json-path/pom.xml b/json-path/pom.xml index 18bbb5af33..0f8ff3bd31 100644 --- a/json-path/pom.xml +++ b/json-path/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 json-path 0.0.1-SNAPSHOT diff --git a/json-path/src/main/resources/logback.xml b/json-path/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/json-path/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/json-path/src/test/resources/logback.xml b/json-path/src/test/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/json-path/src/test/resources/logback.xml +++ b/json-path/src/test/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/json/README.md b/json/README.md index 1317ada8be..e0679bc60b 100644 --- a/json/README.md +++ b/json/README.md @@ -8,3 +8,5 @@ - [Introduction to JSONForms](http://www.baeldung.com/introduction-to-jsonforms) - [Introduction to JsonPath](http://www.baeldung.com/guide-to-jayway-jsonpath) - [Introduction to JSON-Java (org.json)](http://www.baeldung.com/java-org-json) +- [Overview of JSON Pointer](https://www.baeldung.com/json-pointer) +- [Introduction to the JSON Binding API (JSR 367) in Java](http://www.baeldung.com/java-json-binding-api) \ No newline at end of file diff --git a/json/pom.xml b/json/pom.xml index 5d05b73489..b688baec06 100644 --- a/json/pom.xml +++ b/json/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung json @@ -32,12 +32,44 @@ org.json json 20171018 + + + javax.json.bind + javax.json.bind-api + ${jsonb-api.version} + + + junit + junit + 4.12 + test + + + + org.glassfish + javax.json + 1.1.2 + + + org.eclipse + yasson + ${yasson.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + test 1.4.1 1.2.21 + 1.0 + 4.1 + 1.0.1 diff --git a/jsonb/src/main/java/com/baeldung/adapter/PersonAdapter.java b/json/src/main/java/com/baeldung/adapter/PersonAdapter.java similarity index 100% rename from jsonb/src/main/java/com/baeldung/adapter/PersonAdapter.java rename to json/src/main/java/com/baeldung/adapter/PersonAdapter.java diff --git a/jsonb/src/main/java/com/baeldung/jsonb/Person.java b/json/src/main/java/com/baeldung/jsonb/Person.java similarity index 100% rename from jsonb/src/main/java/com/baeldung/jsonb/Person.java rename to json/src/main/java/com/baeldung/jsonb/Person.java diff --git a/json/src/main/java/com/baeldung/jsonpointer/JsonPointerCrud.java b/json/src/main/java/com/baeldung/jsonpointer/JsonPointerCrud.java new file mode 100644 index 0000000000..4398aa7867 --- /dev/null +++ b/json/src/main/java/com/baeldung/jsonpointer/JsonPointerCrud.java @@ -0,0 +1,95 @@ +package com.baeldung.jsonpointer; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonPointer; +import javax.json.JsonReader; +import javax.json.JsonString; +import javax.json.JsonStructure; + +public class JsonPointerCrud { + + private JsonStructure jsonStructure = null; + + public JsonPointerCrud(String fileName) throws IOException { + + try (JsonReader reader = Json.createReader(Files.newBufferedReader(Paths.get(fileName)))) { + jsonStructure = reader.read(); + } catch (FileNotFoundException e) { + System.out.println("Error to open json file: " + e.getMessage()); + } + + } + + public JsonPointerCrud(InputStream stream) { + + JsonReader reader = Json.createReader(stream); + jsonStructure = reader.read(); + reader.close(); + + } + + public JsonStructure insert(String key, String value) { + + JsonPointer jsonPointer = Json.createPointer("/" + key); + JsonString jsonValue = Json.createValue(value); + jsonStructure = jsonPointer.add(jsonStructure, jsonValue); + + return jsonStructure; + + } + + public JsonStructure update(String key, String newValue) { + + JsonPointer jsonPointer = Json.createPointer("/" + key); + JsonString jsonNewValue = Json.createValue(newValue); + jsonStructure = jsonPointer.replace(jsonStructure, jsonNewValue); + + return jsonStructure; + } + + public JsonStructure delete(String key) { + + JsonPointer jsonPointer = Json.createPointer("/" + key); + jsonPointer.getValue(jsonStructure); + jsonStructure = jsonPointer.remove(jsonStructure); + + return jsonStructure; + + } + + public String fetchValueFromKey(String key) { + JsonPointer jsonPointer = Json.createPointer("/" + key); + JsonString jsonString = (JsonString) jsonPointer.getValue(jsonStructure); + + return jsonString.getString(); + } + + public String fetchListValues(String key) { + JsonPointer jsonPointer = Json.createPointer("/" + key); + JsonObject jsonObject = (JsonObject) jsonPointer.getValue(jsonStructure); + + return jsonObject.toString(); + } + + public String fetchFullJSON() { + JsonPointer jsonPointer = Json.createPointer(""); + JsonObject jsonObject = (JsonObject) jsonPointer.getValue(jsonStructure); + + return jsonObject.toString(); + + } + + public boolean check(String key) { + JsonPointer jsonPointer = Json.createPointer("/" + key); + boolean found = jsonPointer.containsValue(jsonStructure); + + return found; + } +} diff --git a/json/src/main/resources/logback.xml b/json/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/json/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jsonb/src/test/java/com/baeldung/jsonb/JsonbTest.java b/json/src/test/java/com/baeldung/jsonb/JsonbUnitTest.java similarity index 99% rename from jsonb/src/test/java/com/baeldung/jsonb/JsonbTest.java rename to json/src/test/java/com/baeldung/jsonb/JsonbUnitTest.java index 67beda77e1..f258700c6b 100644 --- a/jsonb/src/test/java/com/baeldung/jsonb/JsonbTest.java +++ b/json/src/test/java/com/baeldung/jsonb/JsonbUnitTest.java @@ -18,8 +18,9 @@ import org.apache.commons.collections4.ListUtils; import org.junit.Test; import com.baeldung.adapter.PersonAdapter; +import com.baeldung.jsonb.Person; -public class JsonbTest { +public class JsonbUnitTest { @Test public void givenPersonList_whenSerializeWithJsonb_thenGetPersonJsonArray() { diff --git a/json/src/test/java/com/baeldung/jsonpointer/JsonPointerCrudUnitTest.java b/json/src/test/java/com/baeldung/jsonpointer/JsonPointerCrudUnitTest.java new file mode 100644 index 0000000000..c1553db325 --- /dev/null +++ b/json/src/test/java/com/baeldung/jsonpointer/JsonPointerCrudUnitTest.java @@ -0,0 +1,59 @@ +package com.baeldung.jsonpointer; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class JsonPointerCrudUnitTest { + + @Test + public void testJsonPointerCrudForAddress() { + + JsonPointerCrud jsonPointerCrud = new JsonPointerCrud(JsonPointerCrudUnitTest.class.getResourceAsStream("/address.json")); + + assertFalse(jsonPointerCrud.check("city")); + + // insert a value + jsonPointerCrud.insert("city", "Rio de Janeiro"); + + assertTrue(jsonPointerCrud.check("city")); + + // fetch full json + String fullJSON = jsonPointerCrud.fetchFullJSON(); + + assertTrue(fullJSON.contains("name")); + + assertTrue(fullJSON.contains("city")); + + // fetch value + String cityName = jsonPointerCrud.fetchValueFromKey("city"); + + assertEquals(cityName, "Rio de Janeiro"); + + // update value + jsonPointerCrud.update("city", "Sao Paulo"); + + // fetch value + cityName = jsonPointerCrud.fetchValueFromKey("city"); + + assertEquals(cityName, "Sao Paulo"); + + // delete + jsonPointerCrud.delete("city"); + + assertFalse(jsonPointerCrud.check("city")); + + } + + @Test + public void testJsonPointerCrudForBooks() { + + JsonPointerCrud jsonPointerCrud = new JsonPointerCrud(JsonPointerCrudUnitTest.class.getResourceAsStream("/books.json")); + + // fetch value + String book = jsonPointerCrud.fetchListValues("books/1"); + + assertEquals(book, "{\"title\":\"Title 2\",\"author\":\"John Doe\"}"); + + } +} \ No newline at end of file diff --git a/json/src/test/resources/address.json b/json/src/test/resources/address.json new file mode 100644 index 0000000000..599fcae12b --- /dev/null +++ b/json/src/test/resources/address.json @@ -0,0 +1,4 @@ +{ + "name": "Customer 01", + "street name": "Street 01" +} \ No newline at end of file diff --git a/json/src/test/resources/books.json b/json/src/test/resources/books.json new file mode 100644 index 0000000000..0defc3de98 --- /dev/null +++ b/json/src/test/resources/books.json @@ -0,0 +1,7 @@ +{ + "library": "My Personal Library", + "books": [ + { "title":"Title 1", "author":"Jane Doe" }, + { "title":"Title 2", "author":"John Doe" } + ] +} \ No newline at end of file diff --git a/jsonb/README.md b/jsonb/README.md deleted file mode 100644 index 9293a44808..0000000000 --- a/jsonb/README.md +++ /dev/null @@ -1,4 +0,0 @@ -## JSON B - -## Relevant articles: -- [Introduction to the JSON Binding API (JSR 367) in Java](http://www.baeldung.com/java-json-binding-api) diff --git a/jsonb/pom.xml b/jsonb/pom.xml deleted file mode 100644 index c4ef1efed6..0000000000 --- a/jsonb/pom.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - 4.0.0 - com.baeldung - json-b - 0.0.1-SNAPSHOT - jar - json-b - json-b sample project - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - javax.json.bind - javax.json.bind-api - ${jsonb-api.version} - - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - test - - - - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - test - - - org.junit.platform - junit-platform-runner - ${junit.platform.version} - test - - - - - - yasson - - true - - - - - org.eclipse - yasson - ${yasson.version} - - - org.glassfish - javax.json - ${javax.json.version} - - - - - johnzon - - - - org.apache.geronimo.specs - geronimo-json_1.1_spec - ${geronimo-json_1.1_spec.version} - - - org.apache.johnzon - johnzon-jsonb - ${johnzon.version} - - - - - - - UTF-8 - UTF-8 - 1.8 - 1.8 - 1.0.0 - 5.0.0 - 1.0 - 1.1.3 - 1.0 - 1.0.1 - 1.1.2 - 4.1 - - - \ No newline at end of file diff --git a/jsoup/pom.xml b/jsoup/pom.xml index a914b7c6ba..2704d7bc00 100644 --- a/jsoup/pom.xml +++ b/jsoup/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jsoup jar diff --git a/jta/README.md b/jta/README.md new file mode 100644 index 0000000000..445a291c8f --- /dev/null +++ b/jta/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Guide to Java EE JTA](https://www.baeldung.com/jee-jta) diff --git a/jta/pom.xml b/jta/pom.xml new file mode 100644 index 0000000000..89bdccf25e --- /dev/null +++ b/jta/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + com.baeldung + jta-demo + 1.0-SNAPSHOT + jar + + JEE JTA demo + + + org.springframework.boot + spring-boot-starter-parent + 2.0.4.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-jta-bitronix + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.hsqldb + hsqldb + 2.4.1 + + + + + + autoconfiguration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + **/*IntegrationTest.java + **/*IntTest.java + + + **/AutoconfigurationTest.java + + + + + + + json + + + + + + + + diff --git a/jta/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java b/jta/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java new file mode 100644 index 0000000000..4d8779efe5 --- /dev/null +++ b/jta/src/main/java/com/baeldung/jtademo/JtaDemoApplication.java @@ -0,0 +1,48 @@ +package com.baeldung.jtademo; + +import org.hsqldb.jdbc.pool.JDBCXADataSource; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.jta.bitronix.BitronixXADataSourceWrapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; + +@EnableAutoConfiguration +@EnableTransactionManagement +@Configuration +@ComponentScan +public class JtaDemoApplication { + + @Bean("dataSourceAccount") + public DataSource dataSource() throws Exception { + return createHsqlXADatasource("jdbc:hsqldb:mem:accountDb"); + } + + @Bean("dataSourceAudit") + public DataSource dataSourceAudit() throws Exception { + return createHsqlXADatasource("jdbc:hsqldb:mem:auditDb"); + } + + private DataSource createHsqlXADatasource(String connectionUrl) throws Exception { + JDBCXADataSource dataSource = new JDBCXADataSource(); + dataSource.setUrl(connectionUrl); + dataSource.setUser("sa"); + BitronixXADataSourceWrapper wrapper = new BitronixXADataSourceWrapper(); + return wrapper.wrapDataSource(dataSource); + } + + @Bean("jdbcTemplateAccount") + public JdbcTemplate jdbcTemplate(@Qualifier("dataSourceAccount") DataSource dataSource) { + return new JdbcTemplate(dataSource); + } + + @Bean("jdbcTemplateAudit") + public JdbcTemplate jdbcTemplateAudit(@Qualifier("dataSourceAudit") DataSource dataSource) { + return new JdbcTemplate(dataSource); + } +} diff --git a/jta/src/main/java/com/baeldung/jtademo/dto/TransferLog.java b/jta/src/main/java/com/baeldung/jtademo/dto/TransferLog.java new file mode 100644 index 0000000000..cc1474ce81 --- /dev/null +++ b/jta/src/main/java/com/baeldung/jtademo/dto/TransferLog.java @@ -0,0 +1,27 @@ +package com.baeldung.jtademo.dto; + +import java.math.BigDecimal; + +public class TransferLog { + private String fromAccountId; + private String toAccountId; + private BigDecimal amount; + + public TransferLog(String fromAccountId, String toAccountId, BigDecimal amount) { + this.fromAccountId = fromAccountId; + this.toAccountId = toAccountId; + this.amount = amount; + } + + public String getFromAccountId() { + return fromAccountId; + } + + public String getToAccountId() { + return toAccountId; + } + + public BigDecimal getAmount() { + return amount; + } +} diff --git a/jta/src/main/java/com/baeldung/jtademo/services/AuditService.java b/jta/src/main/java/com/baeldung/jtademo/services/AuditService.java new file mode 100644 index 0000000000..f6810e15c8 --- /dev/null +++ b/jta/src/main/java/com/baeldung/jtademo/services/AuditService.java @@ -0,0 +1,33 @@ +package com.baeldung.jtademo.services; + +import com.baeldung.jtademo.dto.TransferLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; + +@Service +public class AuditService { + + final JdbcTemplate jdbcTemplate; + + @Autowired + public AuditService(@Qualifier("jdbcTemplateAudit") JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public void log(String fromAccount, String toAccount, BigDecimal amount) { + jdbcTemplate.update("insert into AUDIT_LOG(FROM_ACCOUNT, TO_ACCOUNT, AMOUNT) values ?,?,?", fromAccount, toAccount, amount); + } + + public TransferLog lastTransferLog() { + return jdbcTemplate.query("select FROM_ACCOUNT,TO_ACCOUNT,AMOUNT from AUDIT_LOG order by ID desc", (ResultSetExtractor) (rs) -> { + if (!rs.next()) + return null; + return new TransferLog(rs.getString(1), rs.getString(2), BigDecimal.valueOf(rs.getDouble(3))); + }); + } +} diff --git a/jta/src/main/java/com/baeldung/jtademo/services/BankAccountService.java b/jta/src/main/java/com/baeldung/jtademo/services/BankAccountService.java new file mode 100644 index 0000000000..0c881edbaa --- /dev/null +++ b/jta/src/main/java/com/baeldung/jtademo/services/BankAccountService.java @@ -0,0 +1,32 @@ +package com.baeldung.jtademo.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ResultSetExtractor; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; + +@Service +public class BankAccountService { + + final JdbcTemplate jdbcTemplate; + + @Autowired + public BankAccountService(@Qualifier("jdbcTemplateAccount") JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public void transfer(String fromAccountId, String toAccountId, BigDecimal amount) { + jdbcTemplate.update("update ACCOUNT set BALANCE=BALANCE-? where ID=?", amount, fromAccountId); + jdbcTemplate.update("update ACCOUNT set BALANCE=BALANCE+? where ID=?", amount, toAccountId); + } + + public BigDecimal balanceOf(String accountId) { + return jdbcTemplate.query("select BALANCE from ACCOUNT where ID=?", new Object[] { accountId }, (ResultSetExtractor) (rs) -> { + rs.next(); + return new BigDecimal(rs.getDouble(1)); + }); + } +} diff --git a/jta/src/main/java/com/baeldung/jtademo/services/TellerService.java b/jta/src/main/java/com/baeldung/jtademo/services/TellerService.java new file mode 100644 index 0000000000..d3bd80a2ee --- /dev/null +++ b/jta/src/main/java/com/baeldung/jtademo/services/TellerService.java @@ -0,0 +1,45 @@ +package com.baeldung.jtademo.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import javax.transaction.UserTransaction; +import java.math.BigDecimal; + +@Service +public class TellerService { + private final BankAccountService bankAccountService; + private final AuditService auditService; + private final UserTransaction userTransaction; + + @Autowired + public TellerService(BankAccountService bankAccountService, AuditService auditService, UserTransaction userTransaction) { + this.bankAccountService = bankAccountService; + this.auditService = auditService; + this.userTransaction = userTransaction; + } + + @Transactional + public void executeTransfer(String fromAccontId, String toAccountId, BigDecimal amount) { + bankAccountService.transfer(fromAccontId, toAccountId, amount); + auditService.log(fromAccontId, toAccountId, amount); + BigDecimal balance = bankAccountService.balanceOf(fromAccontId); + if (balance.compareTo(BigDecimal.ZERO) <= 0) { + throw new RuntimeException("Insufficient fund."); + } + } + + public void executeTransferProgrammaticTx(String fromAccontId, String toAccountId, BigDecimal amount) throws Exception { + userTransaction.begin(); + bankAccountService.transfer(fromAccontId, toAccountId, amount); + auditService.log(fromAccontId, toAccountId, amount); + BigDecimal balance = bankAccountService.balanceOf(fromAccontId); + if (balance.compareTo(BigDecimal.ZERO) <= 0) { + userTransaction.rollback(); + throw new RuntimeException("Insufficient fund."); + } else { + userTransaction.commit(); + } + } +} diff --git a/jta/src/main/java/com/baeldung/jtademo/services/TestHelper.java b/jta/src/main/java/com/baeldung/jtademo/services/TestHelper.java new file mode 100644 index 0000000000..c1e8e355ec --- /dev/null +++ b/jta/src/main/java/com/baeldung/jtademo/services/TestHelper.java @@ -0,0 +1,43 @@ +package com.baeldung.jtademo.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.init.ScriptUtils; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +@Component +public class TestHelper { + final JdbcTemplate jdbcTemplateAccount; + + final JdbcTemplate jdbcTemplateAudit; + + @Autowired + public TestHelper(@Qualifier("jdbcTemplateAccount") JdbcTemplate jdbcTemplateAccount, @Qualifier("jdbcTemplateAudit") JdbcTemplate jdbcTemplateAudit) { + this.jdbcTemplateAccount = jdbcTemplateAccount; + this.jdbcTemplateAudit = jdbcTemplateAudit; + } + + public void runAccountDbInit() throws SQLException { + runScript("account.sql", jdbcTemplateAccount.getDataSource()); + } + + public void runAuditDbInit() throws SQLException { + runScript("audit.sql", jdbcTemplateAudit.getDataSource()); + } + + private void runScript(String scriptName, DataSource dataSouorce) throws SQLException { + DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); + Resource script = resourceLoader.getResource(scriptName); + try (Connection con = dataSouorce.getConnection()) { + ScriptUtils.executeSqlScript(con, script); + } + } + +} diff --git a/jta/src/main/resources/account.sql b/jta/src/main/resources/account.sql new file mode 100644 index 0000000000..af14f89b01 --- /dev/null +++ b/jta/src/main/resources/account.sql @@ -0,0 +1,9 @@ +DROP SCHEMA PUBLIC CASCADE; + +create table ACCOUNT ( +ID char(8) PRIMARY KEY, +BALANCE NUMERIC(28,10) +); + +insert into ACCOUNT(ID, BALANCE) values ('a0000001', 1000); +insert into ACCOUNT(ID, BALANCE) values ('a0000002', 2000); \ No newline at end of file diff --git a/jta/src/main/resources/application.properties b/jta/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/jta/src/main/resources/audit.sql b/jta/src/main/resources/audit.sql new file mode 100644 index 0000000000..aa5845f402 --- /dev/null +++ b/jta/src/main/resources/audit.sql @@ -0,0 +1,8 @@ +DROP SCHEMA PUBLIC CASCADE; + +create table AUDIT_LOG ( +ID INTEGER IDENTITY PRIMARY KEY, +FROM_ACCOUNT varchar(8), +TO_ACCOUNT varchar(8), +AMOUNT numeric(28,10) +); \ No newline at end of file diff --git a/jta/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java b/jta/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java new file mode 100644 index 0000000000..3f6004262b --- /dev/null +++ b/jta/src/test/java/com/baeldung/jtademo/JtaDemoUnitTest.java @@ -0,0 +1,91 @@ +package com.baeldung.jtademo; + +import com.baeldung.jtademo.dto.TransferLog; +import com.baeldung.jtademo.services.AuditService; +import com.baeldung.jtademo.services.BankAccountService; +import com.baeldung.jtademo.services.TellerService; +import com.baeldung.jtademo.services.TestHelper; +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.test.context.junit4.SpringRunner; + +import java.math.BigDecimal; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = JtaDemoApplication.class) +public class JtaDemoUnitTest { + @Autowired + TestHelper testHelper; + + @Autowired + TellerService tellerService; + + @Autowired + BankAccountService accountService; + + @Autowired + AuditService auditService; + + @Before + public void beforeTest() throws Exception { + testHelper.runAuditDbInit(); + testHelper.runAccountDbInit(); + } + + @Test + public void givenAnnotationTx_whenNoException_thenAllCommitted() throws Exception { + tellerService.executeTransfer("a0000001", "a0000002", BigDecimal.valueOf(500)); + + assertThat(accountService.balanceOf("a0000001")).isEqualByComparingTo(BigDecimal.valueOf(500)); + assertThat(accountService.balanceOf("a0000002")).isEqualByComparingTo(BigDecimal.valueOf(2500)); + + TransferLog lastTransferLog = auditService.lastTransferLog(); + assertThat(lastTransferLog).isNotNull(); + assertThat(lastTransferLog.getFromAccountId()).isEqualTo("a0000001"); + assertThat(lastTransferLog.getToAccountId()).isEqualTo("a0000002"); + assertThat(lastTransferLog.getAmount()).isEqualByComparingTo(BigDecimal.valueOf(500)); + } + + @Test + public void givenAnnotationTx_whenException_thenAllRolledBack() throws Exception { + assertThatThrownBy(() -> { + tellerService.executeTransfer("a0000002", "a0000001", BigDecimal.valueOf(100000)); + }).hasMessage("Insufficient fund."); + + assertThat(accountService.balanceOf("a0000001")).isEqualByComparingTo(BigDecimal.valueOf(1000)); + assertThat(accountService.balanceOf("a0000002")).isEqualByComparingTo(BigDecimal.valueOf(2000)); + assertThat(auditService.lastTransferLog()).isNull(); + } + + @Test + public void givenProgrammaticTx_whenCommit_thenAllCommitted() throws Exception { + tellerService.executeTransferProgrammaticTx("a0000001", "a0000002", BigDecimal.valueOf(500)); + + BigDecimal result = accountService.balanceOf("a0000001"); + assertThat(accountService.balanceOf("a0000001")).isEqualByComparingTo(BigDecimal.valueOf(500)); + assertThat(accountService.balanceOf("a0000002")).isEqualByComparingTo(BigDecimal.valueOf(2500)); + + TransferLog lastTransferLog = auditService.lastTransferLog(); + assertThat(lastTransferLog).isNotNull(); + assertThat(lastTransferLog.getFromAccountId()).isEqualTo("a0000001"); + assertThat(lastTransferLog.getToAccountId()).isEqualTo("a0000002"); + assertThat(lastTransferLog.getAmount()).isEqualByComparingTo(BigDecimal.valueOf(500)); + } + + @Test + public void givenProgrammaticTx_whenRollback_thenAllRolledBack() throws Exception { + assertThatThrownBy(() -> { + tellerService.executeTransferProgrammaticTx("a0000002", "a0000001", BigDecimal.valueOf(100000)); + }).hasMessage("Insufficient fund."); + + assertThat(accountService.balanceOf("a0000001")).isEqualByComparingTo(BigDecimal.valueOf(1000)); + assertThat(accountService.balanceOf("a0000002")).isEqualByComparingTo(BigDecimal.valueOf(2000)); + assertThat(auditService.lastTransferLog()).isNull(); + } +} diff --git a/junit5/README.md b/junit5/README.md deleted file mode 100644 index fb1685fdd5..0000000000 --- a/junit5/README.md +++ /dev/null @@ -1,2 +0,0 @@ -## Relevant articles: -- [The Order of Tests in JUnit](http://www.baeldung.com/junit-5-test-order) diff --git a/jws/pom.xml b/jws/pom.xml index 4199021060..1970ab9921 100644 --- a/jws/pom.xml +++ b/jws/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.example jws @@ -13,20 +13,23 @@ 1.0.0-SNAPSHOT + + + OpenNMS Repository + http://repo.opennms.org/maven2/ + + + - javax.jnlp + javax.samples.jnlp jnlp-servlet ${jnlp-servlet.version} - system - ${project.basedir}/java-core-samples-lib/jnlp-servlet.jar - javax.jnlp - jardiff - ${jardiff.version} - system - ${project.basedir}/java-core-samples-lib/jardiff.jar + javax.samples.jnlp + jnlp-jardiff + ${jnlp-jardiff.version} @@ -81,8 +84,8 @@ 3.0.2 3.0.0 - 7.0 - 7.0 + 1.6.0 + 1.6.0 diff --git a/jws/src/main/resources/logback.xml b/jws/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jws/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/kotlin-js/src/main/resources/logback.xml b/kotlin-js/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/kotlin-js/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/kotlin-ktor/webapp/WEB-INF/web.xml b/kotlin-ktor/webapp/WEB-INF/web.xml deleted file mode 100755 index 513a80cb27..0000000000 --- a/kotlin-ktor/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - io.ktor.ktor.config - application.conf - - - - KtorServlet - KtorServlet - io.ktor.server.servlet.ServletApplicationEngine - - - true - - - - 304857600 - 304857600 - 0 - - - - - KtorServlet - / - - - \ No newline at end of file diff --git a/kotlin-libraries/.gitignore b/kotlin-libraries/.gitignore new file mode 100644 index 0000000000..0c017e8f8c --- /dev/null +++ b/kotlin-libraries/.gitignore @@ -0,0 +1,14 @@ +/bin/ + +#ignore gradle +.gradle/ + + +#ignore build and generated files +build/ +node/ +out/ + +#ignore installed node modules and package lock file +node_modules/ +package-lock.json diff --git a/kotlin-libraries/README.md b/kotlin-libraries/README.md new file mode 100644 index 0000000000..30c4d03ded --- /dev/null +++ b/kotlin-libraries/README.md @@ -0,0 +1,9 @@ +## Relevant articles: + +- [Kotlin with Mockito](http://www.baeldung.com/kotlin-mockito) +- [HTTP Requests with Kotlin and khttp](http://www.baeldung.com/kotlin-khttp) +- [Kotlin Dependency Injection with Kodein](http://www.baeldung.com/kotlin-kodein-dependency-injection) +- [Writing Specifications with Kotlin and Spek](http://www.baeldung.com/kotlin-spek) +- [Processing JSON with Kotlin and Klaxson](http://www.baeldung.com/kotlin-json-klaxson) +- [Kotlin with Ktor](http://www.baeldung.com/kotlin-ktor) +- [Guide to the Kotlin Exposed Framework](https://www.baeldung.com/kotlin-exposed-persistence) diff --git a/kotlin-ktor/build.gradle b/kotlin-libraries/build.gradle old mode 100755 new mode 100644 similarity index 83% rename from kotlin-ktor/build.gradle rename to kotlin-libraries/build.gradle index 5c8f523cf1..b244df34b0 --- a/kotlin-ktor/build.gradle +++ b/kotlin-libraries/build.gradle @@ -1,47 +1,57 @@ - - -group 'com.baeldung.ktor' -version '1.0-SNAPSHOT' - - -buildscript { - ext.kotlin_version = '1.2.41' - ext.ktor_version = '0.9.2' - - repositories { - mavenCentral() - } - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -apply plugin: 'java' -apply plugin: 'kotlin' -apply plugin: 'application' - -mainClassName = 'APIServer.kt' - -sourceCompatibility = 1.8 -compileKotlin { kotlinOptions.jvmTarget = "1.8" } -compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } - -kotlin { experimental { coroutines "enable" } } - -repositories { - mavenCentral() - jcenter() - maven { url "https://dl.bintray.com/kotlin/ktor" } -} - -dependencies { - compile "io.ktor:ktor-server-netty:$ktor_version" - compile "ch.qos.logback:logback-classic:1.2.1" - compile "io.ktor:ktor-gson:$ktor_version" - testCompile group: 'junit', name: 'junit', version: '4.12' - -} -task runServer(type: JavaExec) { - main = 'APIServer' - classpath = sourceSets.main.runtimeClasspath + + +group 'com.baeldung.ktor' +version '1.0-SNAPSHOT' + + +buildscript { + ext.kotlin_version = '1.2.41' + ext.ktor_version = '0.9.2' + + repositories { + mavenCentral() + } + dependencies { + + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'java' +apply plugin: 'kotlin' +apply plugin: 'application' + +mainClassName = 'APIServer.kt' + +sourceCompatibility = 1.8 +compileKotlin { kotlinOptions.jvmTarget = "1.8" } +compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } + +kotlin { experimental { coroutines "enable" } } + +repositories { + mavenCentral() + jcenter() + maven { url "https://dl.bintray.com/kotlin/ktor" } +} +sourceSets { + main{ + kotlin{ + srcDirs 'com/baeldung/ktor' + } + } + +} + +dependencies { + compile "io.ktor:ktor-server-netty:$ktor_version" + compile "ch.qos.logback:logback-classic:1.2.1" + compile "io.ktor:ktor-gson:$ktor_version" + testCompile group: 'junit', name: 'junit', version: '4.12' + implementation 'com.beust:klaxon:3.0.1' + +} +task runServer(type: JavaExec) { + main = 'APIServer' + classpath = sourceSets.main.runtimeClasspath } \ No newline at end of file diff --git a/kotlin-libraries/gradle/wrapper/gradle-wrapper.jar b/kotlin-libraries/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..01b8bf6b1f Binary files /dev/null and b/kotlin-libraries/gradle/wrapper/gradle-wrapper.jar differ diff --git a/kotlin-libraries/gradle/wrapper/gradle-wrapper.properties b/kotlin-libraries/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..933b6473ce --- /dev/null +++ b/kotlin-libraries/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip diff --git a/kotlin-libraries/gradlew b/kotlin-libraries/gradlew new file mode 100644 index 0000000000..cccdd3d517 --- /dev/null +++ b/kotlin-libraries/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/kotlin-libraries/gradlew.bat b/kotlin-libraries/gradlew.bat new file mode 100644 index 0000000000..f9553162f1 --- /dev/null +++ b/kotlin-libraries/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/kotlin-libraries/pom.xml b/kotlin-libraries/pom.xml new file mode 100644 index 0000000000..c5b7fed951 --- /dev/null +++ b/kotlin-libraries/pom.xml @@ -0,0 +1,105 @@ + + + 4.0.0 + kotlin-libraries + jar + + + com.baeldung + parent-kotlin + 1.0.0-SNAPSHOT + ../parent-kotlin + + + + + exposed + exposed + https://dl.bintray.com/kotlin/exposed + + + + + + org.jetbrains.spek + spek-api + 1.1.5 + test + + + org.jetbrains.spek + spek-subject-extension + 1.1.5 + test + + + org.jetbrains.spek + spek-junit-platform-engine + 1.1.5 + test + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + khttp + khttp + ${khttp.version} + + + com.nhaarman + mockito-kotlin + ${mockito-kotlin.version} + test + + + com.github.salomonbrys.kodein + kodein + ${kodein.version} + + + org.assertj + assertj-core + ${assertj.version} + test + + + com.beust + klaxon + ${klaxon.version} + + + org.jetbrains.exposed + exposed + ${exposed.version} + + + com.h2database + h2 + ${h2database.version} + + + + + 1.5.0 + 4.1.0 + 3.0.4 + 0.1.0 + 3.6.1 + 1.1.1 + 5.2.0 + 3.10.0 + 1.4.197 + 0.10.4 + + + \ No newline at end of file diff --git a/kotlin-libraries/resources/logback.xml b/kotlin-libraries/resources/logback.xml new file mode 100644 index 0000000000..9452207268 --- /dev/null +++ b/kotlin-libraries/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/kotlin-libraries/settings.gradle b/kotlin-libraries/settings.gradle new file mode 100644 index 0000000000..c91c993971 --- /dev/null +++ b/kotlin-libraries/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'KtorWithKotlin' + diff --git a/core-kotlin/src/main/kotlin/com/baeldung/klaxon/CustomProduct.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/klaxon/CustomProduct.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/klaxon/CustomProduct.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/klaxon/CustomProduct.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/klaxon/Product.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/klaxon/Product.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/klaxon/Product.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/klaxon/Product.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/klaxon/ProductData.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/klaxon/ProductData.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/klaxon/ProductData.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/klaxon/ProductData.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt similarity index 100% rename from core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt diff --git a/kotlin-ktor/src/main/kotlin/APIServer.kt b/kotlin-libraries/src/main/kotlin/com/baeldung/ktor/APIServer.kt similarity index 95% rename from kotlin-ktor/src/main/kotlin/APIServer.kt rename to kotlin-libraries/src/main/kotlin/com/baeldung/ktor/APIServer.kt index 57ccbbe523..a12182ccc8 100755 --- a/kotlin-ktor/src/main/kotlin/APIServer.kt +++ b/kotlin-libraries/src/main/kotlin/com/baeldung/ktor/APIServer.kt @@ -33,7 +33,7 @@ fun main(args: Array) { header("X-Developer", "Baeldung") } install(CallLogging) { - level = Level.INFO + level = Level.DEBUG filter { call -> call.request.path().startsWith("/todo") } filter { call -> call.request.path().startsWith("/author") } } diff --git a/core-kotlin/src/test/kotlin/com/baeldung/klaxon/KlaxonUnitTest.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/klaxon/KlaxonUnitTest.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/klaxon/KlaxonUnitTest.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/klaxon/KlaxonUnitTest.kt diff --git a/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/exposed/ExposedTest.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/exposed/ExposedTest.kt new file mode 100644 index 0000000000..29fa18ef7a --- /dev/null +++ b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/exposed/ExposedTest.kt @@ -0,0 +1,333 @@ +package com.baeldung.kotlin.exposed + +import org.jetbrains.exposed.dao.* +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.transactions.TransactionManager +import org.jetbrains.exposed.sql.transactions.transaction +import org.junit.Test +import java.sql.DriverManager +import kotlin.test.* + +class ExposedTest { + + @Test + fun whenH2Database_thenConnectionSuccessful() { + val database = Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + transaction { + assertEquals(1.4.toBigDecimal(), database.version) + assertEquals("h2", database.vendor) + } + } + + @Test + fun whenH2DatabaseWithCredentials_thenConnectionSuccessful() { + Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver", user = "myself", password = "secret") + } + + @Test + fun whenH2DatabaseWithManualConnection_thenConnectionSuccessful() { + var connected = false + Database.connect({ connected = true; DriverManager.getConnection("jdbc:h2:mem:test;MODE=MySQL") }) + assertEquals(false, connected) + transaction { + addLogger(StdOutSqlLogger) + assertEquals(false, connected) + SchemaUtils.create(Cities) + assertEquals(true, connected) + } + } + + @Test + fun whenManualCommit_thenOk() { + Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + transaction { + assertTrue(this is Transaction) + commit() + commit() + commit() + } + } + + @Test + fun whenInsert_thenGeneratedKeys() { + Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + transaction { + SchemaUtils.create(StarWarsFilms) + val id = StarWarsFilms.insertAndGetId { + it[name] = "The Last Jedi" + it[sequelId] = 8 + it[director] = "Rian Johnson" + } + assertEquals(1, id.value) + val insert = StarWarsFilms.insert { + it[name] = "The Force Awakens" + it[sequelId] = 7 + it[director] = "J.J. Abrams" + } + assertEquals(2, insert[StarWarsFilms.id]?.value) + val selectAll = StarWarsFilms.selectAll() + selectAll.forEach { + assertTrue { it[StarWarsFilms.sequelId] >= 7 } + } + StarWarsFilms.slice(StarWarsFilms.name, StarWarsFilms.director).selectAll() + .forEach { + assertTrue { it[StarWarsFilms.name].startsWith("The") } + } + val select = StarWarsFilms.select { (StarWarsFilms.director like "J.J.%") and (StarWarsFilms.sequelId eq 7) } + assertEquals(1, select.count()) + StarWarsFilms.update ({ StarWarsFilms.sequelId eq 8 }) { + it[name] = "Episode VIII – The Last Jedi" + with(SqlExpressionBuilder) { + it.update(StarWarsFilms.sequelId, StarWarsFilms.sequelId + 1) + } + } + } + } + + @Test + fun whenForeignKey_thenAutoJoin() { + Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + transaction { + addLogger(StdOutSqlLogger) + SchemaUtils.create(StarWarsFilms, Players) + StarWarsFilms.insert { + it[name] = "The Last Jedi" + it[sequelId] = 8 + it[director] = "Rian Johnson" + } + StarWarsFilms.insert { + it[name] = "The Force Awakens" + it[sequelId] = 7 + it[director] = "J.J. Abrams" + } + Players.insert { + it[name] = "Mark Hamill" + it[sequelId] = 7 + } + Players.insert { + it[name] = "Mark Hamill" + it[sequelId] = 8 + } + val simpleInnerJoin = (StarWarsFilms innerJoin Players).selectAll() + assertEquals(2, simpleInnerJoin.count()) + simpleInnerJoin.forEach { + assertNotNull(it[StarWarsFilms.name]) + assertEquals(it[StarWarsFilms.sequelId], it[Players.sequelId]) + assertEquals("Mark Hamill", it[Players.name]) + } + val innerJoinWithCondition = (StarWarsFilms innerJoin Players) + .select { StarWarsFilms.sequelId eq Players.sequelId } + assertEquals(2, innerJoinWithCondition.count()) + innerJoinWithCondition.forEach { + assertNotNull(it[StarWarsFilms.name]) + assertEquals(it[StarWarsFilms.sequelId], it[Players.sequelId]) + assertEquals("Mark Hamill", it[Players.name]) + } + val complexInnerJoin = Join(StarWarsFilms, Players, joinType = JoinType.INNER, onColumn = StarWarsFilms.sequelId, otherColumn = Players.sequelId, additionalConstraint = { + StarWarsFilms.sequelId eq 8 + }).selectAll() + assertEquals(1, complexInnerJoin.count()) + complexInnerJoin.forEach { + assertNotNull(it[StarWarsFilms.name]) + assertEquals(it[StarWarsFilms.sequelId], it[Players.sequelId]) + assertEquals("Mark Hamill", it[Players.name]) + } + + } + } + + @Test + fun whenJoinWithAlias_thenFun() { + Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + transaction { + addLogger(StdOutSqlLogger) + SchemaUtils.create(StarWarsFilms, Players) + StarWarsFilms.insert { + it[name] = "The Last Jedi" + it[sequelId] = 8 + it[director] = "Rian Johnson" + } + StarWarsFilms.insert { + it[name] = "The Force Awakens" + it[sequelId] = 7 + it[director] = "J.J. Abrams" + } + val sequel = StarWarsFilms.alias("sequel") + Join(StarWarsFilms, sequel, + additionalConstraint = { sequel[StarWarsFilms.sequelId] eq StarWarsFilms.sequelId + 1 }) + .selectAll().forEach { + assertEquals(it[sequel[StarWarsFilms.sequelId]], it[StarWarsFilms.sequelId] + 1) + } + } + } + + @Test + fun whenEntity_thenDAO() { + val database = Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + val connection = database.connector.invoke() //Keep a connection open so the DB is not destroyed after the first transaction + val inserted = transaction { + addLogger(StdOutSqlLogger) + SchemaUtils.create(StarWarsFilms, Players) + val theLastJedi = StarWarsFilm.new { + name = "The Last Jedi" + sequelId = 8 + director = "Rian Johnson" + } + assertFalse(TransactionManager.current().entityCache.inserts.isEmpty()) + assertEquals(1, theLastJedi.id.value) //Reading this causes a flush + assertTrue(TransactionManager.current().entityCache.inserts.isEmpty()) + theLastJedi + } + transaction { + val theLastJedi = StarWarsFilm.findById(1) + assertNotNull(theLastJedi) + assertEquals(inserted.id, theLastJedi?.id) + } + connection.close() + } + + @Test + fun whenManyToOne_thenNavigation() { + val database = Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + val connection = database.connector.invoke() + transaction { + addLogger(StdOutSqlLogger) + SchemaUtils.create(StarWarsFilms, Players, Users, UserRatings) + val theLastJedi = StarWarsFilm.new { + name = "The Last Jedi" + sequelId = 8 + director = "Rian Johnson" + } + val someUser = User.new { + name = "Some User" + } + val rating = UserRating.new { + value = 9 + user = someUser + film = theLastJedi + } + assertEquals(theLastJedi, rating.film) + assertEquals(someUser, rating.user) + assertEquals(rating, theLastJedi.ratings.first()) + } + transaction { + val theLastJedi = StarWarsFilm.find { StarWarsFilms.sequelId eq 8 }.first() + val ratings = UserRating.find { UserRatings.film eq theLastJedi.id } + assertEquals(1, ratings.count()) + val rating = ratings.first() + assertEquals("Some User", rating.user.name) + assertEquals(rating, theLastJedi.ratings.first()) + UserRating.new { + value = 8 + user = rating.user + film = theLastJedi + } + assertEquals(2, theLastJedi.ratings.count()) + } + connection.close() + } + + @Test + fun whenManyToMany_thenAssociation() { + val database = Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + val connection = database.connector.invoke() + val film = transaction { + SchemaUtils.create(StarWarsFilms) + StarWarsFilm.new { + name = "The Last Jedi" + sequelId = 8 + director = "Rian Johnson" + } + } + + val actor = transaction { + SchemaUtils.create(Actors) + Actor.new { + firstname = "Daisy" + lastname = "Ridley" + } + } + + transaction { + SchemaUtils.create(StarWarsFilmActors) + film.actors = SizedCollection(listOf(actor)) + } + connection.close() + } + +} + +object Cities: IntIdTable() { + val name = varchar("name", 50) +} + +object StarWarsFilms_Simple : Table() { + val id = integer("id").autoIncrement().primaryKey() + val sequelId = integer("sequel_id").uniqueIndex() + val name = varchar("name", 50) + val director = varchar("director", 50) +} + +object StarWarsFilms : IntIdTable() { + val sequelId = integer("sequel_id").uniqueIndex() + val name = varchar("name", 50) + val director = varchar("director", 50) +} + +object Players : Table() { + //val sequelId = integer("sequel_id").uniqueIndex().references(StarWarsFilms.sequelId) + val sequelId = reference("sequel_id", StarWarsFilms.sequelId).uniqueIndex() + //val filmId = reference("film_id", StarWarsFilms).nullable() + val name = varchar("name", 50) +} + +class StarWarsFilm(id: EntityID) : Entity(id) { + companion object : EntityClass(StarWarsFilms) + + var sequelId by StarWarsFilms.sequelId + var name by StarWarsFilms.name + var director by StarWarsFilms.director + var actors by Actor via StarWarsFilmActors + val ratings by UserRating referrersOn UserRatings.film +} + +object Users: IntIdTable() { + val name = varchar("name", 50) +} + +object UserRatings: IntIdTable() { + val value = long("value") + val film = reference("film", StarWarsFilms) + val user = reference("user", Users) +} + +class User(id: EntityID): IntEntity(id) { + companion object : IntEntityClass(Users) + + var name by Users.name +} + +class UserRating(id: EntityID): IntEntity(id) { + companion object : IntEntityClass(UserRatings) + + var value by UserRatings.value + var film by StarWarsFilm referencedOn UserRatings.film + var user by User referencedOn UserRatings.user +} + +object Actors: IntIdTable() { + val firstname = varchar("firstname", 50) + val lastname = varchar("lastname", 50) +} + +class Actor(id: EntityID): IntEntity(id) { + companion object : IntEntityClass(Actors) + + var firstname by Actors.firstname + var lastname by Actors.lastname +} + +object StarWarsFilmActors : Table() { + val starWarsFilm = reference("starWarsFilm", StarWarsFilms).primaryKey(0) + val actor = reference("actor", Actors).primaryKey(1) +} \ No newline at end of file diff --git a/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/junit5/Calculator.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/junit5/Calculator.kt new file mode 100644 index 0000000000..1b61c05887 --- /dev/null +++ b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/junit5/Calculator.kt @@ -0,0 +1,17 @@ +package com.baeldung.kotlin.junit5 + +class Calculator { + fun add(a: Int, b: Int) = a + b + + fun divide(a: Int, b: Int) = if (b == 0) { + throw DivideByZeroException(a) + } else { + a / b + } + + fun square(a: Int) = a * a + + fun squareRoot(a: Int) = Math.sqrt(a.toDouble()) + + fun log(base: Int, value: Int) = Math.log(value.toDouble()) / Math.log(base.toDouble()) +} diff --git a/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/junit5/DivideByZeroException.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/junit5/DivideByZeroException.kt new file mode 100644 index 0000000000..60bc4e2944 --- /dev/null +++ b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/junit5/DivideByZeroException.kt @@ -0,0 +1,3 @@ +package com.baeldung.kotlin.junit5 + +class DivideByZeroException(val numerator: Int) : Exception() diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/khttp/KhttpTest.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/khttp/KhttpLiveTest.kt similarity index 99% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/khttp/KhttpTest.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/khttp/KhttpLiveTest.kt index e9147c9489..4deb576b9f 100644 --- a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/khttp/KhttpTest.kt +++ b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/khttp/KhttpLiveTest.kt @@ -12,7 +12,7 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue import kotlin.test.fail -class KhttpTest { +class KhttpLiveTest { @Test fun whenHttpGetRequestIsMade_thenArgsAreReturned() { diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorSubjectTest5.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorSubjectTest5.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorSubjectTest5.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorSubjectTest5.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorTest5.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorTest5.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorTest5.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorTest5.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/DataDrivenTest5.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/spek/DataDrivenTest5.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/DataDrivenTest5.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/spek/DataDrivenTest5.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/GroupTest5.kt b/kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/spek/GroupTest5.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/GroupTest5.kt rename to kotlin-libraries/src/test/kotlin/com/baeldung/kotlin/spek/GroupTest5.kt diff --git a/lagom/greeting-api/src/main/resources/logback.xml b/lagom/greeting-api/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/lagom/greeting-api/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/lagom/greeting-impl/src/main/resources/logback.xml b/lagom/greeting-impl/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/lagom/greeting-impl/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/lagom/weather-api/src/main/resources/logback.xml b/lagom/weather-api/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/lagom/weather-api/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/lagom/weather-impl/src/main/resources/logback.xml b/lagom/weather-impl/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/lagom/weather-impl/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/libraries-data/README.md b/libraries-data/README.md index 718f38d703..63ee5f9947 100644 --- a/libraries-data/README.md +++ b/libraries-data/README.md @@ -8,4 +8,7 @@ - [Introduction to HikariCP](http://www.baeldung.com/hikaricp) - [Introduction to JCache](http://www.baeldung.com/jcache) - [A Guide to Apache Ignite](http://www.baeldung.com/apache-ignite) -- [Apache Ignite with Spring Data](http://www.baeldung.com/apache-ignite-spring-data) \ No newline at end of file +- [Apache Ignite with Spring Data](http://www.baeldung.com/apache-ignite-spring-data) +- [Guide to JMapper](https://www.baeldung.com/jmapper) +- [A Guide to Apache Crunch](https://www.baeldung.com/apache-crunch) +- [Building a Data Pipeline with Flink and Kafka](https://www.baeldung.com/kafka-flink-data-pipeline) diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index f1531a8eae..bbf0c7832f 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 libraries-data libraries-data @@ -87,48 +87,48 @@ gson ${gson.version} - + com.zaxxer HikariCP - 2.7.2 + ${HikariCP.version} compile org.datanucleus javax.jdo - 3.2.0-m7 + ${javax.jdo.version} org.datanucleus datanucleus-core - 5.1.1 + ${datanucleus.version} org.datanucleus datanucleus-api-jdo - 5.1.1 + ${datanucleus.version} org.datanucleus datanucleus-rdbms - 5.1.1 + ${datanucleus.version} org.datanucleus datanucleus-maven-plugin - 5.0.2 + ${datanucleus-maven-plugin.version} org.datanucleus datanucleus-xml - 5.0.0-release + ${datanucleus-xml.version} org.datanucleus datanucleus-jdo-query - 5.0.4 + ${datanucleus-jdo-query.version} @@ -141,6 +141,140 @@ hazelcast ${hazelcast.version} + + + com.googlecode.jmapper-framework + jmapper-core + ${jmapper.version} + + + + org.apache.crunch + crunch-core + ${org.apache.crunch.crunch-core.version} + + + org.apache.hadoop + hadoop-client + ${org.apache.hadoop.hadoop-client} + provided + + + + commons-cli + commons-cli + 1.2 + provided + + + commons-io + commons-io + 2.1 + provided + + + commons-httpclient + commons-httpclient + 3.0.1 + provided + + + commons-codec + commons-codec + + + + + org.apache.flink + flink-connector-kafka-0.11_2.11 + ${flink.version} + + + org.apache.flink + flink-streaming-java_2.11 + ${flink.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + org.apache.flink + flink-core + ${flink.version} + + + commons-logging + commons-logging + + + + + org.apache.flink + flink-java + ${flink.version} + + + commons-logging + commons-logging + + + + + org.apache.flink + flink-test-utils_2.11 + ${flink.version} + test + + + org.assertj + assertj-core + ${assertj.version} + + + org.awaitility + awaitility + ${awaitility.version} + test + + + org.awaitility + awaitility-proxy + ${awaitility.version} + test + + + io.ebean + ebean + ${ebean.version} + + + org.slf4j + slf4j-api + ${slf4j.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + ch.qos.logback + logback-core + ${logback.version} + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + @@ -159,24 +293,16 @@ - - - + + + - - + + - + @@ -234,7 +360,7 @@ org.datanucleus datanucleus-maven-plugin - 5.0.2 + ${datanucleus-maven-plugin.version} JDO ${basedir}/datanucleus.properties @@ -253,6 +379,48 @@ + + org.apache.maven.plugins + maven-assembly-plugin + 2.3 + + + src/main/assembly/hadoop-job.xml + + + + com.baeldung.crunch.WordCount + + + + + + make-assembly + package + + single + + + + + + io.ebean + ebean-maven-plugin + 11.11.2 + + + + main + process-classes + + debug=1 + + + enhance + + + + @@ -274,9 +442,25 @@ 2.4.0 2.8.2 1.1.0 - 3.8.4 + 1.5.0 + 2.8.5 + 3.0.0 + 3.6.2 + 3.8.4 1.8 3.0.0 + 2.7.2 + 3.2.0-m7 + 5.1.1 + 5.0.2 + 5.0.0-release + 5.0.4 + 1.6.0.1 + 0.15.0 + 2.2.0 + 11.22.4 + 1.7.25 + 1.0.1 diff --git a/libraries-data/src/main/assembly/hadoop-job.xml b/libraries-data/src/main/assembly/hadoop-job.xml new file mode 100644 index 0000000000..1917e1e5a3 --- /dev/null +++ b/libraries-data/src/main/assembly/hadoop-job.xml @@ -0,0 +1,28 @@ + + + + + job + + jar + + false + + + false + runtime + lib + + ${groupId}:${artifactId} + + + + true + + ${groupId}:${artifactId} + + + + diff --git a/libraries-data/src/main/java/com/baeldung/crunch/StopWordFilter.java b/libraries-data/src/main/java/com/baeldung/crunch/StopWordFilter.java new file mode 100644 index 0000000000..bdd606e179 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/crunch/StopWordFilter.java @@ -0,0 +1,25 @@ +package com.baeldung.crunch; + +import java.util.Set; + +import org.apache.crunch.FilterFn; + +import com.google.common.collect.ImmutableSet; + +/** + * A filter that removes known stop words. + */ +public class StopWordFilter extends FilterFn { + + // English stop words, borrowed from Lucene. + private static final Set STOP_WORDS = ImmutableSet + .copyOf(new String[] { "a", "and", "are", "as", "at", "be", "but", "by", + "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", + "or", "s", "such", "t", "that", "the", "their", "then", "there", + "these", "they", "this", "to", "was", "will", "with" }); + + @Override + public boolean accept(String word) { + return !STOP_WORDS.contains(word); + } +} diff --git a/libraries-data/src/main/java/com/baeldung/crunch/ToUpperCaseFn.java b/libraries-data/src/main/java/com/baeldung/crunch/ToUpperCaseFn.java new file mode 100644 index 0000000000..a277883ad3 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/crunch/ToUpperCaseFn.java @@ -0,0 +1,11 @@ +package com.baeldung.crunch; + +import org.apache.crunch.MapFn; + +public class ToUpperCaseFn extends MapFn { + + @Override + public String map(String input) { + return input != null ? input.toUpperCase() : input; + } +} diff --git a/libraries-data/src/main/java/com/baeldung/crunch/ToUpperCaseWithCounterFn.java b/libraries-data/src/main/java/com/baeldung/crunch/ToUpperCaseWithCounterFn.java new file mode 100644 index 0000000000..f753f98866 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/crunch/ToUpperCaseWithCounterFn.java @@ -0,0 +1,20 @@ +package com.baeldung.crunch; + +import org.apache.crunch.MapFn; + +@SuppressWarnings("serial") +public class ToUpperCaseWithCounterFn extends MapFn { + + @Override + public String map(String input) { + if (input == null) { + return input; + } else { + String output = input.toUpperCase(); + if (!input.equals(output)) { + increment("UpperCase", "modified"); + } + return output; + } + } +} diff --git a/libraries-data/src/main/java/com/baeldung/crunch/Tokenizer.java b/libraries-data/src/main/java/com/baeldung/crunch/Tokenizer.java new file mode 100644 index 0000000000..9523634be1 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/crunch/Tokenizer.java @@ -0,0 +1,23 @@ +package com.baeldung.crunch; + +import org.apache.crunch.DoFn; +import org.apache.crunch.Emitter; + +import com.google.common.base.Splitter; + +/** + * Splits a line of text, filtering known stop words. + */ +public class Tokenizer extends DoFn { + private static final Splitter SPLITTER = Splitter + .onPattern("\\s+") + .omitEmptyStrings(); + + @Override + public void process(String line, + Emitter emitter) { + for (String word : SPLITTER.split(line)) { + emitter.emit(word); + } + } +} diff --git a/libraries-data/src/main/java/com/baeldung/crunch/WordCount.java b/libraries-data/src/main/java/com/baeldung/crunch/WordCount.java new file mode 100644 index 0000000000..c49abec68a --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/crunch/WordCount.java @@ -0,0 +1,62 @@ +package com.baeldung.crunch; + +import org.apache.crunch.PCollection; +import org.apache.crunch.PTable; +import org.apache.crunch.Pipeline; +import org.apache.crunch.PipelineResult; +import org.apache.crunch.impl.mr.MRPipeline; +import org.apache.crunch.types.writable.Writables; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.conf.Configured; +import org.apache.hadoop.util.GenericOptionsParser; +import org.apache.hadoop.util.Tool; +import org.apache.hadoop.util.ToolRunner; + +/** + * A word count example for Apache Crunch, based on Crunch's example projects. + */ +public class WordCount extends Configured implements Tool { + + public static void main(String[] args) throws Exception { + ToolRunner.run(new Configuration(), new WordCount(), args); + } + + public int run(String[] args) throws Exception { + + if (args.length != 2) { + System.err.println("Usage: hadoop jar crunch-1.0.0-SNAPSHOT-job.jar" + " [generic options] input output"); + System.err.println(); + GenericOptionsParser.printGenericCommandUsage(System.err); + return 1; + } + + String inputPath = args[0]; + String outputPath = args[1]; + + // Create an object to coordinate pipeline creation and execution. + Pipeline pipeline = new MRPipeline(WordCount.class, getConf()); + + // Reference a given text file as a collection of Strings. + PCollection lines = pipeline.readTextFile(inputPath); + + // Define a function that splits each line in a PCollection of Strings into + // a PCollection made up of the individual words in the file. + // The second argument sets the serialization format. + PCollection words = lines.parallelDo(new Tokenizer(), Writables.strings()); + + // Take the collection of words and remove known stop words. + PCollection noStopWords = words.filter(new StopWordFilter()); + + // The count method applies a series of Crunch primitives and returns + // a map of the unique words in the input PCollection to their counts. + PTable counts = noStopWords.count(); + + // Instruct the pipeline to write the resulting counts to a text file. + pipeline.writeTextFile(counts, outputPath); + + // Execute the pipeline as a MapReduce. + PipelineResult result = pipeline.done(); + + return result.succeeded() ? 0 : 1; + } +} diff --git a/libraries-data/src/main/java/com/baeldung/ebean/app/App.java b/libraries-data/src/main/java/com/baeldung/ebean/app/App.java new file mode 100644 index 0000000000..44a4fa8562 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ebean/app/App.java @@ -0,0 +1,75 @@ +package com.baeldung.ebean.app; + +import java.util.Arrays; + +import com.baeldung.ebean.model.Address; +import com.baeldung.ebean.model.Customer; + +import io.ebean.Ebean; +import io.ebean.EbeanServer; +import io.ebean.annotation.Transactional; + +public class App { + + public static void main(String[] args) { + insertAndDeleteInsideTransaction(); + crudOperations(); + queryCustomers(); + } + + @Transactional + public static void insertAndDeleteInsideTransaction() { + + Customer c1 = getCustomer(); + EbeanServer server = Ebean.getDefaultServer(); + server.save(c1); + Customer foundC1 = server.find(Customer.class, c1.getId()); + server.delete(foundC1); + } + + public static void crudOperations() { + + Address a1 = new Address("5, Wide Street", null, "New York"); + Customer c1 = new Customer("John Wide", a1); + + EbeanServer server = Ebean.getDefaultServer(); + server.save(c1); + + c1.setName("Jane Wide"); + c1.setAddress(null); + server.save(c1); + + Customer foundC1 = Ebean.find(Customer.class, c1.getId()); + + Ebean.delete(foundC1); + } + + public static void queryCustomers() { + Address a1 = new Address("1, Big Street", null, "New York"); + Customer c1 = new Customer("Big John", a1); + + Address a2 = new Address("2, Big Street", null, "New York"); + Customer c2 = new Customer("Big John", a2); + + Address a3 = new Address("3, Big Street", null, "San Jose"); + Customer c3 = new Customer("Big Bob", a3); + + Ebean.saveAll(Arrays.asList(c1, c2, c3)); + + Customer customer = Ebean.find(Customer.class) + .select("name") + .fetch("address", "city") + .where() + .eq("city", "San Jose") + .findOne(); + + Ebean.deleteAll(Arrays.asList(c1, c2, c3)); + } + + private static Customer getCustomer() { + Address a1 = new Address("1, Big Street", null, "New York"); + Customer c1 = new Customer("Big John", a1); + return c1; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/ebean/app/App2.java b/libraries-data/src/main/java/com/baeldung/ebean/app/App2.java new file mode 100644 index 0000000000..fba77007c6 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ebean/app/App2.java @@ -0,0 +1,26 @@ +package com.baeldung.ebean.app; + +import java.util.Properties; + +import io.ebean.EbeanServer; +import io.ebean.EbeanServerFactory; +import io.ebean.config.ServerConfig; + +public class App2 { + + public static void main(String[] args) { + ServerConfig cfg = new ServerConfig(); + cfg.setDefaultServer(true); + Properties properties = new Properties(); + properties.put("ebean.db.ddl.generate", "true"); + properties.put("ebean.db.ddl.run", "true"); + properties.put("datasource.db.username", "sa"); + properties.put("datasource.db.password", ""); + properties.put("datasource.db.databaseUrl", "jdbc:h2:mem:app2"); + properties.put("datasource.db.databaseDriver", "org.h2.Driver"); + cfg.loadFromProperties(properties); + EbeanServer server = EbeanServerFactory.create(cfg); + + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/ebean/model/Address.java b/libraries-data/src/main/java/com/baeldung/ebean/model/Address.java new file mode 100644 index 0000000000..dfcd90ffa7 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ebean/model/Address.java @@ -0,0 +1,48 @@ +package com.baeldung.ebean.model; + +import javax.persistence.Entity; + +@Entity +public class Address extends BaseModel { + + public Address(String addressLine1, String addressLine2, String city) { + super(); + this.addressLine1 = addressLine1; + this.addressLine2 = addressLine2; + this.city = city; + } + + private String addressLine1; + private String addressLine2; + private String city; + + public String getAddressLine1() { + return addressLine1; + } + + public void setAddressLine1(String addressLine1) { + this.addressLine1 = addressLine1; + } + + public String getAddressLine2() { + return addressLine2; + } + + public void setAddressLine2(String addressLine2) { + this.addressLine2 = addressLine2; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + @Override + public String toString() { + return "Address [id=" + id + ", addressLine1=" + addressLine1 + ", addressLine2=" + addressLine2 + ", city=" + city + "]"; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/ebean/model/BaseModel.java b/libraries-data/src/main/java/com/baeldung/ebean/model/BaseModel.java new file mode 100644 index 0000000000..547d5bf075 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ebean/model/BaseModel.java @@ -0,0 +1,59 @@ +package com.baeldung.ebean.model; + +import java.time.Instant; + +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Version; + +import io.ebean.annotation.WhenCreated; +import io.ebean.annotation.WhenModified; + +@MappedSuperclass +public abstract class BaseModel { + + @Id + protected long id; + + @Version + protected long version; + + @WhenCreated + protected Instant createdOn; + + @WhenModified + protected Instant modifiedOn; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Instant getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(Instant createdOn) { + this.createdOn = createdOn; + } + + public Instant getModifiedOn() { + return modifiedOn; + } + + public void setModifiedOn(Instant modifiedOn) { + this.modifiedOn = modifiedOn; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/ebean/model/Customer.java b/libraries-data/src/main/java/com/baeldung/ebean/model/Customer.java new file mode 100644 index 0000000000..4dd629245a --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ebean/model/Customer.java @@ -0,0 +1,42 @@ +package com.baeldung.ebean.model; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.OneToOne; + +@Entity +public class Customer extends BaseModel { + + public Customer(String name, Address address) { + super(); + this.name = name; + this.address = address; + } + + private String name; + + @OneToOne(cascade = CascadeType.ALL) + Address address; + + 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; + } + + @Override + public String toString() { + return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]"; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java b/libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java new file mode 100644 index 0000000000..d02b1bcb83 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java @@ -0,0 +1,82 @@ +package com.baeldung.flink; + + +import com.baeldung.flink.model.Backup; +import com.baeldung.flink.model.InputMessage; +import com.baeldung.flink.operator.BackupAggregator; +import com.baeldung.flink.operator.InputMessageTimestampAssigner; +import com.baeldung.flink.operator.WordsCapitalizer; +import org.apache.flink.streaming.api.TimeCharacteristic; +import org.apache.flink.streaming.api.datastream.DataStream; +import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; +import org.apache.flink.streaming.api.windowing.time.Time; +import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011; +import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011; + +import static com.baeldung.flink.connector.Consumers.*; +import static com.baeldung.flink.connector.Producers.*; + +public class FlinkDataPipeline { + + public static void capitalize() throws Exception { + String inputTopic = "flink_input"; + String outputTopic = "flink_output"; + String consumerGroup = "baeldung"; + String address = "localhost:9092"; + + StreamExecutionEnvironment environment = + StreamExecutionEnvironment.getExecutionEnvironment(); + + FlinkKafkaConsumer011 flinkKafkaConsumer = + createStringConsumerForTopic(inputTopic, address, consumerGroup); + flinkKafkaConsumer.setStartFromEarliest(); + + DataStream stringInputStream = + environment.addSource(flinkKafkaConsumer); + + FlinkKafkaProducer011 flinkKafkaProducer = + createStringProducer(outputTopic, address); + + stringInputStream + .map(new WordsCapitalizer()) + .addSink(flinkKafkaProducer); + + environment.execute(); + } + +public static void createBackup () throws Exception { + String inputTopic = "flink_input"; + String outputTopic = "flink_output"; + String consumerGroup = "baeldung"; + String kafkaAddress = "localhost:9092"; + + StreamExecutionEnvironment environment = + StreamExecutionEnvironment.getExecutionEnvironment(); + + environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); + + FlinkKafkaConsumer011 flinkKafkaConsumer = + createInputMessageConsumer(inputTopic, kafkaAddress, consumerGroup); + flinkKafkaConsumer.setStartFromEarliest(); + + flinkKafkaConsumer + .assignTimestampsAndWatermarks(new InputMessageTimestampAssigner()); + FlinkKafkaProducer011 flinkKafkaProducer = + createBackupProducer(outputTopic, kafkaAddress); + + DataStream inputMessagesStream = + environment.addSource(flinkKafkaConsumer); + + inputMessagesStream + .timeWindowAll(Time.hours(24)) + .aggregate(new BackupAggregator()) + .addSink(flinkKafkaProducer); + + environment.execute(); +} + + public static void main(String[] args) throws Exception { + createBackup(); + } + +} diff --git a/libraries/src/main/java/com/baeldung/flink/LineSplitter.java b/libraries-data/src/main/java/com/baeldung/flink/LineSplitter.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/LineSplitter.java rename to libraries-data/src/main/java/com/baeldung/flink/LineSplitter.java diff --git a/libraries/src/main/java/com/baeldung/flink/WordCount.java b/libraries-data/src/main/java/com/baeldung/flink/WordCount.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/WordCount.java rename to libraries-data/src/main/java/com/baeldung/flink/WordCount.java diff --git a/libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java b/libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java new file mode 100644 index 0000000000..514085f9c4 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java @@ -0,0 +1,32 @@ +package com.baeldung.flink.connector; + +import com.baeldung.flink.model.InputMessage; +import com.baeldung.flink.schema.InputMessageDeserializationSchema; +import org.apache.flink.api.common.serialization.SimpleStringSchema; +import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer011; + +import java.util.Properties; + +public class Consumers { + +public static FlinkKafkaConsumer011 createStringConsumerForTopic( + String topic, String kafkaAddress, String kafkaGroup ) { + Properties props = new Properties(); + props.setProperty("bootstrap.servers", kafkaAddress); + props.setProperty("group.id",kafkaGroup); + FlinkKafkaConsumer011 consumer = + new FlinkKafkaConsumer011<>(topic, new SimpleStringSchema(),props); + + return consumer; +} + + public static FlinkKafkaConsumer011 createInputMessageConsumer(String topic, String kafkaAddress, String kafkaGroup ) { + Properties properties = new Properties(); + properties.setProperty("bootstrap.servers", kafkaAddress); + properties.setProperty("group.id",kafkaGroup); + FlinkKafkaConsumer011 consumer = new FlinkKafkaConsumer011( + topic, new InputMessageDeserializationSchema(),properties); + + return consumer; + } +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java b/libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java new file mode 100644 index 0000000000..8e6f3f8f37 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java @@ -0,0 +1,17 @@ +package com.baeldung.flink.connector; + +import com.baeldung.flink.model.Backup; +import com.baeldung.flink.schema.BackupSerializationSchema; +import org.apache.flink.api.common.serialization.SimpleStringSchema; +import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer011; + +public class Producers { + + public static FlinkKafkaProducer011 createStringProducer(String topic, String kafkaAddress) { + return new FlinkKafkaProducer011<>(kafkaAddress, topic, new SimpleStringSchema()); + } + + public static FlinkKafkaProducer011 createBackupProducer(String topic, String kafkaAddress) { + return new FlinkKafkaProducer011(kafkaAddress, topic, new BackupSerializationSchema()); + } +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/model/Backup.java b/libraries-data/src/main/java/com/baeldung/flink/model/Backup.java new file mode 100644 index 0000000000..268ceec7f3 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/model/Backup.java @@ -0,0 +1,27 @@ +package com.baeldung.flink.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + +public class Backup { + + @JsonProperty("inputMessages") + List inputMessages; + @JsonProperty("backupTimestamp") + LocalDateTime backupTimestamp; + @JsonProperty("uuid") + UUID uuid; + + public Backup(List inputMessages, LocalDateTime backupTimestamp) { + this.inputMessages = inputMessages; + this.backupTimestamp = backupTimestamp; + this.uuid = UUID.randomUUID(); + } + + public List getInputMessages() { + return inputMessages; + } +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java b/libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java new file mode 100644 index 0000000000..b3f75256ae --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java @@ -0,0 +1,71 @@ +package com.baeldung.flink.model; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.base.Objects; + +import java.time.LocalDateTime; + +@JsonSerialize +public class InputMessage { + String sender; + String recipient; + LocalDateTime sentAt; + String message; + + public InputMessage() { + } + + public String getSender() { + return sender; + } + public void setSender(String sender) { + this.sender = sender; + } + + public String getRecipient() { + return recipient; + } + + public void setRecipient(String recipient) { + this.recipient = recipient; + } + + public LocalDateTime getSentAt() { + return sentAt; + } + + public void setSentAt(LocalDateTime sentAt) { + this.sentAt = sentAt; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public InputMessage(String sender, String recipient, LocalDateTime sentAt, String message) { + this.sender = sender; + this.recipient = recipient; + this.sentAt = sentAt; + this.message = message; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InputMessage message1 = (InputMessage) o; + return Objects.equal(sender, message1.sender) && + Objects.equal(recipient, message1.recipient) && + Objects.equal(sentAt, message1.sentAt) && + Objects.equal(message, message1.message); + } + + @Override + public int hashCode() { + return Objects.hashCode(sender, recipient, sentAt, message); + } +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java b/libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java new file mode 100644 index 0000000000..c39b8413d1 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java @@ -0,0 +1,34 @@ +package com.baeldung.flink.operator; + +import com.baeldung.flink.model.Backup; +import com.baeldung.flink.model.InputMessage; +import org.apache.flink.api.common.functions.AggregateFunction; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + + public class BackupAggregator implements AggregateFunction, Backup> { + @Override + public List createAccumulator() { + return new ArrayList<>(); + } + + @Override + public List add(InputMessage inputMessage, List inputMessages) { + inputMessages.add(inputMessage); + return inputMessages; + } + + @Override + public Backup getResult(List inputMessages) { + Backup backup = new Backup(inputMessages, LocalDateTime.now()); + return backup; + } + + @Override + public List merge(List inputMessages, List acc1) { + inputMessages.addAll(acc1); + return inputMessages; + } + } diff --git a/libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java b/libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java new file mode 100644 index 0000000000..05828d9588 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java @@ -0,0 +1,23 @@ +package com.baeldung.flink.operator; + +import com.baeldung.flink.model.InputMessage; +import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks; +import org.apache.flink.streaming.api.watermark.Watermark; + +import javax.annotation.Nullable; +import java.time.ZoneId; + +public class InputMessageTimestampAssigner implements AssignerWithPunctuatedWatermarks { + + @Override + public long extractTimestamp(InputMessage element, long previousElementTimestamp) { + ZoneId zoneId = ZoneId.systemDefault(); + return element.getSentAt().atZone(zoneId).toEpochSecond() * 1000; + } + + @Nullable + @Override + public Watermark checkAndGetNextWatermark(InputMessage lastElement, long extractedTimestamp) { + return new Watermark(extractedTimestamp - 15); + } +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java b/libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java new file mode 100644 index 0000000000..f9103d225c --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java @@ -0,0 +1,11 @@ +package com.baeldung.flink.operator; + +import org.apache.flink.api.common.functions.MapFunction; + +public class WordsCapitalizer implements MapFunction { + + @Override + public String map(String s) { + return s.toUpperCase(); + } +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java b/libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java new file mode 100644 index 0000000000..967b266bb6 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java @@ -0,0 +1,33 @@ +package com.baeldung.flink.schema; + +import com.baeldung.flink.model.Backup; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.apache.flink.api.common.serialization.SerializationSchema; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BackupSerializationSchema + implements SerializationSchema { + + static ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); + + Logger logger = LoggerFactory.getLogger(BackupSerializationSchema.class); + + @Override + public byte[] serialize(Backup backupMessage) { + if(objectMapper == null) { + objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); + } + try { + String json = objectMapper.writeValueAsString(backupMessage); + return json.getBytes(); + } catch (com.fasterxml.jackson.core.JsonProcessingException e) { + logger.error("Failed to parse JSON", e); + } + return new byte[0]; + } +} diff --git a/libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java b/libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java new file mode 100644 index 0000000000..9aaf8b9877 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java @@ -0,0 +1,32 @@ +package com.baeldung.flink.schema; + +import com.baeldung.flink.model.InputMessage; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.apache.flink.api.common.serialization.DeserializationSchema; +import org.apache.flink.api.common.typeinfo.TypeInformation; + +import java.io.IOException; + +public class InputMessageDeserializationSchema implements + DeserializationSchema { + + static ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); + + + @Override + public InputMessage deserialize(byte[] bytes) throws IOException { + + return objectMapper.readValue(bytes, InputMessage.class); + } + + @Override + public boolean isEndOfStream(InputMessage inputMessage) { + return false; + } + + @Override + public TypeInformation getProducedType() { + return TypeInformation.of(InputMessage.class); + } +} diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/User.java b/libraries-data/src/main/java/com/baeldung/jmapper/User.java new file mode 100644 index 0000000000..9f99157183 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/jmapper/User.java @@ -0,0 +1,56 @@ +package com.baeldung.jmapper; + +import java.time.LocalDate; + + +public class User { + + private long id; + private String email; + private LocalDate birthDate; + + // constructors + + public User() { + super(); + } + + public User(long id, String email, LocalDate birthDate) { + super(); + this.id = id; + this.email = email; + this.birthDate = birthDate; + } + + // getters and setters + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public LocalDate getBirthDate() { + return birthDate; + } + + public void setBirthDate(LocalDate birthDate) { + this.birthDate = birthDate; + } + + @Override + public String toString() { + return "User [id=" + id + ", email=" + email + ", birthDate=" + birthDate + "]"; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/UserDto.java b/libraries-data/src/main/java/com/baeldung/jmapper/UserDto.java new file mode 100644 index 0000000000..326e8f3cd5 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/jmapper/UserDto.java @@ -0,0 +1,69 @@ +package com.baeldung.jmapper; + +import java.time.LocalDate; +import java.time.Period; + +import com.googlecode.jmapper.annotations.JMap; +import com.googlecode.jmapper.annotations.JMapConversion; + +public class UserDto { + + @JMap + private long id; + + @JMap("email") + private String username; + + @JMap("birthDate") + private int age; + + @JMapConversion(from={"birthDate"}, to={"age"}) + public int conversion(LocalDate birthDate){ + return Period.between(birthDate, LocalDate.now()).getYears(); + } + + // constructors + + public UserDto() { + super(); + } + + public UserDto(long id, String username, int age) { + super(); + this.id = id; + this.username = username; + this.age = age; + } + + // getters and setters + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "UserDto [id=" + id + ", username=" + username + ", age=" + age + "]"; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/UserDto1.java b/libraries-data/src/main/java/com/baeldung/jmapper/UserDto1.java new file mode 100644 index 0000000000..99247c56f6 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/jmapper/UserDto1.java @@ -0,0 +1,47 @@ +package com.baeldung.jmapper; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +@JGlobalMap +public class UserDto1 { + + private long id; + private String email; + + + // constructors + + public UserDto1() { + super(); + } + + public UserDto1(long id, String email) { + super(); + this.id = id; + this.email = email; + } + + // getters and setters + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public String toString() { + return "UserDto [id=" + id + ", email=" + email + "]"; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/relational/User.java b/libraries-data/src/main/java/com/baeldung/jmapper/relational/User.java new file mode 100644 index 0000000000..1238a82684 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/jmapper/relational/User.java @@ -0,0 +1,49 @@ +package com.baeldung.jmapper.relational; + +import com.googlecode.jmapper.annotations.JMap; + + +public class User { + + @JMap(classes = {UserDto1.class, UserDto2.class}) + private long id; + + @JMap(attributes = {"username", "email"}, classes = {UserDto1.class, UserDto2.class}) + private String email; + + // constructors + + public User() { + super(); + } + + public User(long id, String email) { + super(); + this.id = id; + this.email = email; + } + + // getters and setters + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public String toString() { + return "User [id=" + id + ", email=" + email + "]"; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto1.java b/libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto1.java new file mode 100644 index 0000000000..375fd267a0 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto1.java @@ -0,0 +1,44 @@ +package com.baeldung.jmapper.relational; + + +public class UserDto1 { + + private long id; + private String username; + + // constructors + + public UserDto1() { + super(); + } + + public UserDto1(long id, String username) { + super(); + this.id = id; + this.username = username; + } + + // getters and setters + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + @Override + public String toString() { + return "UserDto [id=" + id + ", username=" + username + "]"; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto2.java b/libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto2.java new file mode 100644 index 0000000000..d0858c7d8e --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/jmapper/relational/UserDto2.java @@ -0,0 +1,44 @@ +package com.baeldung.jmapper.relational; + + +public class UserDto2 { + + private long id; + private String email; + + // constructors + + public UserDto2() { + super(); + } + + public UserDto2(long id, String email) { + super(); + this.id = id; + this.email = email; + } + + // getters and setters + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public String toString() { + return "UserDto2 [id=" + id + ", email=" + email + "]"; + } + +} diff --git a/libraries-data/src/main/resources/ebean.mf b/libraries-data/src/main/resources/ebean.mf new file mode 100644 index 0000000000..f49fecc717 --- /dev/null +++ b/libraries-data/src/main/resources/ebean.mf @@ -0,0 +1,3 @@ +entity-packages: com.baeldung.ebean.model +transactional-packages: com.baeldung.ebean.app +querybean-packages: com.baeldung.ebean.app diff --git a/libraries-data/src/main/resources/ebean.properties b/libraries-data/src/main/resources/ebean.properties new file mode 100644 index 0000000000..9cc5cc170a --- /dev/null +++ b/libraries-data/src/main/resources/ebean.properties @@ -0,0 +1,7 @@ +ebean.db.ddl.generate=true +ebean.db.ddl.run=true + +datasource.db.username=sa +datasource.db.password= +datasource.db.databaseUrl=jdbc:h2:mem:customer +datasource.db.databaseDriver=org.h2.Driver diff --git a/libraries-data/src/main/resources/logback.xml b/libraries-data/src/main/resources/logback.xml new file mode 100644 index 0000000000..a57d22fcb2 --- /dev/null +++ b/libraries-data/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/libraries-data/src/main/resources/user_jmapper.xml b/libraries-data/src/main/resources/user_jmapper.xml new file mode 100644 index 0000000000..f007de9f0a --- /dev/null +++ b/libraries-data/src/main/resources/user_jmapper.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/libraries-data/src/main/resources/user_jmapper1.xml b/libraries-data/src/main/resources/user_jmapper1.xml new file mode 100644 index 0000000000..abcfd77e1c --- /dev/null +++ b/libraries-data/src/main/resources/user_jmapper1.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries-data/src/main/resources/user_jmapper2.xml b/libraries-data/src/main/resources/user_jmapper2.xml new file mode 100644 index 0000000000..1e708e14bf --- /dev/null +++ b/libraries-data/src/main/resources/user_jmapper2.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries-data/src/test/java/com/baeldung/crunch/MemPipelineUnitTest.java b/libraries-data/src/test/java/com/baeldung/crunch/MemPipelineUnitTest.java new file mode 100644 index 0000000000..3ee2bb6836 --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/crunch/MemPipelineUnitTest.java @@ -0,0 +1,89 @@ +package com.baeldung.crunch; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Calendar; + +import org.apache.crunch.PCollection; +import org.apache.crunch.Pipeline; +import org.apache.crunch.Source; +import org.apache.crunch.Target; +import org.apache.crunch.impl.mem.MemPipeline; +import org.apache.crunch.io.From; +import org.apache.crunch.io.To; +import org.junit.Ignore; +import org.junit.Test; + +public class MemPipelineUnitTest { + + private static final String INPUT_FILE_PATH = "src/test/resources/crunch/input.txt"; + + @Test + public void givenPipeLineAndSource_whenSourceRead_thenExpectedNumberOfRecordsRead() { + Pipeline pipeline = MemPipeline.getInstance(); + Source source = From.textFile(INPUT_FILE_PATH); + + PCollection lines = pipeline.read(source); + + assertEquals(21, lines.asCollection() + .getValue() + .size()); + } + + @Test + public void givenPipeLine_whenTextFileRead_thenExpectedNumberOfRecordsRead() { + Pipeline pipeline = MemPipeline.getInstance(); + + PCollection lines = pipeline.readTextFile(INPUT_FILE_PATH); + + assertEquals(21, lines.asCollection() + .getValue() + .size()); + } + + private String createOutputPath() throws IOException { + Path path = Files.createTempDirectory("test"); + final String outputFilePath = path.toString() + File.separatorChar + + "output.text"; + return outputFilePath; + } + + @Test + @Ignore("Requires Hadoop binaries") + public void givenCollection_whenWriteCalled_fileWrittenSuccessfully() + throws IOException { + PCollection inputStrings = MemPipeline.collectionOf("Hello", + "Apache", "Crunch", Calendar.getInstance() + .toString()); + final String outputFilePath = createOutputPath(); + Target target = To.textFile(outputFilePath); + + inputStrings.write(target); + + Pipeline pipeline = MemPipeline.getInstance(); + PCollection lines = pipeline.readTextFile(outputFilePath); + assertIterableEquals(inputStrings.materialize(), lines.materialize()); + } + + @Test + @Ignore("Requires Hadoop binaries") + public void givenPipeLine_whenWriteTextFileCalled_fileWrittenSuccessfully() + throws IOException { + Pipeline pipeline = MemPipeline.getInstance(); + PCollection inputStrings = MemPipeline.collectionOf("Hello", + "Apache", "Crunch", Calendar.getInstance() + .toString()); + final String outputFilePath = createOutputPath(); + + pipeline.writeTextFile(inputStrings, outputFilePath); + + PCollection lines = pipeline.readTextFile(outputFilePath); + assertIterableEquals(inputStrings.materialize(), lines.materialize()); + } + +} diff --git a/libraries-data/src/test/java/com/baeldung/crunch/StopWordFilterUnitTest.java b/libraries-data/src/test/java/com/baeldung/crunch/StopWordFilterUnitTest.java new file mode 100644 index 0000000000..fffefc2bfb --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/crunch/StopWordFilterUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.crunch; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.apache.crunch.FilterFn; +import org.apache.crunch.PCollection; +import org.apache.crunch.impl.mem.MemPipeline; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +public class StopWordFilterUnitTest { + + @Test + public void givenFilter_whenStopWordPassed_thenFalseReturned() { + FilterFn filter = new StopWordFilter(); + + assertFalse(filter.accept("the")); + } + + @Test + public void givenFilter_whenNonStopWordPassed_thenTrueReturned() { + FilterFn filter = new StopWordFilter(); + + assertTrue(filter.accept("Hello")); + } + + @Test + public void givenWordCollection_whenFiltered_thenStopWordsRemoved() { + PCollection words = MemPipeline.collectionOf("This", "is", "a", + "test", "sentence"); + + PCollection noStopWords = words.filter(new StopWordFilter()); + + assertEquals(ImmutableList.of("This", "test", "sentence"), + Lists.newArrayList(noStopWords.materialize())); + } +} diff --git a/libraries-data/src/test/java/com/baeldung/crunch/ToUpperCaseFnUnitTest.java b/libraries-data/src/test/java/com/baeldung/crunch/ToUpperCaseFnUnitTest.java new file mode 100644 index 0000000000..09fb9fba85 --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/crunch/ToUpperCaseFnUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.crunch; + +import static org.junit.Assert.assertEquals; + +import org.apache.crunch.impl.mem.emit.InMemoryEmitter; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; + +public class ToUpperCaseFnUnitTest { + + @Test + public void givenString_whenToUpperCaseFnCalled_UpperCaseStringReturned() { + InMemoryEmitter emitter = new InMemoryEmitter(); + + new ToUpperCaseFn().process("input", emitter); + + assertEquals(ImmutableList.of("INPUT"), emitter.getOutput()); + } + +} diff --git a/libraries-data/src/test/java/com/baeldung/crunch/ToUpperCaseWithCounterFnUnitTest.java b/libraries-data/src/test/java/com/baeldung/crunch/ToUpperCaseWithCounterFnUnitTest.java new file mode 100644 index 0000000000..76294d273d --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/crunch/ToUpperCaseWithCounterFnUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.crunch; + +import static org.junit.Assert.assertEquals; + +import org.apache.crunch.PCollection; +import org.apache.crunch.impl.mem.MemPipeline; +import org.apache.crunch.types.writable.Writables; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +public class ToUpperCaseWithCounterFnUnitTest { + + @Before + public void setUp() throws Exception { + MemPipeline.clearCounters(); + } + + @Test + public void whenFunctionCalled_counterIncementendForChangedValues() { + PCollection inputStrings = MemPipeline.collectionOf("This", "is", "a", "TEST", "string"); + PCollection upperCaseStrings = inputStrings.parallelDo(new ToUpperCaseWithCounterFn(), Writables.strings()); + + assertEquals(ImmutableList.of("THIS", "IS", "A", "TEST", "STRING"), Lists.newArrayList(upperCaseStrings.materialize())); + assertEquals(4L, MemPipeline.getCounters() + .findCounter("UpperCase", "modified") + .getValue()); + } +} diff --git a/libraries-data/src/test/java/com/baeldung/crunch/TokenizerUnitTest.java b/libraries-data/src/test/java/com/baeldung/crunch/TokenizerUnitTest.java new file mode 100644 index 0000000000..1e85826d17 --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/crunch/TokenizerUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.crunch; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +import org.apache.crunch.Emitter; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class TokenizerUnitTest { + @Mock + private Emitter emitter; + + @Test + public void givenTokenizer_whenLineProcessed_thenOnlyExpectedWordsEmitted() { + Tokenizer splitter = new Tokenizer(); + + splitter.process(" hello world ", emitter); + + verify(emitter).emit("hello"); + verify(emitter).emit("world"); + verifyNoMoreInteractions(emitter); + } +} diff --git a/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java new file mode 100644 index 0000000000..ab7d119c16 --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java @@ -0,0 +1,103 @@ +package com.baeldung.flink; + +import com.baeldung.flink.model.Backup; +import com.baeldung.flink.model.InputMessage; +import com.baeldung.flink.operator.BackupAggregator; +import com.baeldung.flink.operator.InputMessageTimestampAssigner; +import com.baeldung.flink.schema.BackupSerializationSchema; +import com.baeldung.flink.schema.InputMessageDeserializationSchema; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.apache.commons.collections.ListUtils; +import org.apache.flink.api.common.serialization.DeserializationSchema; +import org.apache.flink.api.common.serialization.SerializationSchema; +import org.apache.flink.streaming.api.TimeCharacteristic; +import org.apache.flink.streaming.api.datastream.DataStreamSource; +import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; +import org.apache.flink.streaming.api.functions.sink.SinkFunction; +import org.apache.flink.streaming.api.windowing.time.Time; +import org.awaitility.Awaitility; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class BackupCreatorIntegrationTest { + public static ObjectMapper mapper; + + @Before + public void setup() { + mapper = new ObjectMapper().registerModule(new JavaTimeModule()); + } + + @Test + public void givenProperJson_whenDeserializeIsInvoked_thenProperObjectIsReturned() throws IOException { + InputMessage message = new InputMessage("Me", "User", LocalDateTime.now(), "Test Message"); + byte[] messageSerialized = mapper.writeValueAsBytes(message); + DeserializationSchema deserializationSchema = new InputMessageDeserializationSchema(); + InputMessage messageDeserialized = deserializationSchema.deserialize(messageSerialized); + + assertEquals(message, messageDeserialized); + } + + @Test + public void givenMultipleInputMessagesFromDifferentDays_whenBackupCreatorIsUser_thenMessagesAreGroupedProperly() throws Exception { + LocalDateTime currentTime = LocalDateTime.now(); + InputMessage message = new InputMessage("Me", "User", currentTime, "First TestMessage"); + InputMessage secondMessage = new InputMessage("Me", "User", currentTime.plusHours(1), "First TestMessage"); + InputMessage thirdMessage = new InputMessage("Me", "User", currentTime.plusHours(2), "First TestMessage"); + InputMessage fourthMessage = new InputMessage("Me", "User", currentTime.plusHours(3), "First TestMessage"); + InputMessage fifthMessage = new InputMessage("Me", "User", currentTime.plusHours(25), "First TestMessage"); + InputMessage sixthMessage = new InputMessage("Me", "User", currentTime.plusHours(26), "First TestMessage"); + + List firstBackupMessages = Arrays.asList(message, secondMessage, thirdMessage, fourthMessage); + List secondBackupMessages = Arrays.asList(fifthMessage, sixthMessage); + List inputMessages = ListUtils.union(firstBackupMessages, secondBackupMessages); + + StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); + env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); + env.setParallelism(1); + DataStreamSource testDataSet = env.fromCollection(inputMessages); + CollectingSink sink = new CollectingSink(); + testDataSet.assignTimestampsAndWatermarks(new InputMessageTimestampAssigner()) + .timeWindowAll(Time.hours(24)) + .aggregate(new BackupAggregator()) + .addSink(sink); + + env.execute(); + + Awaitility.await().until(() -> sink.backups.size() == 2); + assertEquals(2, sink.backups.size()); + assertEquals(firstBackupMessages, sink.backups.get(0).getInputMessages()); + assertEquals(secondBackupMessages, sink.backups.get(1).getInputMessages()); + + } + + @Test + public void givenProperBackupObject_whenSerializeIsInvoked_thenObjectIsProperlySerialized() throws IOException { + InputMessage message = new InputMessage("Me", "User", LocalDateTime.now(), "Test Message"); + List messages = Arrays.asList(message); + Backup backup = new Backup(messages, LocalDateTime.now()); + byte[] backupSerialized = mapper.writeValueAsBytes(backup); + SerializationSchema serializationSchema = new BackupSerializationSchema(); + byte[] backupProcessed = serializationSchema.serialize(backup); + + assertEquals(backupSerialized, backupProcessed); + } + + private static class CollectingSink implements SinkFunction { + + public static List backups = new ArrayList<>(); + + @Override + public synchronized void invoke(Backup value, Context context) throws Exception { + backups.add(value); + } + } +} diff --git a/libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java new file mode 100644 index 0000000000..8a98dae4b5 --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java @@ -0,0 +1,34 @@ +package com.baeldung.flink; + +import com.baeldung.flink.operator.WordsCapitalizer; +import org.apache.flink.api.java.DataSet; +import org.apache.flink.api.java.ExecutionEnvironment; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class WordCapitalizerIntegrationTest { + + @Test + public void givenDataSet_whenExecuteWordCapitalizer_thenReturnCapitalizedWords() throws Exception { + ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); + List data = Arrays.asList("dog", "cat", "wolf", "pig"); + + DataSet testDataSet = env.fromCollection(data); + + + List dataProcessed = testDataSet + .map(new WordsCapitalizer()) + .collect(); + + List testDataCapitalized = data.stream() + .map(String::toUpperCase) + .collect(Collectors.toList()); + + Assert.assertEquals(testDataCapitalized, dataProcessed); + } + +} diff --git a/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java diff --git a/libraries-data/src/test/java/com/baeldung/jmapper/JMapperIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jmapper/JMapperIntegrationTest.java new file mode 100644 index 0000000000..96ed090482 --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/jmapper/JMapperIntegrationTest.java @@ -0,0 +1,114 @@ +package com.baeldung.jmapper; + +import static com.googlecode.jmapper.api.JMapperAPI.attribute; +import static com.googlecode.jmapper.api.JMapperAPI.global; +import static com.googlecode.jmapper.api.JMapperAPI.mappedClass; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.time.LocalDate; + +import org.junit.Test; + +import com.googlecode.jmapper.JMapper; +import com.googlecode.jmapper.api.JMapperAPI; + +public class JMapperIntegrationTest { + + + @Test + public void givenUser_whenUseAnnotation_thenConverted(){ + JMapper userMapper = new JMapper<>(UserDto.class, User.class); + + User user = new User(1L,"john@test.com", LocalDate.of(1980,8,20)); + UserDto result = userMapper.getDestination(user); + + System.out.println(result); + assertEquals(user.getId(), result.getId()); + assertEquals(user.getEmail(), result.getUsername()); + } + + @Test + public void givenUser_whenUseGlobalMapAnnotation_thenConverted(){ + JMapper userMapper= new JMapper<>(UserDto1.class, User.class); + + User user = new User(1L,"john@test.com", LocalDate.of(1980,8,20)); + UserDto1 result = userMapper.getDestination(user); + + System.out.println(result); + assertEquals(user.getId(), result.getId()); + assertEquals(user.getEmail(), result.getEmail()); + } + + @Test + public void givenUser_whenUseAnnotationExplicitConversion_thenConverted(){ + JMapper userMapper = new JMapper<>(UserDto.class, User.class); + + User user = new User(1L,"john@test.com", LocalDate.of(1980,8,20)); + UserDto result = userMapper.getDestination(user); + + System.out.println(result); + assertEquals(user.getId(), result.getId()); + assertEquals(user.getEmail(), result.getUsername()); + assertTrue(result.getAge() > 0); + } + + //======================= XML + + @Test + public void givenUser_whenUseXml_thenConverted(){ + JMapper userMapper = new JMapper<>(UserDto.class, User.class,"user_jmapper.xml"); + + User user = new User(1L,"john@test.com", LocalDate.of(1980,8,20)); + UserDto result = userMapper.getDestination(user); + + System.out.println(result); + assertEquals(user.getId(), result.getId()); + assertEquals(user.getEmail(), result.getUsername()); + } + + @Test + public void givenUser_whenUseXmlGlobal_thenConverted(){ + JMapper userMapper = new JMapper<>(UserDto1.class, User.class,"user_jmapper1.xml"); + + User user = new User(1L,"john@test.com", LocalDate.of(1980,8,20)); + UserDto1 result = userMapper.getDestination(user); + + System.out.println(result); + assertEquals(user.getId(), result.getId()); + assertEquals(user.getEmail(), result.getEmail()); + } + + // ===== API + + @Test + public void givenUser_whenUseApi_thenConverted(){ + JMapperAPI jmapperApi = new JMapperAPI() .add(mappedClass(UserDto.class) + .add(attribute("id").value("id")) + .add(attribute("username").value("email")) + ) ; + JMapper userMapper = new JMapper<>(UserDto.class, User.class, jmapperApi); + + User user = new User(1L,"john@test.com", LocalDate.of(1980,8,20)); + UserDto result = userMapper.getDestination(user); + + System.out.println(result); + assertEquals(user.getId(), result.getId()); + assertEquals(user.getEmail(), result.getUsername()); + } + + @Test + public void givenUser_whenUseApiGlobal_thenConverted(){ + JMapperAPI jmapperApi = new JMapperAPI() .add(mappedClass(UserDto.class) + .add(global()) + ) ; + JMapper userMapper1 = new JMapper<>(UserDto1.class, User.class,jmapperApi); + + User user = new User(1L,"john@test.com", LocalDate.of(1980,8,20)); + UserDto1 result = userMapper1.getDestination(user); + + System.out.println(result); + assertEquals(user.getId(), result.getId()); + assertEquals(user.getEmail(), result.getEmail()); + } +} diff --git a/libraries-data/src/test/java/com/baeldung/jmapper/JMapperRelationalIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jmapper/JMapperRelationalIntegrationTest.java new file mode 100644 index 0000000000..6af2865159 --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/jmapper/JMapperRelationalIntegrationTest.java @@ -0,0 +1,76 @@ +package com.baeldung.jmapper; + +import static com.googlecode.jmapper.api.JMapperAPI.attribute; +import static com.googlecode.jmapper.api.JMapperAPI.mappedClass; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.baeldung.jmapper.relational.User; +import com.baeldung.jmapper.relational.UserDto1; +import com.baeldung.jmapper.relational.UserDto2; +import com.googlecode.jmapper.RelationalJMapper; +import com.googlecode.jmapper.api.JMapperAPI; + +public class JMapperRelationalIntegrationTest { + + + @Test + public void givenUser_whenUseAnnotation_thenConverted(){ + RelationalJMapper relationalMapper = new RelationalJMapper<>(User.class); + + User user = new User(1L,"john@test.com"); + UserDto1 result1 = relationalMapper.oneToMany(UserDto1.class, user); + UserDto2 result2= relationalMapper.oneToMany(UserDto2.class, user); + + System.out.println(result1); + System.out.println(result2); + assertEquals(user.getId(), result1.getId()); + assertEquals(user.getEmail(), result1.getUsername()); + assertEquals(user.getId(), result2.getId()); + assertEquals(user.getEmail(), result2.getEmail()); + } + + //======================= XML + + @Test + public void givenUser_whenUseXml_thenConverted(){ + RelationalJMapper relationalMapper = new RelationalJMapper<>(User.class,"user_jmapper2.xml"); + + User user = new User(1L,"john@test.com"); + UserDto1 result1 = relationalMapper.oneToMany(UserDto1.class, user); + UserDto2 result2 = relationalMapper.oneToMany(UserDto2.class, user); + + System.out.println(result1); + System.out.println(result2); + assertEquals(user.getId(), result1.getId()); + assertEquals(user.getEmail(), result1.getUsername()); + assertEquals(user.getId(), result2.getId()); + assertEquals(user.getEmail(), result2.getEmail()); + } + + + // ===== API + + @Test + public void givenUser_whenUseApi_thenConverted(){ + JMapperAPI jmapperApi = new JMapperAPI() + .add(mappedClass(User.class) + .add(attribute("id").value("id").targetClasses(UserDto1.class,UserDto2.class)) + .add(attribute("email").targetAttributes("username","email").targetClasses(UserDto1.class,UserDto2.class)) ) + ; + RelationalJMapper relationalMapper = new RelationalJMapper<>(User.class,jmapperApi); + + User user = new User(1L,"john@test.com"); + UserDto1 result1 = relationalMapper.oneToMany(UserDto1.class, user); + UserDto2 result2 = relationalMapper.oneToMany(UserDto2.class, user); + + System.out.println(result1); + System.out.println(result2); + assertEquals(user.getId(), result1.getId()); + assertEquals(user.getEmail(), result1.getUsername()); + assertEquals(user.getId(), result2.getId()); + assertEquals(user.getEmail(), result2.getEmail()); + } + +} diff --git a/libraries-data/src/test/resources/crunch/input.txt b/libraries-data/src/test/resources/crunch/input.txt new file mode 100644 index 0000000000..cb78ea5351 --- /dev/null +++ b/libraries-data/src/test/resources/crunch/input.txt @@ -0,0 +1,21 @@ +An an valley indeed so no wonder future nature vanity. Debating all she mistaken indulged believed provided declared. He many kept on draw lain song as same. Whether at dearest certain spirits is entered in to. Rich fine bred real use too many good. She compliment unaffected expression favourable any. Unknown chiefly showing to conduct no. Hung as love evil able to post at as. + + + +Is he staying arrival address earnest. To preference considered it themselves inquietude collecting estimating. View park for why gay knew face. Next than near to four so hand. Times so do he downs me would. Witty abode party her found quiet law. They door four bed fail now have. + +Tolerably earnestly middleton extremely distrusts she boy now not. Add and offered prepare how cordial two promise. Greatly who affixed suppose but enquire compact prepare all put. Added forth chief trees but rooms think may. Wicket do manner others seemed enable rather in. Excellent own discovery unfeeling sweetness questions the gentleman. Chapter shyness matters mr parlors if mention thought. + +Extended kindness trifling remember he confined outlived if. Assistance sentiments yet unpleasing say. Open they an busy they my such high. An active dinner wishes at unable hardly no talked on. Immediate him her resolving his favourite. Wished denote abroad at branch at. + +Village did removed enjoyed explain nor ham saw calling talking. Securing as informed declared or margaret. Joy horrible moreover man feelings own shy. Request norland neither mistake for yet. Between the for morning assured country believe. On even feet time have an no at. Relation so in confined smallest children unpacked delicate. Why sir end believe uncivil respect. Always get adieus nature day course for common. My little garret repair to desire he esteem. + +You vexed shy mirth now noise. Talked him people valley add use her depend letter. Allowance too applauded now way something recommend. Mrs age men and trees jokes fancy. Gay pretended engrossed eagerness continued ten. Admitting day him contained unfeeling attention mrs out. + +Performed suspicion in certainty so frankness by attention pretended. Newspaper or in tolerably education enjoyment. Extremity excellent certainty discourse sincerity no he so resembled. Joy house worse arise total boy but. Elderly up chicken do at feeling is. Like seen drew no make fond at on rent. Behaviour extremely her explained situation yet september gentleman are who. Is thought or pointed hearing he. + +If wandered relation no surprise of screened doubtful. Overcame no insisted ye of trifling husbands. Might am order hours on found. Or dissimilar companions friendship impossible at diminution. Did yourself carriage learning she man its replying. Sister piqued living her you enable mrs off spirit really. Parish oppose repair is me misery. Quick may saw style after money mrs. + +Effects present letters inquiry no an removed or friends. Desire behind latter me though in. Supposing shameless am he engrossed up additions. My possible peculiar together to. Desire so better am cannot he up before points. Remember mistaken opinions it pleasure of debating. Court front maids forty if aware their at. Chicken use are pressed removed. + +To sorry world an at do spoil along. Incommode he depending do frankness remainder to. Edward day almost active him friend thirty piqued. People as period twenty my extent as. Set was better abroad ham plenty secure had horses. Admiration has sir decisively excellence say everything inhabiting acceptance. Sooner settle add put you sudden him. diff --git a/libraries-security/.gitignore b/libraries-security/.gitignore new file mode 100644 index 0000000000..71881ad3ca --- /dev/null +++ b/libraries-security/.gitignore @@ -0,0 +1,14 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear +/bin/ diff --git a/libraries-security/README.md b/libraries-security/README.md new file mode 100644 index 0000000000..c42e91a888 --- /dev/null +++ b/libraries-security/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Guide to ScribeJava](https://www.baeldung.com/scribejava) diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml new file mode 100644 index 0000000000..3077abc29c --- /dev/null +++ b/libraries-security/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + libraries-security + libraries-security + jar + + + com.baeldung + parent-boot-1 + 0.0.1-SNAPSHOT + ../parent-boot-1 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.security.oauth + spring-security-oauth2 + 2.3.3.RELEASE + + + + com.github.scribejava + scribejava-apis + ${scribejava.version} + + + + junit + junit + ${junit.version} + test + + + org.passay + passay + 1.3.1 + + + org.cryptacular + cryptacular + 1.2.2 + + + + + + 4.12 + 2.0.4.RELEASE + 5.6.0 + + + + diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java b/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java new file mode 100644 index 0000000000..bb86c497b0 --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.scribejava; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + + +@SpringBootApplication +public class ScribejavaApplication { + + public static void main(String[] args) { + SpringApplication.run(ScribejavaApplication.class, args); + } + + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java b/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java new file mode 100644 index 0000000000..cf073d3035 --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java @@ -0,0 +1,27 @@ +package com.baeldung.scribejava.api; + +import com.github.scribejava.core.builder.api.DefaultApi20; + +public class MyApi extends DefaultApi20 { + + private MyApi() { + } + + private static class InstanceHolder { + private static final MyApi INSTANCE = new MyApi(); + } + + public static MyApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() { + return "http://localhost:8080/oauth/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return null; + } +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java new file mode 100644 index 0000000000..ffe4f0cc8a --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java @@ -0,0 +1,49 @@ +package com.baeldung.scribejava.controller; + +import com.baeldung.scribejava.service.GoogleService; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; + +@RestController +public class GoogleController { + + @Autowired + private GoogleService service; + + + @GetMapping(value ="/me/google") + public void me(HttpServletResponse response){ + String auth = service.getService().getAuthorizationUrl(); + + response.setHeader("Location", auth); + response.setStatus(302); + + } + + @GetMapping(value = "/auth/google") + public String google(@RequestParam String code, HttpServletResponse servletResponse){ + + try { + OAuth2AccessToken token = service.getService().getAccessToken(code); + + OAuthRequest request = new OAuthRequest(Verb.GET, "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"); + service.getService().signRequest(token, request); + Response response = service.getService().execute(request); + return response.getBody(); + + }catch (Exception e){ + servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + + return null; + } + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java new file mode 100644 index 0000000000..bfcd6d960c --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java @@ -0,0 +1,57 @@ +package com.baeldung.scribejava.controller; + +import com.baeldung.scribejava.service.TwitterService; +import com.github.scribejava.core.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; + +@RestController +public class TwitterController { + + @Autowired + private TwitterService service; + + + @GetMapping(value ="/me/twitter") + public String me(HttpServletResponse servletResponse){ + try { + OAuth1RequestToken requestToken = service.getService().getRequestToken(); + + String auth = service.getService().getAuthorizationUrl(requestToken); + + Runtime runtime = Runtime.getRuntime(); + try { + runtime.exec("rundll32 url.dll,FileProtocolHandler " + auth); + } catch (IOException e) { + servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return null; + } + + System.out.println("Insert twitter code:"); + Scanner in = new Scanner(System.in); + + String oauthverifier = in.nextLine(); + + final OAuth1AccessToken accessToken = service.getService().getAccessToken(requestToken,oauthverifier); + + OAuthRequest request = new OAuthRequest(Verb.GET, "https://api.twitter.com/1.1/account/verify_credentials.json"); + service.getService().signRequest(accessToken, request); + Response response = service.getService().execute(request); + return response.getBody(); + + } catch (IOException | InterruptedException | ExecutionException e) { + servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + + return null; + } + + + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java new file mode 100644 index 0000000000..68a11250de --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java @@ -0,0 +1,46 @@ +package com.baeldung.scribejava.controller; + +import com.baeldung.scribejava.service.MyService; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.security.Principal; + +@RestController(value = "/user") +public class UserController { + + @Autowired + private MyService service; + + @GetMapping("/me/myapi") + public String me(@RequestParam String username, @RequestParam String password, HttpServletResponse responsehttp) { + + try { + OAuth2AccessToken token = service.getService().getAccessTokenPasswordGrant(username, password); + + OAuthRequest request = new OAuthRequest(Verb.GET, "http://localhost:8080/me"); + service.getService().signRequest(token, request); + Response response = service.getService().execute(request); + + return response.getBody(); + + } catch (Exception e) { + responsehttp.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + + return null; + + } + + @GetMapping("/me") + public Principal user(Principal principal) { + return principal; + } +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java new file mode 100644 index 0000000000..2c7162399b --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java @@ -0,0 +1,45 @@ +package com.baeldung.scribejava.oauth; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; + + +@Configuration +@EnableAuthorizationServer +public class AuthServiceConfig extends AuthorizationServerConfigurerAdapter { + + @Autowired + @Qualifier("authenticationManagerBean") + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.tokenKeyAccess("permitAll()") + .checkTokenAccess("isAuthenticated()"); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.inMemory() + .withClient("baeldung_api_key") + .secret("baeldung_api_secret") + .authorizedGrantTypes("password","refresh_token") + .scopes("read","write").autoApprove(true); + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints + .authenticationManager(authenticationManager) + .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST); + } + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java new file mode 100644 index 0000000000..7aa51400ea --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java @@ -0,0 +1,53 @@ +package com.baeldung.scribejava.oauth; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; + +@Configuration +@EnableResourceServer +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .headers().frameOptions().disable() + .and() + .csrf().disable(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("baeldung") + .password("scribejava") + .roles("USER"); + } + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + + @EnableResourceServer + @Configuration + public class ResourceServerConfig extends ResourceServerConfigurerAdapter { + + @Override + public void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/user/me").authenticated() + .and() + .csrf().disable(); + } + } + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java new file mode 100644 index 0000000000..fbcc39763c --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java @@ -0,0 +1,31 @@ +package com.baeldung.scribejava.service; + +import com.github.scribejava.apis.GoogleApi20; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth20Service; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +@Component +public class GoogleService { + + private OAuth20Service service; + private final String API_KEY = "api_key"; + private final String API_SECRET = "api_secret"; + private final String SCOPE = "https://www.googleapis.com/auth/userinfo.email"; + private final String CALLBACK = "http://localhost:8080/auth/google"; + + @PostConstruct + private void init(){ + this.service = new ServiceBuilder(API_KEY) + .apiSecret(API_SECRET) + .scope(SCOPE) + .callback(CALLBACK) + .build(GoogleApi20.instance()); + } + + + public OAuth20Service getService() { + return service; + } +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java new file mode 100644 index 0000000000..739c82172c --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java @@ -0,0 +1,29 @@ +package com.baeldung.scribejava.service; + +import com.baeldung.scribejava.api.MyApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth20Service; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component +public class MyService { + + private OAuth20Service service; + private final String API_KEY = "baeldung_api_key"; + private final String API_SECRET = "baeldung_api_secret"; + + @PostConstruct + private void init(){ + this.service = new ServiceBuilder(API_KEY) + .apiSecret(API_SECRET) + .scope("read write") + .build(MyApi.instance()); + } + + + public OAuth20Service getService() { + return service; + } +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java new file mode 100644 index 0000000000..df49f74679 --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java @@ -0,0 +1,29 @@ +package com.baeldung.scribejava.service; + +import com.github.scribejava.apis.TwitterApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth10aService; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component +public class TwitterService { + + private final String API_KEY = "api_key"; + private final String API_SECRET = "api_secret"; + private OAuth10aService service; + + @PostConstruct + private void init(){ + this.service = new ServiceBuilder(API_KEY) + .apiSecret(API_SECRET) + .build(TwitterApi.instance()); + } + + public OAuth10aService getService(){ + return service; + } + + +} diff --git a/libraries-security/src/main/resources/application.properties b/libraries-security/src/main/resources/application.properties new file mode 100644 index 0000000000..71c6176533 --- /dev/null +++ b/libraries-security/src/main/resources/application.properties @@ -0,0 +1 @@ +security.oauth2.resource.filter-order = 3 \ No newline at end of file diff --git a/libraries-security/src/test/java/com/baeldung/passay/NegativeMatchingRulesUnitTest.java b/libraries-security/src/test/java/com/baeldung/passay/NegativeMatchingRulesUnitTest.java new file mode 100644 index 0000000000..5054a5880e --- /dev/null +++ b/libraries-security/src/test/java/com/baeldung/passay/NegativeMatchingRulesUnitTest.java @@ -0,0 +1,149 @@ +package com.baeldung.passay; + +import org.cryptacular.bean.EncodingHashBean; +import org.cryptacular.spec.CodecSpec; +import org.cryptacular.spec.DigestSpec; +import org.junit.Assert; +import org.junit.Test; +import org.passay.DictionaryRule; +import org.passay.DictionarySubstringRule; +import org.passay.DigestHistoryRule; +import org.passay.EnglishSequenceData; +import org.passay.HistoryRule; +import org.passay.IllegalCharacterRule; +import org.passay.IllegalRegexRule; +import org.passay.IllegalSequenceRule; +import org.passay.NumberRangeRule; +import org.passay.PasswordData; +import org.passay.PasswordValidator; +import org.passay.RepeatCharacterRegexRule; +import org.passay.RuleResult; +import org.passay.SourceRule; +import org.passay.UsernameRule; +import org.passay.WhitespaceRule; +import org.passay.dictionary.ArrayWordList; +import org.passay.dictionary.WordListDictionary; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +public class NegativeMatchingRulesUnitTest { + + @Test + public void givenDictionaryRules_whenValidatePassword_thenFoundIllegalWordsFromDictionary() { + ArrayWordList arrayWordList = new ArrayWordList(new String[] { "bar", "foobar" }); + + WordListDictionary wordListDictionary = new WordListDictionary(arrayWordList); + + DictionaryRule dictionaryRule = new DictionaryRule(wordListDictionary); + DictionarySubstringRule dictionarySubstringRule = new DictionarySubstringRule(wordListDictionary); + + PasswordValidator passwordValidator = new PasswordValidator(dictionaryRule, dictionarySubstringRule); + RuleResult validate = passwordValidator.validate(new PasswordData("foobar")); + + assertFalse(validate.isValid()); + assertEquals("ILLEGAL_WORD:{matchingWord=foobar}", getDetail(validate, 0)); + assertEquals("ILLEGAL_WORD:{matchingWord=bar}", getDetail(validate, 1)); + } + + @Test + public void givenHistoryRule_whenValidatePassword_thenFoundIllegalWordsFromHistory() { + HistoryRule historyRule = new HistoryRule(); + + PasswordData passwordData = new PasswordData("123"); + passwordData.setPasswordReferences(new PasswordData.HistoricalReference("12345"), new PasswordData.HistoricalReference("1234"), new PasswordData.HistoricalReference("123")); + + PasswordValidator passwordValidator = new PasswordValidator(historyRule); + + RuleResult validate = passwordValidator.validate(passwordData); + + assertFalse(validate.isValid()); + assertEquals("HISTORY_VIOLATION:{historySize=3}", getDetail(validate, 0)); + } + + @Test + public void givenSeveralIllegalRules_whenValidatePassword_thenFoundSeveralIllegalPatterns() { + IllegalCharacterRule illegalCharacterRule = new IllegalCharacterRule(new char[] { 'a' }); + IllegalRegexRule illegalRegexRule = new IllegalRegexRule("\\w{2}\\d{2}"); + IllegalSequenceRule illegalSequenceRule = new IllegalSequenceRule(EnglishSequenceData.Alphabetical, 3, true); + NumberRangeRule numberRangeRule = new NumberRangeRule(1, 10); + WhitespaceRule whitespaceRule = new WhitespaceRule(); + + PasswordValidator passwordValidator = new PasswordValidator(illegalCharacterRule, illegalRegexRule, illegalSequenceRule, numberRangeRule, whitespaceRule); + + RuleResult validate = passwordValidator.validate(new PasswordData("abcd22 ")); + + assertFalse(validate.isValid()); + assertEquals("ILLEGAL_CHAR:{illegalCharacter=a, matchBehavior=contains}", getDetail(validate, 0)); + assertEquals("ILLEGAL_MATCH:{match=cd22, pattern=\\w{2}\\d{2}}", getDetail(validate, 1)); + assertEquals("ILLEGAL_ALPHABETICAL_SEQUENCE:{sequence=abc}", getDetail(validate, 2)); + assertEquals("ILLEGAL_ALPHABETICAL_SEQUENCE:{sequence=bcd}", getDetail(validate, 3)); + assertEquals("ILLEGAL_NUMBER_RANGE:{number=2, matchBehavior=contains}", getDetail(validate, 4)); + assertEquals("ILLEGAL_WHITESPACE:{whitespaceCharacter= , matchBehavior=contains}", getDetail(validate, 5)); + } + + @Test + public void givenSourceRule_whenValidatePassword_thenFoundIllegalWordsFromSource() { + SourceRule sourceRule = new SourceRule(); + + PasswordData passwordData = new PasswordData("password"); + passwordData.setPasswordReferences(new PasswordData.SourceReference("source", "password")); + + PasswordValidator passwordValidator = new PasswordValidator(sourceRule); + RuleResult validate = passwordValidator.validate(passwordData); + + assertFalse(validate.isValid()); + assertEquals("SOURCE_VIOLATION:{source=source}", getDetail(validate, 0)); + } + + @Test + public void givenRepeatCharacterRegexRuleRule_whenValidatePassword_thenFoundIllegalPatternMatches() { + RepeatCharacterRegexRule repeatCharacterRegexRule = new RepeatCharacterRegexRule(3); + + PasswordValidator passwordValidator = new PasswordValidator(repeatCharacterRegexRule); + + RuleResult validate = passwordValidator.validate(new PasswordData("aaabbb")); + + assertFalse(validate.isValid()); + assertEquals("ILLEGAL_MATCH:{match=aaa, pattern=([^\\x00-\\x1F])\\1{2}}", getDetail(validate, 0)); + assertEquals("ILLEGAL_MATCH:{match=bbb, pattern=([^\\x00-\\x1F])\\1{2}}", getDetail(validate, 1)); + } + + @Test + public void givenUserNameRule_whenValidatePassword_thenFoundUserNameInPassword() { + PasswordValidator passwordValidator = new PasswordValidator(new UsernameRule()); + + PasswordData passwordData = new PasswordData("testuser1234"); + passwordData.setUsername("testuser"); + + RuleResult validate = passwordValidator.validate(passwordData); + + assertFalse(validate.isValid()); + assertEquals("ILLEGAL_USERNAME:{username=testuser, matchBehavior=contains}", getDetail(validate, 0)); + } + + @Test + public void givenPasswordAndHashBeanAndEncryptedReferences_whenValidate_thenPasswordValidationShouldPass() { + List historicalReferences = Arrays.asList(new PasswordData.HistoricalReference("SHA256", "2e4551de804e27aacf20f9df5be3e8cd384ed64488b21ab079fb58e8c90068ab")); + PasswordData passwordData = new PasswordData("example!"); + passwordData.setPasswordReferences(historicalReferences); + + EncodingHashBean encodingHashBean = new EncodingHashBean(new CodecSpec("Base64"), new DigestSpec("SHA256"), 1, false); + + PasswordValidator passwordValidator = new PasswordValidator(new DigestHistoryRule(encodingHashBean)); + + RuleResult validate = passwordValidator.validate(passwordData); + + Assert.assertTrue(validate.isValid()); + } + + private String getDetail(RuleResult validate, int i) { + return validate.getDetails() + .get(i) + .toString(); + } + +} diff --git a/libraries-security/src/test/java/com/baeldung/passay/PasswordGeneratorUnitTest.java b/libraries-security/src/test/java/com/baeldung/passay/PasswordGeneratorUnitTest.java new file mode 100644 index 0000000000..ff279e9317 --- /dev/null +++ b/libraries-security/src/test/java/com/baeldung/passay/PasswordGeneratorUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.passay; + +import org.junit.Assert; +import org.junit.Test; +import org.passay.CharacterData; +import org.passay.CharacterRule; +import org.passay.EnglishCharacterData; +import org.passay.PasswordGenerator; + +import java.util.stream.Stream; + +public class PasswordGeneratorUnitTest { + + @Test + public void givenDigitsGenerator_whenGeneratingPassword_thenPasswordContainsDigitsHasLength10() { + CharacterRule digits = new CharacterRule(EnglishCharacterData.Digit); + + PasswordGenerator passwordGenerator = new PasswordGenerator(); + String password = passwordGenerator.generatePassword(10, digits); + + Assert.assertTrue(password.length() == 10); + Assert.assertTrue(containsOnlyCharactersFromSet(password, "0123456789")); + } + + @Test + public void givenCustomizedRule_whenGenerating_thenGeneratedPasswordContainsCustomizedCharacters() { + CharacterRule specialCharacterRule = new CharacterRule(new CharacterData() { + @Override + public String getErrorCode() { + return "SAMPLE_ERROR_CODE"; + } + + @Override + public String getCharacters() { + return "ABCxyz123!@#"; + } + }); + + PasswordGenerator passwordGenerator = new PasswordGenerator(); + String password = passwordGenerator.generatePassword(10, specialCharacterRule); + + Assert.assertTrue(containsOnlyCharactersFromSet(password, "ABCxyz123!@#")); + } + + private boolean containsOnlyCharactersFromSet(String password, String setOfCharacters) { + return Stream.of(password.split("")) + .allMatch(it -> setOfCharacters.contains(it)); + } + +} diff --git a/libraries-security/src/test/java/com/baeldung/passay/PasswordValidatorUnitTest.java b/libraries-security/src/test/java/com/baeldung/passay/PasswordValidatorUnitTest.java new file mode 100644 index 0000000000..3fc59a82d5 --- /dev/null +++ b/libraries-security/src/test/java/com/baeldung/passay/PasswordValidatorUnitTest.java @@ -0,0 +1,81 @@ +package com.baeldung.passay; + +import org.junit.Assert; +import org.junit.Test; +import org.passay.LengthRule; +import org.passay.MessageResolver; +import org.passay.PasswordData; +import org.passay.PasswordValidator; +import org.passay.PropertiesMessageResolver; +import org.passay.RuleResult; +import org.passay.RuleResultDetail; +import org.passay.RuleResultMetadata; +import org.passay.WhitespaceRule; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +public class PasswordValidatorUnitTest { + + @Test + public void givenPasswordValidatorWithLengthRule_whenValidation_thenTooShortPassword() { + PasswordData passwordData = new PasswordData("1234"); + + PasswordValidator passwordValidator = new PasswordValidator(new LengthRule(5)); + + RuleResult validate = passwordValidator.validate(passwordData); + assertEquals(false, validate.isValid()); + + RuleResultDetail ruleResultDetail = validate.getDetails() + .get(0); + assertEquals("TOO_SHORT", ruleResultDetail.getErrorCode()); + assertEquals(5, ruleResultDetail.getParameters() + .get("minimumLength")); + assertEquals(5, ruleResultDetail.getParameters() + .get("maximumLength")); + + Integer lengthCount = validate.getMetadata() + .getCounts() + .get(RuleResultMetadata.CountCategory.Length); + assertEquals(Integer.valueOf(4), lengthCount); + } + + @Test + public void givenPasswordValidatorWithLengthRule_whenValidation_thenTooLongPassword() { + PasswordData passwordData = new PasswordData("123456"); + + PasswordValidator passwordValidator = new PasswordValidator(new LengthRule(5)); + + RuleResult validate = passwordValidator.validate(passwordData); + assertFalse(validate.isValid()); + Assert.assertEquals("TOO_LONG", validate.getDetails() + .get(0) + .getErrorCode()); + } + + @Test + public void givenPasswordValidatorWithLengthRule_whenValidation_thenCustomizedMeesagesAvailable() throws IOException { + URL resource = this.getClass() + .getClassLoader() + .getResource("messages.properties"); + Properties props = new Properties(); + props.load(new FileInputStream(resource.getPath())); + + MessageResolver resolver = new PropertiesMessageResolver(props); + PasswordValidator validator = new PasswordValidator(resolver, new LengthRule(8, 16), new WhitespaceRule()); + + RuleResult tooShort = validator.validate(new PasswordData("XXXX")); + RuleResult tooLong = validator.validate(new PasswordData("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ")); + + assertEquals("Password must not contain less characters than 16.", validator.getMessages(tooShort) + .get(0)); + assertEquals("Password must not have more characters than 16.", validator.getMessages(tooLong) + .get(0)); + } + +} diff --git a/libraries-security/src/test/java/com/baeldung/passay/PositiveMatchingRulesUnitTest.java b/libraries-security/src/test/java/com/baeldung/passay/PositiveMatchingRulesUnitTest.java new file mode 100644 index 0000000000..0da1b43335 --- /dev/null +++ b/libraries-security/src/test/java/com/baeldung/passay/PositiveMatchingRulesUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.passay; + +import org.junit.Test; +import org.passay.AllowedCharacterRule; +import org.passay.AllowedRegexRule; +import org.passay.CharacterCharacteristicsRule; +import org.passay.CharacterRule; +import org.passay.EnglishCharacterData; +import org.passay.LengthComplexityRule; +import org.passay.LengthRule; +import org.passay.PasswordData; +import org.passay.PasswordValidator; +import org.passay.RuleResult; + +import static org.junit.Assert.*; + +public class PositiveMatchingRulesUnitTest { + + @Test + public void givenPasswordValidationRules_whenValidatingPassword_thenPosswordIsNotValidWithSeveralErrors() { + PasswordValidator passwordValidator = new PasswordValidator(new AllowedCharacterRule(new char[] { 'a', 'b', 'c' }), new AllowedRegexRule("\\d{2}\\w{10}"), new CharacterRule(EnglishCharacterData.LowerCase, 5), new LengthRule(8, 10)); + + RuleResult validate = passwordValidator.validate(new PasswordData("12abc")); + + assertFalse(validate.isValid()); + assertEquals("ALLOWED_CHAR:{illegalCharacter=1, matchBehavior=contains}", getDetail(validate, 0)); + assertEquals("ALLOWED_CHAR:{illegalCharacter=2, matchBehavior=contains}", getDetail(validate, 1)); + assertEquals("ALLOWED_MATCH:{pattern=\\d{2}\\w{10}}", getDetail(validate, 2)); + assertEquals("INSUFFICIENT_LOWERCASE:{" + "minimumRequired=5, matchingCharacterCount=3, " + "validCharacters=abcdefghijklmnopqrstuvwxyz, " + "matchingCharacters=abc}", getDetail(validate, 3)); + assertEquals("TOO_SHORT:{minimumLength=8, maximumLength=10}", getDetail(validate, 4)); + } + + @Test + public void givenRulesForDifferentPasswordLength_whenValidatingTwoDifferentPassword_thenBothOfThemAreInvalid() { + PasswordData shortPassword = new PasswordData("12ab"); + PasswordData longPassword = new PasswordData("1234abcde"); + + LengthComplexityRule lengthComplexityRule = new LengthComplexityRule(); + lengthComplexityRule.addRules("[1,5]", new CharacterRule(EnglishCharacterData.LowerCase, 5)); + lengthComplexityRule.addRules("[6,10]", new AllowedCharacterRule(new char[] { 'a', 'b', 'c', 'd' })); + + PasswordValidator passwordValidator = new PasswordValidator(lengthComplexityRule); + + RuleResult validateShort = passwordValidator.validate(shortPassword); + RuleResult validateLong = passwordValidator.validate(longPassword); + + assertFalse(validateShort.isValid()); + assertFalse(validateLong.isValid()); + + assertEquals("INSUFFICIENT_LOWERCASE:{" + "minimumRequired=5, " + "matchingCharacterCount=2, " + "validCharacters=abcdefghijklmnopqrstuvwxyz, " + "matchingCharacters=ab}", getDetail(validateShort, 0)); + assertEquals("ALLOWED_CHAR:{illegalCharacter=1, matchBehavior=contains}", getDetail(validateLong, 0)); + } + + @Test + public void givenCharacterCharacteristicsRule_whenValidatingPassword_thenItIsInvalidAsItBreaksToManyRules() { + PasswordData shortPassword = new PasswordData(); + shortPassword.setPassword("12345abcde!"); + + CharacterCharacteristicsRule characterCharacteristicsRule = new CharacterCharacteristicsRule(4, new CharacterRule(EnglishCharacterData.LowerCase, 5), new CharacterRule(EnglishCharacterData.UpperCase, 5), new CharacterRule(EnglishCharacterData.Digit), + new CharacterRule(EnglishCharacterData.Special)); + + PasswordValidator passwordValidator = new PasswordValidator(characterCharacteristicsRule); + + RuleResult validate = passwordValidator.validate(shortPassword); + assertFalse(validate.isValid()); + + assertEquals("INSUFFICIENT_UPPERCASE:{" + "minimumRequired=5, " + "matchingCharacterCount=0, " + "validCharacters=ABCDEFGHIJKLMNOPQRSTUVWXYZ, " + "matchingCharacters=}", getDetail(validate, 0)); + assertEquals("INSUFFICIENT_CHARACTERISTICS:{" + "successCount=3, " + "minimumRequired=4, " + "ruleCount=4}", getDetail(validate, 1)); + } + + private String getDetail(RuleResult validate, int i) { + return validate.getDetails() + .get(i) + .toString(); + } +} diff --git a/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/spring/cloud/LogSinkApplicationIntegrationTest.java b/libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java similarity index 67% rename from spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/spring/cloud/LogSinkApplicationIntegrationTest.java rename to libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java index b362d72705..6565a5b085 100644 --- a/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/spring/cloud/LogSinkApplicationIntegrationTest.java +++ b/libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.cloud; +package com.baeldung.scribejava; import org.junit.Test; import org.junit.runner.RunWith; @@ -7,10 +7,11 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class LogSinkApplicationIntegrationTest { +public class ScribejavaUnitTest { @Test - public void contextLoads() { + public void contextLoad(){ + } } diff --git a/libraries-security/src/test/resources/messages.properties b/libraries-security/src/test/resources/messages.properties new file mode 100644 index 0000000000..ad0039d71d --- /dev/null +++ b/libraries-security/src/test/resources/messages.properties @@ -0,0 +1,2 @@ +TOO_LONG=Password must not have more characters than %2$s. +TOO_SHORT=Password must not contain less characters than %2$s. \ No newline at end of file diff --git a/libraries-server/.gitignore b/libraries-server/.gitignore new file mode 100644 index 0000000000..e594daf27a --- /dev/null +++ b/libraries-server/.gitignore @@ -0,0 +1,9 @@ +*.class + +# Folders # +/gensrc +/target + +# Packaged files # +*.jar +/bin/ diff --git a/libraries-server/README.md b/libraries-server/README.md new file mode 100644 index 0000000000..28f963ade8 --- /dev/null +++ b/libraries-server/README.md @@ -0,0 +1,9 @@ +### Relevant articles + +- [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded) +- [Introduction to Netty](http://www.baeldung.com/netty) +- [Exceptions in Netty](http://www.baeldung.com/netty-exception-handling) +- [Programatically Create, Configure, and Run a Tomcat Server](http://www.baeldung.com/tomcat-programmatic-setup) +- [Creating and Configuring Jetty 9 Server in Java](http://www.baeldung.com/jetty-java-programmatic) +- [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel) +- [MQTT Client in Java](https://www.baeldung.com/java-mqtt-client) diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml new file mode 100644 index 0000000000..6fca09faf4 --- /dev/null +++ b/libraries-server/pom.xml @@ -0,0 +1,86 @@ + + 4.0.0 + com.baeldung + libraries-server + 0.0.1-SNAPSHOT + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + 1.2.0 + + + + org.assertj + assertj-core + ${assertj.version} + + + org.eclipse.jetty + jetty-server + ${jetty.version} + + + org.eclipse.jetty + jetty-servlet + ${jetty.version} + + + org.eclipse.jetty + jetty-webapp + ${jetty.version} + + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + commons-logging + commons-logging + + + + + commons-io + commons-io + ${commons.io.version} + + + io.netty + netty-all + ${netty.version} + + + junit + junit + ${junit.version} + test + + + + + org.apache.tomcat + tomcat-catalina + ${tomcat.version} + + + + + 3.6.2 + 4.5.3 + 2.5 + 9.4.8.v20171121 + 4.1.20.Final + 4.1 + 4.12 + 8.5.24 + + + \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/jetty/AsyncServlet.java b/libraries-server/src/main/java/com/baeldung/jetty/AsyncServlet.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jetty/AsyncServlet.java rename to libraries-server/src/main/java/com/baeldung/jetty/AsyncServlet.java diff --git a/libraries/src/main/java/com/baeldung/jetty/BlockingServlet.java b/libraries-server/src/main/java/com/baeldung/jetty/BlockingServlet.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jetty/BlockingServlet.java rename to libraries-server/src/main/java/com/baeldung/jetty/BlockingServlet.java diff --git a/libraries/src/main/java/com/baeldung/jetty/JettyServer.java b/libraries-server/src/main/java/com/baeldung/jetty/JettyServer.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jetty/JettyServer.java rename to libraries-server/src/main/java/com/baeldung/jetty/JettyServer.java diff --git a/libraries/src/main/java/com/baeldung/jetty/JettyServerFactory.java b/libraries-server/src/main/java/com/baeldung/jetty/JettyServerFactory.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jetty/JettyServerFactory.java rename to libraries-server/src/main/java/com/baeldung/jetty/JettyServerFactory.java diff --git a/libraries/src/main/java/com/baeldung/jetty/LoggingRequestHandler.java b/libraries-server/src/main/java/com/baeldung/jetty/LoggingRequestHandler.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jetty/LoggingRequestHandler.java rename to libraries-server/src/main/java/com/baeldung/jetty/LoggingRequestHandler.java diff --git a/libraries-server/src/main/java/com/baeldung/mqtt/EngineTemperatureSensor.java b/libraries-server/src/main/java/com/baeldung/mqtt/EngineTemperatureSensor.java new file mode 100644 index 0000000000..98111edb94 --- /dev/null +++ b/libraries-server/src/main/java/com/baeldung/mqtt/EngineTemperatureSensor.java @@ -0,0 +1,49 @@ +package com.baeldung.mqtt; + +import java.util.Random; +import java.util.concurrent.Callable; + +import org.eclipse.paho.client.mqttv3.IMqttClient; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EngineTemperatureSensor implements Callable { + + private static final Logger log = LoggerFactory.getLogger(EngineTemperatureSensor.class); + public static final String TOPIC = "engine/temperature"; + + private IMqttClient client; + private Random rnd = new Random(); + + public EngineTemperatureSensor(IMqttClient client) { + this.client = client; + } + + @Override + public Void call() throws Exception { + + if ( !client.isConnected()) { + log.info("[I31] Client not connected."); + return null; + } + + MqttMessage msg = readEngineTemp(); + msg.setQos(0); + msg.setRetained(true); + client.publish(TOPIC,msg); + + return null; + } + + /** + * This method simulates reading the engine temperature + * @return + */ + private MqttMessage readEngineTemp() { + double temp = 80 + rnd.nextDouble() * 20.0; + byte[] payload = String.format("T:%04.2f",temp).getBytes(); + MqttMessage msg = new MqttMessage(payload); + return msg; + } +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/netty/CalculatorOperationHandler.java b/libraries-server/src/main/java/com/baeldung/netty/CalculatorOperationHandler.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/CalculatorOperationHandler.java rename to libraries-server/src/main/java/com/baeldung/netty/CalculatorOperationHandler.java diff --git a/libraries/src/main/java/com/baeldung/netty/ChannelHandlerA.java b/libraries-server/src/main/java/com/baeldung/netty/ChannelHandlerA.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/ChannelHandlerA.java rename to libraries-server/src/main/java/com/baeldung/netty/ChannelHandlerA.java diff --git a/libraries/src/main/java/com/baeldung/netty/ChannelHandlerB.java b/libraries-server/src/main/java/com/baeldung/netty/ChannelHandlerB.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/ChannelHandlerB.java rename to libraries-server/src/main/java/com/baeldung/netty/ChannelHandlerB.java diff --git a/libraries/src/main/java/com/baeldung/netty/ClientHandler.java b/libraries-server/src/main/java/com/baeldung/netty/ClientHandler.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/ClientHandler.java rename to libraries-server/src/main/java/com/baeldung/netty/ClientHandler.java diff --git a/libraries/src/main/java/com/baeldung/netty/HttpMessageHandler.java b/libraries-server/src/main/java/com/baeldung/netty/HttpMessageHandler.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/HttpMessageHandler.java rename to libraries-server/src/main/java/com/baeldung/netty/HttpMessageHandler.java diff --git a/libraries/src/main/java/com/baeldung/netty/NettyClient.java b/libraries-server/src/main/java/com/baeldung/netty/NettyClient.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/NettyClient.java rename to libraries-server/src/main/java/com/baeldung/netty/NettyClient.java diff --git a/libraries/src/main/java/com/baeldung/netty/NettyServer.java b/libraries-server/src/main/java/com/baeldung/netty/NettyServer.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/NettyServer.java rename to libraries-server/src/main/java/com/baeldung/netty/NettyServer.java diff --git a/libraries/src/main/java/com/baeldung/netty/NettyServerB.java b/libraries-server/src/main/java/com/baeldung/netty/NettyServerB.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/NettyServerB.java rename to libraries-server/src/main/java/com/baeldung/netty/NettyServerB.java diff --git a/libraries/src/main/java/com/baeldung/netty/Operation.java b/libraries-server/src/main/java/com/baeldung/netty/Operation.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/Operation.java rename to libraries-server/src/main/java/com/baeldung/netty/Operation.java diff --git a/libraries/src/main/java/com/baeldung/netty/ProcessingHandler.java b/libraries-server/src/main/java/com/baeldung/netty/ProcessingHandler.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/ProcessingHandler.java rename to libraries-server/src/main/java/com/baeldung/netty/ProcessingHandler.java diff --git a/libraries/src/main/java/com/baeldung/netty/RequestData.java b/libraries-server/src/main/java/com/baeldung/netty/RequestData.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/RequestData.java rename to libraries-server/src/main/java/com/baeldung/netty/RequestData.java diff --git a/libraries/src/main/java/com/baeldung/netty/RequestDataEncoder.java b/libraries-server/src/main/java/com/baeldung/netty/RequestDataEncoder.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/RequestDataEncoder.java rename to libraries-server/src/main/java/com/baeldung/netty/RequestDataEncoder.java diff --git a/libraries/src/main/java/com/baeldung/netty/RequestDecoder.java b/libraries-server/src/main/java/com/baeldung/netty/RequestDecoder.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/RequestDecoder.java rename to libraries-server/src/main/java/com/baeldung/netty/RequestDecoder.java diff --git a/libraries/src/main/java/com/baeldung/netty/ResponseData.java b/libraries-server/src/main/java/com/baeldung/netty/ResponseData.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/ResponseData.java rename to libraries-server/src/main/java/com/baeldung/netty/ResponseData.java diff --git a/libraries/src/main/java/com/baeldung/netty/ResponseDataDecoder.java b/libraries-server/src/main/java/com/baeldung/netty/ResponseDataDecoder.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/ResponseDataDecoder.java rename to libraries-server/src/main/java/com/baeldung/netty/ResponseDataDecoder.java diff --git a/libraries/src/main/java/com/baeldung/netty/ResponseDataEncoder.java b/libraries-server/src/main/java/com/baeldung/netty/ResponseDataEncoder.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/ResponseDataEncoder.java rename to libraries-server/src/main/java/com/baeldung/netty/ResponseDataEncoder.java diff --git a/libraries/src/main/java/com/baeldung/netty/SimpleProcessingHandler.java b/libraries-server/src/main/java/com/baeldung/netty/SimpleProcessingHandler.java similarity index 100% rename from libraries/src/main/java/com/baeldung/netty/SimpleProcessingHandler.java rename to libraries-server/src/main/java/com/baeldung/netty/SimpleProcessingHandler.java diff --git a/libraries/src/main/java/com/baeldung/tomcat/MyFilter.java b/libraries-server/src/main/java/com/baeldung/tomcat/MyFilter.java similarity index 100% rename from libraries/src/main/java/com/baeldung/tomcat/MyFilter.java rename to libraries-server/src/main/java/com/baeldung/tomcat/MyFilter.java diff --git a/libraries/src/main/java/com/baeldung/tomcat/MyServlet.java b/libraries-server/src/main/java/com/baeldung/tomcat/MyServlet.java similarity index 100% rename from libraries/src/main/java/com/baeldung/tomcat/MyServlet.java rename to libraries-server/src/main/java/com/baeldung/tomcat/MyServlet.java diff --git a/libraries/src/main/java/com/baeldung/tomcat/ProgrammaticTomcat.java b/libraries-server/src/main/java/com/baeldung/tomcat/ProgrammaticTomcat.java similarity index 100% rename from libraries/src/main/java/com/baeldung/tomcat/ProgrammaticTomcat.java rename to libraries-server/src/main/java/com/baeldung/tomcat/ProgrammaticTomcat.java diff --git a/libraries-server/src/main/resources/logback.xml b/libraries-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/libraries-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/jetty/JettyIntegrationTest.java b/libraries-server/src/test/java/com/baeldung/jetty/JettyIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jetty/JettyIntegrationTest.java rename to libraries-server/src/test/java/com/baeldung/jetty/JettyIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/jetty/JettyServerFactoryUnitTest.java b/libraries-server/src/test/java/com/baeldung/jetty/JettyServerFactoryUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jetty/JettyServerFactoryUnitTest.java rename to libraries-server/src/test/java/com/baeldung/jetty/JettyServerFactoryUnitTest.java diff --git a/libraries-server/src/test/java/com/baeldung/mqtt/EngineTemperatureSensorLiveTest.java b/libraries-server/src/test/java/com/baeldung/mqtt/EngineTemperatureSensorLiveTest.java new file mode 100644 index 0000000000..b1c0002888 --- /dev/null +++ b/libraries-server/src/test/java/com/baeldung/mqtt/EngineTemperatureSensorLiveTest.java @@ -0,0 +1,109 @@ +package com.baeldung.mqtt; + + + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.eclipse.paho.client.mqttv3.MqttClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EngineTemperatureSensorLiveTest { + + private static Logger log = LoggerFactory.getLogger(EngineTemperatureSensorLiveTest.class); + + @Test + public void whenSendSingleMessage_thenSuccess() throws Exception { + + String publisherId = UUID.randomUUID().toString(); + MqttClient publisher = new MqttClient("tcp://iot.eclipse.org:1883",publisherId); + + String subscriberId = UUID.randomUUID().toString(); + MqttClient subscriber = new MqttClient("tcp://iot.eclipse.org:1883",subscriberId); + + MqttConnectOptions options = new MqttConnectOptions(); + options.setAutomaticReconnect(true); + options.setCleanSession(true); + options.setConnectionTimeout(10); + + + subscriber.connect(options); + publisher.connect(options); + + CountDownLatch receivedSignal = new CountDownLatch(1); + + subscriber.subscribe(EngineTemperatureSensor.TOPIC, (topic, msg) -> { + byte[] payload = msg.getPayload(); + log.info("[I46] Message received: topic={}, payload={}", topic, new String(payload)); + receivedSignal.countDown(); + }); + + + Callable target = new EngineTemperatureSensor(publisher); + target.call(); + + receivedSignal.await(1, TimeUnit.MINUTES); + + log.info("[I56] Success !"); + } + + @Test + public void whenSendMultipleMessages_thenSuccess() throws Exception { + + String publisherId = UUID.randomUUID().toString(); + MqttClient publisher = new MqttClient("tcp://iot.eclipse.org:1883",publisherId); + + String subscriberId = UUID.randomUUID().toString(); + MqttClient subscriber = new MqttClient("tcp://iot.eclipse.org:1883",subscriberId); + + + MqttConnectOptions options = new MqttConnectOptions(); + options.setAutomaticReconnect(true); + options.setCleanSession(true); + options.setConnectionTimeout(10); + + + publisher.connect(options); + subscriber.connect(options); + + CountDownLatch receivedSignal = new CountDownLatch(10); + + subscriber.subscribe(EngineTemperatureSensor.TOPIC, (topic, msg) -> { + byte[] payload = msg.getPayload(); + log.info("[I82] Message received: topic={}, payload={}", topic, new String(payload)); + receivedSignal.countDown(); + }); + + + Callable target = new EngineTemperatureSensor(publisher); + + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + executor.scheduleAtFixedRate(() -> { + try { + target.call(); + } + catch(Exception ex) { + throw new RuntimeException(ex); + } + }, 1, 1, TimeUnit.SECONDS); + + + receivedSignal.await(1, TimeUnit.MINUTES); + executor.shutdown(); + + assertTrue(receivedSignal.getCount() == 0 , "Countdown should be zero"); + + log.info("[I105] Success !"); + } + + +} diff --git a/libraries/src/test/java/com/baeldung/netty/EmbeddedChannelUnitTest.java b/libraries-server/src/test/java/com/baeldung/netty/EmbeddedChannelUnitTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/netty/EmbeddedChannelUnitTest.java rename to libraries-server/src/test/java/com/baeldung/netty/EmbeddedChannelUnitTest.java diff --git a/libraries/src/test/java/com/baeldung/tomcat/ProgrammaticTomcatIntegrationTest.java b/libraries-server/src/test/java/com/baeldung/tomcat/ProgrammaticTomcatIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/tomcat/ProgrammaticTomcatIntegrationTest.java rename to libraries-server/src/test/java/com/baeldung/tomcat/ProgrammaticTomcatIntegrationTest.java diff --git a/libraries/src/test/resources/jetty-embedded-demo-app.war b/libraries-server/src/test/resources/jetty-embedded-demo-app.war similarity index 100% rename from libraries/src/test/resources/jetty-embedded-demo-app.war rename to libraries-server/src/test/resources/jetty-embedded-demo-app.war diff --git a/libraries/.gitignore b/libraries/.gitignore index ac45fafa62..e594daf27a 100644 --- a/libraries/.gitignore +++ b/libraries/.gitignore @@ -6,3 +6,4 @@ # Packaged files # *.jar +/bin/ diff --git a/libraries/README.md b/libraries/README.md index 3ef6303c88..fcf687d806 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -5,13 +5,11 @@ - [String Processing with Apache Commons Lang 3](http://www.baeldung.com/string-processing-commons-lang) - [Introduction to Javatuples](http://www.baeldung.com/java-tuples) - [Introduction to Javassist](http://www.baeldung.com/javassist) -- [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded) - [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink) - [Introduction to JSONassert](http://www.baeldung.com/jsonassert) - [Intro to JaVers](http://www.baeldung.com/javers) - [Introduction to Apache Commons Math](http://www.baeldung.com/apache-commons-math) - [Intro to Serenity BDD](http://www.baeldung.com/serenity-bdd) -- [Introduction to Netty](http://www.baeldung.com/netty) - [Merging Streams in Java](http://www.baeldung.com/java-merge-streams) - [Serenity BDD and Screenplay](http://www.baeldung.com/serenity-screenplay) - [Introduction to Quartz](http://www.baeldung.com/quartz) @@ -35,7 +33,6 @@ - [Introduction to Eclipse Collections](http://www.baeldung.com/eclipse-collections) - [DistinctBy in Java Stream API](http://www.baeldung.com/java-streams-distinct-by) - [Introduction to Apache Commons CSV](http://www.baeldung.com/apache-commons-csv) -- [Difference Between Two Dates in Java](http://www.baeldung.com/java-date-difference) - [Introduction to NoException](http://www.baeldung.com/no-exception) - [Apache Commons IO](http://www.baeldung.com/apache-commons-io) - [Introduction to Conflict-Free Replicated Data Types](http://www.baeldung.com/java-conflict-free-replicated-data-types) @@ -55,10 +52,7 @@ - [Introduction to BouncyCastle with Java](http://www.baeldung.com/java-bouncy-castle) - [Guide to google-http-client](http://www.baeldung.com/google-http-client) - [Interact with Google Sheets from Java](http://www.baeldung.com/google-sheets-java-client) -- [Programatically Create, Configure, and Run a Tomcat Server](http://www.baeldung.com/tomcat-programmatic-setup) - [A Docker Guide for Java](http://www.baeldung.com/docker-java-api) -- [Exceptions in Netty](http://www.baeldung.com/netty-exception-handling) -- [Creating and Configuring Jetty 9 Server in Java](http://www.baeldung.com/jetty-java-programmatic) - [Introduction To OpenCSV](http://www.baeldung.com/opencsv) - [Introduction to Akka Actors in Java](http://www.baeldung.com/akka-actors-java) - [Asynchronous HTTP with async-http-client in Java](http://www.baeldung.com/async-http-client) @@ -78,10 +72,17 @@ - [Publish and Receive Messages with Nats Java Client](http://www.baeldung.com/nats-java-client) - [Java Concurrency Utility with JCTools](http://www.baeldung.com/java-concurrency-jc-tools) - [Apache Commons Collections MapUtils](http://www.baeldung.com/apache-commons-map-utils) -- [Testing Netty with EmbeddedChannel](http://www.baeldung.com/testing-netty-embedded-channel) - [Creating REST Microservices with Javalin](http://www.baeldung.com/javalin-rest-microservices) - - +- [Introduction to JavaPoet](http://www.baeldung.com/java-poet) +- [Introduction to Joda-Time](http://www.baeldung.com/joda-time) +- [Implementing a FTP-Client in Java](http://www.baeldung.com/java-ftp-client) +- [Convert String to Date in Java](http://www.baeldung.com/java-string-to-date) +- [Histograms with Apache Commons Frequency](http://www.baeldung.com/apache-commons-frequency) +- [Guide to Resilience4j](http://www.baeldung.com/resilience4j) +- [Parsing YAML with SnakeYAML](http://www.baeldung.com/java-snake-yaml) +- [Guide to JMapper](http://www.baeldung.com/jmapper) +- [An Introduction to Apache Commons Lang 3](https://www.baeldung.com/java-commons-lang-3) +- [Exactly Once Processing in Kafka](https://www.baeldung.com/kafka-exactly-once) The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. diff --git a/libraries/pom.xml b/libraries/pom.xml index e3a6656995..6bbe8e6f1c 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 libraries libraries @@ -67,7 +68,7 @@ tec.units unit-ri - 1.0.3 + ${unit-ri.version} org.apache.commons @@ -105,21 +106,6 @@ javers-core ${javers.version} - - org.eclipse.jetty - jetty-server - ${jetty.version} - - - org.eclipse.jetty - jetty-servlet - ${jetty.version} - - - org.eclipse.jetty - jetty-webapp - ${jetty.version} - io.nats @@ -135,7 +121,7 @@ io.specto hoverfly-java - 0.8.1 + ${hoverfly-java.version} org.apache.httpcomponents @@ -168,44 +154,23 @@ commons-dbutils ${commons.dbutils.version} - - org.apache.flink - flink-core - ${flink.version} - - - commons-logging - commons-logging - - - - - org.apache.flink - flink-java - ${flink.version} - - - commons-logging - commons-logging - - - - - org.apache.flink - flink-test-utils_2.10 - ${flink.version} - test - + org.apache.commons commons-math3 - 3.6.1 + ${common-math3.version} net.serenity-bdd serenity-core ${serenity.version} test + + + org.asciidoctor + asciidoctorj + + net.serenity-bdd @@ -236,46 +201,47 @@ jackson-databind ${jackson.version} + org.datanucleus javax.jdo - 3.2.0-m7 + ${javax.jdo.version} org.datanucleus datanucleus-core - 5.1.1 + ${datanucleus.version} org.datanucleus datanucleus-api-jdo - 5.1.1 + ${datanucleus.version} org.datanucleus datanucleus-rdbms - 5.1.1 + ${datanucleus.version} org.datanucleus datanucleus-maven-plugin - 5.0.2 + ${datanucleus-maven-plugin.version} org.datanucleus datanucleus-xml - 5.0.0-release + ${datanucleus-xml.version} org.datanucleus datanucleus-jdo-query - 5.0.2 + ${datanucleus-jdo-query.version} net.openhft chronicle - 3.6.4 + ${chronicle.version} com.sun.java @@ -286,7 +252,7 @@ org.springframework spring-web - 4.3.8.RELEASE + ${spring.version} net.serenity-bdd @@ -322,7 +288,7 @@ io.rest-assured spring-mock-mvc - 3.0.3 + ${spring-mock-mvc.version} test @@ -333,7 +299,7 @@ com.zaxxer HikariCP - 2.6.3 + ${HikariCP.version} compile @@ -350,7 +316,7 @@ org.quartz-scheduler quartz - 2.3.0 + ${quartz.version} one.util @@ -360,22 +326,17 @@ org.jooq jool - 0.9.12 + ${jool.version} org.openjdk.jmh jmh-core - 1.19 + ${jmh.version} org.openjdk.jmh jmh-generator-annprocess - 1.19 - - - io.netty - netty-all - ${netty.version} + ${jmh.version} junit @@ -397,7 +358,8 @@ org.codehaus.groovy groovy-all - 2.4.10 + pom + ${groovy.version} org.awaitility @@ -440,7 +402,7 @@ com.machinezoo.noexception noexception - 1.1.0 + ${noexception.version} org.eclipse.collections @@ -472,18 +434,7 @@ com.squareup.okhttp3 logging-interceptor - 3.9.0 - - - com.darwinsys - hirondelle-date4j - RELEASE - test - - - joda-time - joda-time - ${joda-time.version} + ${logging-interceptor.version} com.darwinsys @@ -493,17 +444,17 @@ com.haulmont.yarg yarg - 2.0.4 + ${yarg.version} net.engio mbassador - 1.3.1 + ${mbassador.version} org.jdeferred jdeferred-core - 1.2.6 + ${jdeferred.version} com.codepoetics @@ -513,22 +464,22 @@ org.functionaljava functionaljava - 4.7 + ${functionaljava.version} org.functionaljava functionaljava-java8 - 4.7 + ${functionaljava.version} org.functionaljava functionaljava-quickcheck - 4.7 + ${functionaljava.version} org.functionaljava functionaljava-java-core - 4.7 + ${functionaljava.version} javax.cache @@ -543,7 +494,7 @@ org.jgrapht jgrapht-core - 1.0.1 + ${jgrapht.version} com.netopyr.wurmloch @@ -553,12 +504,12 @@ org.docx4j docx4j - 3.3.5 + ${docx4j.version} javax.xml.bind jaxb-api - 2.1 + ${jaxb-api.version} com.github.ben-manes.caffeine @@ -568,12 +519,12 @@ org.bouncycastle bcprov-jdk15on - 1.58 + ${bouncycastle.version} org.bouncycastle bcpkix-jdk15on - 1.58 + ${bouncycastle.version} com.google.http-client @@ -619,7 +570,7 @@ com.sun.jersey jersey-client - 1.19.4 + ${jersey.version} @@ -662,13 +613,7 @@ test test - - - - org.apache.tomcat - tomcat-catalina - ${tomcat.version} - + org.milyn milyn-smooks-all @@ -684,13 +629,13 @@ io.javalin javalin - 1.6.0 + ${javalin.version} io.atlassian.fugue fugue - 4.5.1 + ${fugue.version} @@ -699,10 +644,36 @@ ${jctools.version} + - org.apache.commons - commons-math3 - ${common-math3-version} + io.github.resilience4j + resilience4j-circuitbreaker + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-ratelimiter + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-bulkhead + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-retry + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-cache + ${resilience4j.version} + + + io.github.resilience4j + resilience4j-timelimiter + ${resilience4j.version} org.knowm.xchart @@ -734,6 +705,12 @@ test + + org.yaml + snakeyaml + ${snakeyaml.version} + + @@ -759,19 +736,6 @@ - - org.apache.maven.plugins - maven-dependency-plugin - - - org.apache.felix - maven-bundle-plugin - 3.3.0 - maven-plugin - - - true - maven-failsafe-plugin ${maven-failsafe-plugin.version} @@ -799,7 +763,7 @@ org.datanucleus datanucleus-maven-plugin - 5.0.2 + ${datanucleus-maven-plugin.version} JDO ${basedir}/datanucleus.properties @@ -821,7 +785,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.0.2 + ${maven-jar-plugin.version} **/log4j.properties @@ -854,10 +818,7 @@ - + *:* META-INF/*.SF @@ -874,10 +835,11 @@ + 1.21 1.23.0 0.1.0 0.7.0 - 3.2.4 + 3.2.7 3.6 1.1 1.9.3 @@ -893,20 +855,17 @@ 2.5 1.6 1.4.196 - 9.4.8.v20171121 1.0 4.5.3 2.5 - 1.2.0 2.8.5 2.92 - 1.4.0 - 1.24.0 - 1.1.3-rc.5 - 1.4.0 + 1.9.26 + 1.41.0 + 1.9.0 + 1.9.27 1.1.0 - 4.1.20.Final 4.1 4.12 0.10 @@ -921,22 +880,20 @@ 0.6.5 0.9.0 15.2 - 2.9.9 1.5.1 2.3.0 - 2.9.9 + 2.10 1.5.1 - 1.14 + 1.15 1.0.3 1.0.0 - 3.8.4 + 3.10.2 2.5.5 1.23.0 v4-rev493-1.21.0 - 1.0.0 + 2.0.0 1.7.0 3.0.14 - 8.5.24 2.2.0 9.1.5.Final 4.1 @@ -946,12 +903,42 @@ 0.9.4.0006L 2.1.2 2.5.11 - 3.6.1 + 0.12.1 3.5.2 3.6 2.7.1 1.10.0 1.3 + 0.8.1 + 3.6.1 + 3.2.0-m7 + 5.1.1 + 5.0.2 + 5.0.0-release + 5.0.2 + 3.6.4 + 4.3.8.RELEASE + 3.0.3 + 2.6.3 + 2.3.0 + 0.9.12 + 1.19 + 2.5.2 + 1.1.0 + 3.9.0 + 2.0.4 + 1.3.1 + 1.2.6 + 4.7 + 1.0.1 + 3.3.5 + 2.1 + 1.58 + 1.19.4 + 1.6.0 + 4.5.1 + 3.3.0 + 3.0.2 - \ No newline at end of file + diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java b/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java new file mode 100644 index 0000000000..7d4316e3ec --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.commons.lang3.application; + +public class Application { + + public static void main(String[] args) { + + } +} diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java b/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java new file mode 100644 index 0000000000..68aab46c33 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java @@ -0,0 +1,25 @@ +package com.baeldung.commons.lang3.beans; + +public class User { + + private final String name; + private final String email; + + public User(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + + @Override + public String toString() { + return "User{" + "name=" + name + ", email=" + email + '}'; + } +} diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java b/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java new file mode 100644 index 0000000000..ae5d80244c --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java @@ -0,0 +1,11 @@ +package com.baeldung.commons.lang3.beans; + +import org.apache.commons.lang3.concurrent.LazyInitializer; + +public class UserInitializer extends LazyInitializer { + + @Override + protected User initialize() { + return new User("John", "john@domain.com"); + } +} diff --git a/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java b/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java new file mode 100644 index 0000000000..15488bbaf4 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java @@ -0,0 +1,56 @@ +package com.baeldung.kafka; + +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.KafkaException; + +import java.util.Properties; +import java.util.stream.Stream; + +import static org.apache.kafka.clients.consumer.ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.TRANSACTIONAL_ID_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG; + +public class TransactionalMessageProducer { + + private static final String DATA_MESSAGE_1 = "Put any space separated data here for count"; + private static final String DATA_MESSAGE_2 = "Output will contain count of every word in the message"; + + public static void main(String[] args) { + + KafkaProducer producer = createKafkaProducer(); + + producer.initTransactions(); + + try{ + + producer.beginTransaction(); + + Stream.of(DATA_MESSAGE_1, DATA_MESSAGE_2).forEach(s -> producer.send( + new ProducerRecord("input", null, s))); + + producer.commitTransaction(); + + }catch (KafkaException e){ + + producer.abortTransaction(); + + } + + } + + private static KafkaProducer createKafkaProducer() { + + Properties props = new Properties(); + props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ENABLE_IDEMPOTENCE_CONFIG, "true"); + props.put(TRANSACTIONAL_ID_CONFIG, "prod-0"); + props.put(KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + props.put(VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + + return new KafkaProducer(props); + + } +} diff --git a/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java b/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java new file mode 100644 index 0000000000..0563ba6684 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java @@ -0,0 +1,105 @@ +package com.baeldung.kafka; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.consumer.OffsetAndMetadata; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.KafkaException; +import org.apache.kafka.common.TopicPartition; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.time.Duration.ofSeconds; +import static java.util.Collections.singleton; +import static org.apache.kafka.clients.consumer.ConsumerConfig.*; +import static org.apache.kafka.clients.consumer.ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.*; + +public class TransactionalWordCount { + + private static final String CONSUMER_GROUP_ID = "my-group-id"; + private static final String OUTPUT_TOPIC = "output"; + private static final String INPUT_TOPIC = "input"; + + public static void main(String[] args) { + + KafkaConsumer consumer = createKafkaConsumer(); + KafkaProducer producer = createKafkaProducer(); + + producer.initTransactions(); + + try { + + while (true) { + + ConsumerRecords records = consumer.poll(ofSeconds(60)); + + Map wordCountMap = records.records(new TopicPartition(INPUT_TOPIC, 0)) + .stream() + .flatMap(record -> Stream.of(record.value().split(" "))) + .map(word -> Tuple.of(word, 1)) + .collect(Collectors.toMap(tuple -> tuple.getKey(), t1 -> t1.getValue(), (v1, v2) -> v1 + v2)); + + producer.beginTransaction(); + + wordCountMap.forEach((key, value) -> producer.send(new ProducerRecord(OUTPUT_TOPIC, key, value.toString()))); + + Map offsetsToCommit = new HashMap<>(); + + for (TopicPartition partition : records.partitions()) { + List> partitionedRecords = records.records(partition); + long offset = partitionedRecords.get(partitionedRecords.size() - 1).offset(); + + offsetsToCommit.put(partition, new OffsetAndMetadata(offset + 1)); + } + + producer.sendOffsetsToTransaction(offsetsToCommit, CONSUMER_GROUP_ID); + producer.commitTransaction(); + + } + + } catch (KafkaException e) { + + producer.abortTransaction(); + + } + + + } + + private static KafkaConsumer createKafkaConsumer() { + Properties props = new Properties(); + props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(GROUP_ID_CONFIG, CONSUMER_GROUP_ID); + props.put(ENABLE_AUTO_COMMIT_CONFIG, "false"); + props.put(ISOLATION_LEVEL_CONFIG, "read_committed"); + props.put(KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + props.put(VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + + KafkaConsumer consumer = new KafkaConsumer<>(props); + consumer.subscribe(singleton(INPUT_TOPIC)); + return consumer; + } + + private static KafkaProducer createKafkaProducer() { + + Properties props = new Properties(); + props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ENABLE_IDEMPOTENCE_CONFIG, "true"); + props.put(TRANSACTIONAL_ID_CONFIG, "prod-1"); + props.put(KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + props.put(VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + + return new KafkaProducer(props); + + } + +} diff --git a/libraries/src/main/java/com/baeldung/kafka/Tuple.java b/libraries/src/main/java/com/baeldung/kafka/Tuple.java new file mode 100644 index 0000000000..883de4ba21 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/kafka/Tuple.java @@ -0,0 +1,24 @@ +package com.baeldung.kafka; + +public class Tuple { + + private String key; + private Integer value; + + private Tuple(String key, Integer value) { + this.key = key; + this.value = value; + } + + public static Tuple of(String key, Integer value){ + return new Tuple(key,value); + } + + public String getKey() { + return key; + } + + public Integer getValue() { + return value; + } +} diff --git a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java b/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java index 76d044ca60..086f32677e 100644 --- a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java +++ b/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java @@ -18,16 +18,19 @@ import java.util.List; public class BeanExamples { public static List beanBuilderExample(Path path, Class clazz) { + ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy(); + return beanBuilderExample(path, clazz, ms); + } + + public static List beanBuilderExample(Path path, Class clazz, MappingStrategy ms) { CsvTransfer csvTransfer = new CsvTransfer(); try { - ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy(); ms.setType(clazz); Reader reader = Files.newBufferedReader(path); - CsvToBean cb = new CsvToBeanBuilder(reader) - .withType(clazz) - .withMappingStrategy(ms) - .build(); + CsvToBean cb = new CsvToBeanBuilder(reader).withType(clazz) + .withMappingStrategy(ms) + .build(); csvTransfer.setCsvList(cb.parse()); reader.close(); @@ -40,11 +43,10 @@ public class BeanExamples { public static String writeCsvFromBean(Path path) { try { - Writer writer = new FileWriter(path.toString()); + Writer writer = new FileWriter(path.toString()); - StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer) - .withSeparator(CSVWriter.DEFAULT_SEPARATOR) - .build(); + StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer).withSeparator(CSVWriter.DEFAULT_SEPARATOR) + .build(); List list = new ArrayList<>(); list.add(new WriteExampleBean("Test1", "sfdsf", "fdfd")); diff --git a/libraries/src/main/java/com/baeldung/snakeyaml/Address.java b/libraries/src/main/java/com/baeldung/snakeyaml/Address.java new file mode 100644 index 0000000000..83c327a4ed --- /dev/null +++ b/libraries/src/main/java/com/baeldung/snakeyaml/Address.java @@ -0,0 +1,41 @@ +package com.baeldung.snakeyaml; + +public class Address { + private String line; + private String city; + private String state; + private Integer zip; + + public String getLine() { + return line; + } + + public void setLine(String line) { + this.line = line; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Integer getZip() { + return zip; + } + + public void setZip(Integer zip) { + this.zip = zip; + } + +} diff --git a/libraries/src/main/java/com/baeldung/snakeyaml/Contact.java b/libraries/src/main/java/com/baeldung/snakeyaml/Contact.java new file mode 100644 index 0000000000..a808747786 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/snakeyaml/Contact.java @@ -0,0 +1,26 @@ +package com.baeldung.snakeyaml; + +public class Contact { + + private String type; + + private int number; + + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + +} diff --git a/libraries/src/main/java/com/baeldung/snakeyaml/Customer.java b/libraries/src/main/java/com/baeldung/snakeyaml/Customer.java new file mode 100644 index 0000000000..c741f6dc85 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/snakeyaml/Customer.java @@ -0,0 +1,53 @@ +package com.baeldung.snakeyaml; + +import java.util.List; + +public class Customer { + + private String firstName; + private String lastName; + private int age; + private List contactDetails; + private Address homeAddress; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public List getContactDetails() { + return contactDetails; + } + + public void setContactDetails(List contactDetails) { + this.contactDetails = contactDetails; + } + + public Address getHomeAddress() { + return homeAddress; + } + + public void setHomeAddress(Address homeAddress) { + this.homeAddress = homeAddress; + } + +} diff --git a/libraries/src/main/resources/logback.xml b/libraries/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/libraries/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/atlassian/fugue/FugueTest.java b/libraries/src/test/java/com/baeldung/atlassian/fugue/FugueUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/atlassian/fugue/FugueTest.java rename to libraries/src/test/java/com/baeldung/atlassian/fugue/FugueUnitTest.java index 2ba1086226..773e39b76a 100644 --- a/libraries/src/test/java/com/baeldung/atlassian/fugue/FugueTest.java +++ b/libraries/src/test/java/com/baeldung/atlassian/fugue/FugueUnitTest.java @@ -10,7 +10,7 @@ import java.util.function.Function; import static org.junit.Assert.*; import static io.atlassian.fugue.Unit.Unit; -public class FugueTest { +public class FugueUnitTest { @Test public void whenSome_thenDefined() { diff --git a/libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueTest.java b/libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueTest.java rename to libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueUnitTest.java index 9f670af03c..39384a7442 100644 --- a/libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueTest.java +++ b/libraries/src/test/java/com/baeldung/circularfifoqueue/CircularFifoQueueUnitTest.java @@ -7,7 +7,7 @@ import org.apache.commons.collections4.queue.CircularFifoQueue; import org.junit.Assert; import org.junit.Test; -public class CircularFifoQueueTest { +public class CircularFifoQueueUnitTest { private static final int DEFAULT_SIZE = 32; diff --git a/libraries/src/test/java/com/baeldung/commons/chain/AtmChainTest.java b/libraries/src/test/java/com/baeldung/commons/chain/AtmChainUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/commons/chain/AtmChainTest.java rename to libraries/src/test/java/com/baeldung/commons/chain/AtmChainUnitTest.java index cd9a7baaf3..3d12662968 100644 --- a/libraries/src/test/java/com/baeldung/commons/chain/AtmChainTest.java +++ b/libraries/src/test/java/com/baeldung/commons/chain/AtmChainUnitTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import static com.baeldung.commons.chain.AtmConstants.*; -public class AtmChainTest { +public class AtmChainUnitTest { public static final int EXPECTED_TOTAL_AMOUNT_TO_BE_WITHDRAWN = 460; public static final int EXPECTED_AMOUNT_LEFT_TO_BE_WITHDRAWN = 0; diff --git a/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java b/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java index e46d8654a2..64e13a277e 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java +++ b/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java @@ -42,4 +42,13 @@ public class BidiMapUnitTest { map.put("key1", "value1"); assertEquals(map.getKey("value1"), "key1"); } + + @Test + public void givenKeyValue_whenAddValue_thenReplaceFirstKey() { + BidiMap map = new DualHashBidiMap<>(); + map.put("key1", "value1"); + map.put("key2", "value1"); + assertEquals(map.size(), 1); + assertFalse(map.containsKey("key1")); + } } diff --git a/libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideTest.java b/libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideTest.java rename to libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideUnitTest.java index f34f431d8e..448c5b0729 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideTest.java +++ b/libraries/src/test/java/com/baeldung/commons/collections/CollectionUtilsGuideUnitTest.java @@ -18,7 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -public class CollectionUtilsGuideTest { +public class CollectionUtilsGuideUnitTest { Customer customer1 = new Customer(1, "Daniel", 123456l, "locality1", "city1", "1234"); Customer customer4 = new Customer(4, "Bob", 456789l, "locality4", "city4", "4567"); diff --git a/libraries/src/test/java/com/baeldung/commons/collections/MapUtilsTest.java b/libraries/src/test/java/com/baeldung/commons/collections/MapUtilsUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/commons/collections/MapUtilsTest.java rename to libraries/src/test/java/com/baeldung/commons/collections/MapUtilsUnitTest.java index 988335b7d1..bad4d823a0 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections/MapUtilsTest.java +++ b/libraries/src/test/java/com/baeldung/commons/collections/MapUtilsUnitTest.java @@ -17,7 +17,7 @@ import static org.hamcrest.collection.IsMapWithSize.anEmptyMap; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; -public class MapUtilsTest { +public class MapUtilsUnitTest { private String[][] color2DArray = new String[][] { { "RED", "#FF0000" }, { "GREEN", "#00FF00" }, { "BLUE", "#0000FF" } }; private String[] color1DArray = new String[] { "RED", "#FF0000", "GREEN", "#00FF00", "BLUE", "#0000FF" }; diff --git a/libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java b/libraries/src/test/java/com/baeldung/commons/collections4/BagUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java rename to libraries/src/test/java/com/baeldung/commons/collections4/BagUnitTest.java index 4408dcc195..ebad4093f0 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java +++ b/libraries/src/test/java/com/baeldung/commons/collections4/BagUnitTest.java @@ -14,7 +14,7 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsEqual.equalTo; -public class BagTests { +public class BagUnitTest { @Test public void givenMultipleCopies_whenAdded_theCountIsKept() { diff --git a/libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterTest.java b/libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterTest.java rename to libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterUnitTest.java index 6210bb51a9..f93e59ed75 100644 --- a/libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterTest.java +++ b/libraries/src/test/java/com/baeldung/commons/csv/CSVReaderWriterUnitTest.java @@ -15,7 +15,7 @@ import java.util.Map; import static org.junit.Assert.assertEquals; -public class CSVReaderWriterTest { +public class CSVReaderWriterUnitTest { public static final Map AUTHOR_BOOK_MAP = Collections.unmodifiableMap(new LinkedHashMap() { { diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java rename to libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsUnitTest.java index 29bcebeb2b..a10f92639c 100644 --- a/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java +++ b/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsUnitTest.java @@ -32,7 +32,7 @@ import org.apache.commons.lang3.time.FastDateFormat; import org.junit.Assert; import org.junit.Test; -public class Lang3UtilsTest { +public class Lang3UtilsUnitTest { @Test public void test_to_Boolean_fromString() { diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java new file mode 100644 index 0000000000..5eba736b4a --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java @@ -0,0 +1,84 @@ +package com.baeldung.commons.lang3.test; + +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.lang3.ArrayUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class ArrayUtilsUnitTest { + + @Test + public void givenArrayUtilsClass_whenCalledtoString_thenCorrect() { + String[] array = {"a", "b", "c"}; + assertThat(ArrayUtils.toString(array)).isEqualTo("{a,b,c}"); + } + + @Test + public void givenArrayUtilsClass_whenCalledtoStringIfArrayisNull_thenCorrect() { + String[] array = null; + assertThat(ArrayUtils.toString(array, "Array is null")).isEqualTo("Array is null"); + } + + @Test + public void givenArrayUtilsClass_whenCalledhashCode_thenCorrect() { + String[] array = {"a", "b", "c"}; + assertThat(ArrayUtils.hashCode(array)).isEqualTo(997619); + } + + @Test + public void givenArrayUtilsClass_whenCalledtoMap_thenCorrect() { + String[][] array = {{"1", "one", }, {"2", "two", }, {"3", "three"}}; + Map map = new HashMap(); + map.put("1", "one"); + map.put("2", "two"); + map.put("3", "three"); + assertThat(ArrayUtils.toMap(array)).isEqualTo(map); + } + + @Test + public void givenArrayUtilsClass_whenCallednullToEmptyStringArray_thenCorrect() { + String[] array = null; + assertThat(ArrayUtils.nullToEmpty(array)).isEmpty(); + } + + @Test + public void givenArrayUtilsClass_whenCallednullToEmptyObjectArray_thenCorrect() { + Object[] array = null; + assertThat(ArrayUtils.nullToEmpty(array)).isEmpty(); + } + + @Test + public void givenArrayUtilsClass_whenCalledsubarray_thenCorrect() { + int[] array = {1, 2, 3}; + int[] expected = {1}; + assertThat(ArrayUtils.subarray(array, 0, 1)).isEqualTo(expected); + } + + @Test + public void givenArrayUtilsClass_whenCalledisSameLength_thenCorrect() { + int[] array1 = {1, 2, 3}; + int[] array2 = {1, 2, 3}; + assertThat(ArrayUtils.isSameLength(array1, array2)).isTrue(); + } + + @Test + public void givenArrayUtilsClass_whenCalledreverse_thenCorrect() { + int[] array1 = {1, 2, 3}; + int[] array2 = {3, 2, 1}; + ArrayUtils.reverse(array1); + assertThat(array1).isEqualTo(array2); + } + + @Test + public void givenArrayUtilsClass_whenCalledIndexOf_thenCorrect() { + int[] array = {1, 2, 3}; + assertThat(ArrayUtils.indexOf(array, 1, 0)).isEqualTo(0); + } + + @Test + public void givenArrayUtilsClass_whenCalledcontains_thenCorrect() { + int[] array = {1, 2, 3}; + assertThat(ArrayUtils.contains(array, 1)).isTrue(); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java new file mode 100644 index 0000000000..f32980269a --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class BasicThreadFactoryUnitTest { + + @Test + public void givenBasicThreadFactoryInstance_whenCalledBuilder_thenCorrect() { + BasicThreadFactory factory = new BasicThreadFactory.Builder() + .namingPattern("workerthread-%d") + .daemon(true) + .priority(Thread.MAX_PRIORITY) + .build(); + assertThat(factory).isInstanceOf(BasicThreadFactory.class); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java new file mode 100644 index 0000000000..f55f239d75 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.commons.lang3.test; + +import com.baeldung.commons.lang3.beans.User; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import org.apache.commons.lang3.reflect.ConstructorUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class ConstructorUtilsUnitTest { + + @Test + public void givenConstructorUtilsClass_whenCalledgetAccessibleConstructor_thenCorrect() { + assertThat(ConstructorUtils.getAccessibleConstructor(User.class, String.class, String.class)).isInstanceOf(Constructor.class); + } + + @Test + public void givenConstructorUtilsClass_whenCalledinvokeConstructor_thenCorrect() throws Exception { + assertThat(ConstructorUtils.invokeConstructor(User.class, "name", "email")).isInstanceOf(User.class); + } + + @Test + public void givenConstructorUtilsClass_whenCalledinvokeExactConstructor_thenCorrect() throws Exception { + String[] args = {"name", "email"}; + Class[] parameterTypes= {String.class, String.class}; + assertThat(ConstructorUtils.invokeExactConstructor(User.class, args, parameterTypes)).isInstanceOf(User.class); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java new file mode 100644 index 0000000000..8abb373e30 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.commons.lang3.test; + +import com.baeldung.commons.lang3.beans.User; +import org.apache.commons.lang3.reflect.FieldUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class FieldUtilsUnitTest { + + private static User user; + + @BeforeClass + public static void setUpUserInstance() { + user = new User("Julie", "julie@domain.com"); + } + + @Test + public void givenFieldUtilsClass_whenCalledgetField_thenCorrect() { + assertThat(FieldUtils.getField(User.class, "name", true).getName()).isEqualTo("name"); + } + + @Test + public void givenFieldUtilsClass_whenCalledgetFieldForceAccess_thenCorrect() { + assertThat(FieldUtils.getField(User.class, "name", true).getName()).isEqualTo("name"); + } + + @Test + public void givenFieldUtilsClass_whenCalledgetDeclaredFieldForceAccess_thenCorrect() { + assertThat(FieldUtils.getDeclaredField(User.class, "name", true).getName()).isEqualTo("name"); + } + + @Test + public void givenFieldUtilsClass_whenCalledgetAllField_thenCorrect() { + assertThat(FieldUtils.getAllFields(User.class).length).isEqualTo(2); + } + + @Test + public void givenFieldUtilsClass_whenCalledreadField_thenCorrect() throws IllegalAccessException { + assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie"); + } + + @Test + public void givenFieldUtilsClass_whenCalledreadDeclaredField_thenCorrect() throws IllegalAccessException { + assertThat(FieldUtils.readDeclaredField(user, "name", true)).isEqualTo("Julie"); + } + + @Test + public void givenFieldUtilsClass_whenCalledwriteField_thenCorrect() throws IllegalAccessException { + FieldUtils.writeField(user, "name", "Julie", true); + assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie"); + + } + + @Test + public void givenFieldUtilsClass_whenCalledwriteDeclaredField_thenCorrect() throws IllegalAccessException { + FieldUtils.writeDeclaredField(user, "name", "Julie", true); + assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java new file mode 100644 index 0000000000..1a5094a16d --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.math.Fraction; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class FractionUnitTest { + + @Test + public void givenFractionClass_whenCalledgetFraction_thenCorrect() { + assertThat(Fraction.getFraction(5, 6)).isInstanceOf(Fraction.class); + } + + @Test + public void givenTwoFractionInstances_whenCalledadd_thenCorrect() { + Fraction fraction1 = Fraction.getFraction(1, 4); + Fraction fraction2 = Fraction.getFraction(3, 4); + assertThat(fraction1.add(fraction2).toString()).isEqualTo("1/1"); + } + + @Test + public void givenTwoFractionInstances_whenCalledsubstract_thenCorrect() { + Fraction fraction1 = Fraction.getFraction(3, 4); + Fraction fraction2 = Fraction.getFraction(1, 4); + assertThat(fraction1.subtract(fraction2).toString()).isEqualTo("1/2"); + } + + @Test + public void givenTwoFractionInstances_whenCalledmultiply_thenCorrect() { + Fraction fraction1 = Fraction.getFraction(3, 4); + Fraction fraction2 = Fraction.getFraction(1, 4); + assertThat(fraction1.multiplyBy(fraction2).toString()).isEqualTo("3/16"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java new file mode 100644 index 0000000000..bbd24c8207 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.builder.HashCodeBuilder; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class HashCodeBuilderUnitTest { + + @Test + public void givenHashCodeBuilderInstance_whenCalledtoHashCode_thenCorrect() { + int hashcode = new HashCodeBuilder(17, 37) + .append("John") + .append("john@domain.com") + .toHashCode(); + assertThat(hashcode).isEqualTo(1269178828); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java new file mode 100644 index 0000000000..28ed8d2514 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ImmutablePairUnitTest { + + private static ImmutablePair immutablePair; + + @BeforeClass + public static void setUpImmutablePairInstance() { + immutablePair = new ImmutablePair<>("leftElement", "rightElement"); + } + + @Test + public void givenImmutablePairInstance_whenCalledgetLeft_thenCorrect() { + assertThat(immutablePair.getLeft()).isEqualTo("leftElement"); + } + + @Test + public void givenImmutablePairInstance_whenCalledgetRight_thenCorrect() { + assertThat(immutablePair.getRight()).isEqualTo("rightElement"); + } + + @Test + public void givenImmutablePairInstance_whenCalledof_thenCorrect() { + assertThat(ImmutablePair.of("leftElement", "rightElement")).isInstanceOf(ImmutablePair.class); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenImmutablePairInstance_whenCalledSetValue_thenThrowUnsupportedOperationException() { + immutablePair.setValue("newValue"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java new file mode 100644 index 0000000000..a9dd3fa7c0 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.tuple.ImmutableTriple; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ImmutableTripleUnitTest { + + private static ImmutableTriple immutableTriple; + + @BeforeClass + public static void setUpImmutableTripleInstance() { + immutableTriple = new ImmutableTriple<>("leftElement", "middleElement", "rightElement"); + } + + @Test + public void givenImmutableTripleInstance_whenCalledgetLeft_thenCorrect() { + assertThat(immutableTriple.getLeft()).isEqualTo("leftElement"); + } + + @Test + public void givenImmutableTripleInstance_whenCalledgetMiddle_thenCorrect() { + assertThat(immutableTriple.getMiddle()).isEqualTo("middleElement"); + } + + @Test + public void givenImmutableInstance_whenCalledgetRight_thenCorrect() { + assertThat(immutableTriple.getRight()).isEqualTo("rightElement"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java new file mode 100644 index 0000000000..a08399f8de --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java @@ -0,0 +1,16 @@ +package com.baeldung.commons.lang3.test; + +import com.baeldung.commons.lang3.beans.User; +import com.baeldung.commons.lang3.beans.UserInitializer; +import org.apache.commons.lang3.concurrent.ConcurrentException; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class LazyInitializerUnitTest { + + @Test + public void givenLazyInitializerInstance_whenCalledget_thenCorrect() throws ConcurrentException { + UserInitializer userInitializer = new UserInitializer(); + assertThat(userInitializer.get()).isInstanceOf(User.class); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java new file mode 100644 index 0000000000..5e1d15f2f8 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.commons.lang3.test; + +import com.baeldung.commons.lang3.beans.User; +import java.lang.reflect.Method; +import org.apache.commons.lang3.reflect.MethodUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class MethodUtilsUnitTest { + + @Test + public void givenMethodUtilsClass_whenCalledgetAccessibleMethod_thenCorrect() { + assertThat(MethodUtils.getAccessibleMethod(User.class, "getName")).isInstanceOf(Method.class); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java new file mode 100644 index 0000000000..02041f51e8 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.mutable.MutableObject; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class MutableObjectUnitTest { + + private static MutableObject mutableObject; + + @BeforeClass + public static void setUpMutableObject() { + mutableObject = new MutableObject("Initial value"); + } + + @Test + public void givenMutableObject_whenCalledgetValue_thenCorrect() { + assertThat(mutableObject.getValue()).isInstanceOf(String.class); + } + + @Test + public void givenMutableObject_whenCalledsetValue_thenCorrect() { + mutableObject.setValue("Another value"); + assertThat(mutableObject.getValue()).isEqualTo("Another value"); + } + + @Test + public void givenMutableObject_whenCalledtoString_thenCorrect() { + assertThat(mutableObject.toString()).isEqualTo("Another value"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java new file mode 100644 index 0000000000..174ec70c4d --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.tuple.MutablePair; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class MutablePairUnitTest { + + private static MutablePair mutablePair; + + @BeforeClass + public static void setUpMutablePairInstance() { + mutablePair = new MutablePair<>("leftElement", "rightElement"); + } + + @Test + public void givenMutablePairInstance_whenCalledgetLeft_thenCorrect() { + assertThat(mutablePair.getLeft()).isEqualTo("leftElement"); + } + + @Test + public void givenMutablePairInstance_whenCalledgetRight_thenCorrect() { + assertThat(mutablePair.getRight()).isEqualTo("rightElement"); + } + + @Test + public void givenMutablePairInstance_whenCalledsetLeft_thenCorrect() { + mutablePair.setLeft("newLeftElement"); + assertThat(mutablePair.getLeft()).isEqualTo("newLeftElement"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java new file mode 100644 index 0000000000..bdf254a102 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.math.NumberUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class NumberUtilsUnitTest { + + @Test + public void givenNumberUtilsClass_whenCalledcompareWithIntegers_thenCorrect() { + assertThat(NumberUtils.compare(1, 1)).isEqualTo(0); + } + + @Test + public void givenNumberUtilsClass_whenCalledcompareWithLongs_thenCorrect() { + assertThat(NumberUtils.compare(1L, 1L)).isEqualTo(0); + } + + @Test + public void givenNumberUtilsClass_whenCalledcreateNumber_thenCorrect() { + assertThat(NumberUtils.createNumber("123456")).isEqualTo(123456); + } + + @Test + public void givenNumberUtilsClass_whenCalledisDigits_thenCorrect() { + assertThat(NumberUtils.isDigits("123456")).isTrue(); + } + + @Test + public void givenNumberUtilsClass_whenCallemaxwithIntegerArray_thenCorrect() { + int[] array = {1, 2, 3, 4, 5, 6}; + assertThat(NumberUtils.max(array)).isEqualTo(6); + } + + @Test + public void givenNumberUtilsClass_whenCalleminwithIntegerArray_thenCorrect() { + int[] array = {1, 2, 3, 4, 5, 6}; + assertThat(NumberUtils.min(array)).isEqualTo(1); + } + + @Test + public void givenNumberUtilsClass_whenCalleminwithByteArray_thenCorrect() { + byte[] array = {1, 2, 3, 4, 5, 6}; + assertThat(NumberUtils.min(array)).isEqualTo((byte) 1); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java new file mode 100644 index 0000000000..ab39ba7bd9 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java @@ -0,0 +1,73 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.StringUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class StringUtilsUnitTest { + + @Test + public void givenStringUtilsClass_whenCalledisBlank_thenCorrect() { + assertThat(StringUtils.isBlank(" ")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisEmpty_thenCorrect() { + assertThat(StringUtils.isEmpty("")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisAllLowerCase_thenCorrect() { + assertThat(StringUtils.isAllLowerCase("abd")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisAllUpperCase_thenCorrect() { + assertThat(StringUtils.isAllUpperCase("ABC")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisMixedCase_thenCorrect() { + assertThat(StringUtils.isMixedCase("abC")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisAlpha_thenCorrect() { + assertThat(StringUtils.isAlpha("abc")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisAlphanumeric_thenCorrect() { + assertThat(StringUtils.isAlphanumeric("abc123")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledcontains_thenCorrect() { + assertThat(StringUtils.contains("abc", "ab")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledcontainsAny_thenCorrect() { + assertThat(StringUtils.containsAny("abc", 'a', 'b', 'c')).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledcontainsIgnoreCase_thenCorrect() { + assertThat(StringUtils.containsIgnoreCase("abc", "ABC")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledswapCase_thenCorrect() { + assertThat(StringUtils.swapCase("abc")).isEqualTo("ABC"); + } + + @Test + public void givenStringUtilsClass_whenCalledreverse_thenCorrect() { + assertThat(StringUtils.reverse("abc")).isEqualTo("cba"); + } + + @Test + public void givenStringUtilsClass_whenCalleddifference_thenCorrect() { + assertThat(StringUtils.difference("abc", "abd")).isEqualTo("d"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsManualTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsManualTest.java new file mode 100644 index 0000000000..cb45ebc24d --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsManualTest.java @@ -0,0 +1,27 @@ +package com.baeldung.commons.lang3.test; + +import java.io.File; +import org.apache.commons.lang3.JavaVersion; +import org.apache.commons.lang3.SystemUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class SystemsUtilsManualTest { + + // the paths depend on the OS and installed version of Java + + @Test + public void givenSystemUtilsClass_whenCalledgetJavaHome_thenCorrect() { + assertThat(SystemUtils.getJavaHome()).isEqualTo(new File("/usr/lib/jvm/java-8-oracle/jre")); + } + + @Test + public void givenSystemUtilsClass_whenCalledgetUserHome_thenCorrect() { + assertThat(SystemUtils.getUserHome()).isEqualTo(new File("/home/travis")); + } + + @Test + public void givenSystemUtilsClass_whenCalledisJavaVersionAtLeast_thenCorrect() { + assertThat(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_RECENT)).isTrue(); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java new file mode 100644 index 0000000000..7d506bbbab --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.tuple.Triple; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class TripleUnitTest { + + private static Triple triple; + + @BeforeClass + public static void setUpTripleInstance() { + triple = Triple.of("leftElement", "middleElement", "rightElement"); + } + + @Test + public void givenTripleInstance_whenCalledgetLeft_thenCorrect() { + assertThat(triple.getLeft()).isEqualTo("leftElement"); + } + + @Test + public void givenTripleInstance_whenCalledgetMiddle_thenCorrect() { + assertThat(triple.getMiddle()).isEqualTo("middleElement"); + } + + @Test + public void givenTripleInstance_whenCalledgetRight_thenCorrect() { + assertThat(triple.getRight()).isEqualTo("rightElement"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/math/IntegrationTest.java b/libraries/src/test/java/com/baeldung/commons/math/SimpsonIntegratorUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/commons/math/IntegrationTest.java rename to libraries/src/test/java/com/baeldung/commons/math/SimpsonIntegratorUnitTest.java index 7e047577e5..bb4dc53eec 100644 --- a/libraries/src/test/java/com/baeldung/commons/math/IntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/commons/math/SimpsonIntegratorUnitTest.java @@ -6,7 +6,7 @@ import org.apache.commons.math3.analysis.integration.UnivariateIntegrator; import org.junit.Assert; import org.junit.Test; -public class IntegrationTest { +public class SimpsonIntegratorUnitTest { @Test public void whenUnivariateIntegratorIntegrate_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java b/libraries/src/test/java/com/baeldung/crdt/CRDTUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/crdt/CRDTTest.java rename to libraries/src/test/java/com/baeldung/crdt/CRDTUnitTest.java index 3d3c952863..840263e430 100644 --- a/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java +++ b/libraries/src/test/java/com/baeldung/crdt/CRDTUnitTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -public class CRDTTest { +public class CRDTUnitTest { @Test public void givenGrowOnlySet_whenTwoReplicasDiverge_thenShouldMergeItWithoutAConflict() { diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternUnitTest.java similarity index 93% rename from libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternUnitTest.java index ee369fc75b..b9790e37ea 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/AllSatisfyPatternUnitTest.java @@ -8,7 +8,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class AllSatisfyPatternTest { +public class AllSatisfyPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternUnitTest.java similarity index 93% rename from libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternUnitTest.java index a3314ebee6..d5a736503e 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/AnySatisfyPatternUnitTest.java @@ -8,7 +8,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class AnySatisfyPatternTest { +public class AnySatisfyPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternUnitTest.java index b1aaceb09b..ff111a6d72 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/CollectPatternUnitTest.java @@ -6,7 +6,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.assertj.core.api.Assertions; import org.junit.Test; -public class CollectPatternTest { +public class CollectPatternUnitTest { @Test public void whenCollect_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherUnitTest.java similarity index 92% rename from libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherUnitTest.java index e279314034..cb2bc11dc0 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/ConvertContainerToAnotherUnitTest.java @@ -5,7 +5,7 @@ import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Test; -public class ConvertContainerToAnotherTest { +public class ConvertContainerToAnotherUnitTest { @SuppressWarnings({ "unchecked", "rawtypes" }) @Test diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternUnitTest.java index 4ef7348a0d..1479b06593 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/DetectPatternUnitTest.java @@ -7,7 +7,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class DetectPatternTest { +public class DetectPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectUnitTest.java index 3091f90908..b0735267ae 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/FlatCollectUnitTest.java @@ -10,7 +10,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; -public class FlatCollectTest { +public class FlatCollectUnitTest { MutableList addresses1; MutableList addresses2; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternUnitTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternUnitTest.java index 8cea575222..38d95047ed 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/ForEachPatternUnitTest.java @@ -7,7 +7,7 @@ import org.eclipse.collections.impl.map.mutable.UnifiedMap; import org.eclipse.collections.impl.tuple.Tuples; import org.junit.Test; -public class ForEachPatternTest { +public class ForEachPatternUnitTest { @SuppressWarnings("unchecked") @Test diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternUnitTest.java similarity index 92% rename from libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternUnitTest.java index 01a8fcaef4..10448c4474 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/InjectIntoPatternUnitTest.java @@ -7,7 +7,7 @@ import java.util.List; import org.eclipse.collections.impl.factory.Lists; import org.junit.Test; -public class InjectIntoPatternTest { +public class InjectIntoPatternUnitTest { @Test public void whenInjectInto_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationUnitTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationUnitTest.java index bcb816c34a..0c3418b7b2 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/LazyIterationUnitTest.java @@ -6,7 +6,7 @@ import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.impl.factory.Lists; import org.junit.Test; -public class LazyIterationTest { +public class LazyIterationUnitTest { @Test public void whenLazyIteration_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternUnitTest.java index 8ef18004aa..e5c27179a9 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/PartitionPatternUnitTest.java @@ -8,7 +8,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class PartitionPatternTest { +public class PartitionPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternUnitTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternUnitTest.java index bd743d56e8..b455938b0b 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/RejectPatternUnitTest.java @@ -7,7 +7,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class RejectPatternTest { +public class RejectPatternUnitTest { MutableList list; MutableList expectedList; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternUnitTest.java index 154be08f08..7735daff65 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/SelectPatternUnitTest.java @@ -7,7 +7,7 @@ import org.eclipse.collections.impl.list.mutable.FastList; import org.junit.Before; import org.junit.Test; -public class SelectPatternTest { +public class SelectPatternUnitTest { MutableList list; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/ZipTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/ZipUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/eclipsecollections/ZipTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/ZipUnitTest.java index 2b5aa06289..942cdf4595 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/ZipTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/ZipUnitTest.java @@ -9,7 +9,7 @@ import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; -public class ZipTest { +public class ZipUnitTest { MutableList> expectedPairs; diff --git a/libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexTest.java b/libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexTest.java rename to libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexUnitTest.java index 724f693011..b297d1d1eb 100644 --- a/libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexTest.java +++ b/libraries/src/test/java/com/baeldung/eclipsecollections/ZipWithIndexUnitTest.java @@ -9,7 +9,7 @@ import org.eclipse.collections.impl.tuple.Tuples; import org.junit.Before; import org.junit.Test; -public class ZipWithIndexTest { +public class ZipWithIndexUnitTest { MutableList> expectedPairs; diff --git a/libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java b/libraries/src/test/java/com/baeldung/fj/FunctionalJavaUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java rename to libraries/src/test/java/com/baeldung/fj/FunctionalJavaUnitTest.java index 33952c8669..d62a115abd 100644 --- a/libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java +++ b/libraries/src/test/java/com/baeldung/fj/FunctionalJavaUnitTest.java @@ -11,7 +11,7 @@ import fj.data.Option; import fj.function.Characters; import fj.function.Integers; -public class FunctionalJavaTest { +public class FunctionalJavaUnitTest { public static final F isEven = i -> i % 2 == 0; diff --git a/libraries/src/test/java/com/baeldung/hoverfly/HoverflyApiIntegrationTest.java b/libraries/src/test/java/com/baeldung/hoverfly/HoverflyApiLiveTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/hoverfly/HoverflyApiIntegrationTest.java rename to libraries/src/test/java/com/baeldung/hoverfly/HoverflyApiLiveTest.java index 09d31eac21..8d60b40bb0 100644 --- a/libraries/src/test/java/com/baeldung/hoverfly/HoverflyApiIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/hoverfly/HoverflyApiLiveTest.java @@ -31,7 +31,7 @@ import org.springframework.web.client.RestTemplate; import io.specto.hoverfly.junit.core.SimulationSource; import io.specto.hoverfly.junit.rule.HoverflyRule; -public class HoverflyApiIntegrationTest { +public class HoverflyApiLiveTest { private static final SimulationSource source = dsl(service("http://www.baeldung.com").get("/api/courses/1").willReturn(success().body(jsonWithSingleQuotes("{'id':'1','name':'HCI'}"))) diff --git a/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java b/libraries/src/test/java/com/baeldung/infinispan/AbstractIntegrationTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java rename to libraries/src/test/java/com/baeldung/infinispan/AbstractIntegrationTest.java index 9210b18f0c..2a9d430430 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/ConfigurationTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/AbstractIntegrationTest.java @@ -8,10 +8,12 @@ import org.infinispan.Cache; import org.infinispan.manager.DefaultCacheManager; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import java.util.function.Supplier; -public class ConfigurationTest { +@Ignore +public abstract class AbstractIntegrationTest { private DefaultCacheManager cacheManager; diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceIntegrationTest.java b/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceTemporaryLiveTest.java similarity index 93% rename from libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceIntegrationTest.java rename to libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceTemporaryLiveTest.java index 0a2ace9ca0..46cc77cbba 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/service/HelloWorldServiceTemporaryLiveTest.java @@ -1,11 +1,11 @@ package com.baeldung.infinispan.service; -import com.baeldung.infinispan.ConfigurationTest; +import com.baeldung.infinispan.AbstractIntegrationTest; import org.junit.Test; import static org.assertj.core.api.Java6Assertions.assertThat; -public class HelloWorldServiceIntegrationTest extends ConfigurationTest { +public class HelloWorldServiceTemporaryLiveTest extends AbstractIntegrationTest { @Test public void whenGetIsCalledTwoTimes_thenTheSecondShouldHitTheCache() { diff --git a/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java b/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java index ace99eef36..800c6c2775 100644 --- a/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/infinispan/service/TransactionalServiceIntegrationTest.java @@ -1,11 +1,11 @@ package com.baeldung.infinispan.service; -import com.baeldung.infinispan.ConfigurationTest; +import com.baeldung.infinispan.AbstractIntegrationTest; import org.junit.Test; import static org.assertj.core.api.Java6Assertions.assertThat; -public class TransactionalServiceIntegrationTest extends ConfigurationTest { +public class TransactionalServiceIntegrationTest extends AbstractIntegrationTest { @Test public void whenLockingAnEntry_thenItShouldBeInaccessible() throws InterruptedException { diff --git a/libraries/src/test/java/com/baeldung/jdeffered/AppTest.java b/libraries/src/test/java/com/baeldung/jdeffered/JDeferredUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/jdeffered/AppTest.java rename to libraries/src/test/java/com/baeldung/jdeffered/JDeferredUnitTest.java index 97b20cda57..80cd16bd53 100644 --- a/libraries/src/test/java/com/baeldung/jdeffered/AppTest.java +++ b/libraries/src/test/java/com/baeldung/jdeffered/JDeferredUnitTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; -public class AppTest { +public class JDeferredUnitTest { @Test public void givenJob_expectPromise() { diff --git a/libraries/src/test/java/com/baeldung/jool/JOOLTest.java b/libraries/src/test/java/com/baeldung/jool/JOOLUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/jool/JOOLTest.java rename to libraries/src/test/java/com/baeldung/jool/JOOLUnitTest.java index 2cb393abd3..153014e324 100644 --- a/libraries/src/test/java/com/baeldung/jool/JOOLTest.java +++ b/libraries/src/test/java/com/baeldung/jool/JOOLUnitTest.java @@ -21,7 +21,7 @@ import static junit.framework.Assert.assertTrue; import static junit.framework.TestCase.assertEquals; import static org.jooq.lambda.tuple.Tuple.tuple; -public class JOOLTest { +public class JOOLUnitTest { @Test public void givenSeq_whenCheckContains_shouldReturnTrue() { List concat = Seq.of(1, 2, 3).concat(Seq.of(4, 5, 6)).toList(); diff --git a/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java b/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java rename to libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilUnitTest.java index c8718aef8d..f9213d9ab5 100644 --- a/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java +++ b/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilUnitTest.java @@ -9,7 +9,7 @@ import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals; @RunWith(JUnitParamsRunner.class) -public class SafeAdditionUtilTest { +public class SafeAdditionUtilUnitTest { private SafeAdditionUtil serviceUnderTest = new SafeAdditionUtil(); diff --git a/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java b/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java index 4406494d30..e61f4158a7 100644 --- a/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java +++ b/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java @@ -4,10 +4,12 @@ import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.common.serialization.Serde; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.KafkaStreams; +import org.apache.kafka.streams.StreamsBuilder; import org.apache.kafka.streams.StreamsConfig; +import org.apache.kafka.streams.Topology; import org.apache.kafka.streams.kstream.KStream; -import org.apache.kafka.streams.kstream.KStreamBuilder; import org.apache.kafka.streams.kstream.KTable; +import org.apache.kafka.streams.kstream.Produced; import org.apache.kafka.test.TestUtils; import org.junit.Ignore; import org.junit.Test; @@ -36,20 +38,20 @@ public class KafkaStreamsLiveTest { streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getAbsolutePath()); // when - KStreamBuilder builder = new KStreamBuilder(); + StreamsBuilder builder = new StreamsBuilder(); KStream textLines = builder.stream(inputTopic); Pattern pattern = Pattern.compile("\\W+", Pattern.UNICODE_CHARACTER_CLASS); KTable wordCounts = textLines.flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase()))).groupBy((key, word) -> word).count(); - wordCounts.foreach((word, count) -> System.out.println("word: " + word + " -> " + count)); + textLines.foreach((word, count) -> System.out.println("word: " + word + " -> " + count)); String outputTopic = "outputTopic"; final Serde stringSerde = Serdes.String(); - final Serde longSerde = Serdes.Long(); - wordCounts.to(stringSerde, longSerde, outputTopic); + final Serde longSerde = Serdes.String(); + textLines.to(outputTopic, Produced.with(stringSerde,longSerde)); - KafkaStreams streams = new KafkaStreams(builder, streamsConfiguration); + KafkaStreams streams = new KafkaStreams(new Topology(), streamsConfiguration); streams.start(); // then diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchUnitTest.java similarity index 95% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchUnitTest.java index 0cab612a7b..903da00995 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchUnitTest.java @@ -11,7 +11,7 @@ import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertNotNull; -public class MBassadorAsyncDispatchTest { +public class MBassadorAsyncDispatchUnitTest { private MBassador dispatcher = new MBassador(); private String testString; diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationUnitTest.java index 99ea1aab71..bf20645e2d 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationUnitTest.java @@ -13,7 +13,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertFalse; -public class MBassadorAsyncInvocationTest { +public class MBassadorAsyncInvocationUnitTest { private MBassador dispatcher = new MBassador(); diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicUnitTest.java index 04f6272412..bd05d2888e 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorBasicUnitTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -public class MBassadorBasicTest { +public class MBassadorBasicUnitTest { private MBassador dispatcher = new MBassador(); diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationUnitTest.java index 9d9a58aee9..68cfff0014 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationUnitTest.java @@ -12,7 +12,7 @@ import java.util.*; import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.*; -public class MBassadorConfigurationTest implements IPublicationErrorHandler { +public class MBassadorConfigurationUnitTest implements IPublicationErrorHandler { private MBassador dispatcher; private String messageString; diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterUnitTest.java index e90ae15d3d..0094140fee 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorFilterUnitTest.java @@ -14,7 +14,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -public class MBassadorFilterTest { +public class MBassadorFilterUnitTest { private MBassador dispatcher = new MBassador(); diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java rename to libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyUnitTest.java index be5c9d4897..6f1ca83f0a 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyUnitTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import static org.junit.Assert.*; -public class MBassadorHierarchyTest { +public class MBassadorHierarchyUnitTest { private MBassador dispatcher = new MBassador(); diff --git a/libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java b/libraries/src/test/java/com/baeldung/measurement/WaterTankUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java rename to libraries/src/test/java/com/baeldung/measurement/WaterTankUnitTest.java index b023ffe8d9..e23eea1714 100644 --- a/libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java +++ b/libraries/src/test/java/com/baeldung/measurement/WaterTankUnitTest.java @@ -20,7 +20,7 @@ import tec.units.ri.quantity.Quantities; import tec.units.ri.unit.MetricPrefix; import static tec.units.ri.unit.Units.*; -public class WaterTankTests { +public class WaterTankUnitTest { @Test public void givenQuantity_whenGetUnitAndConvertValue_thenSuccess() { diff --git a/libraries/src/test/java/com/baeldung/opencsv/OpenCsvTest.java b/libraries/src/test/java/com/baeldung/opencsv/OpenCsvIntegrationTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/opencsv/OpenCsvTest.java rename to libraries/src/test/java/com/baeldung/opencsv/OpenCsvIntegrationTest.java index 394b3fba4f..fca96684ad 100644 --- a/libraries/src/test/java/com/baeldung/opencsv/OpenCsvTest.java +++ b/libraries/src/test/java/com/baeldung/opencsv/OpenCsvIntegrationTest.java @@ -5,7 +5,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -public class OpenCsvTest { +public class OpenCsvIntegrationTest { private Object testReadCsv(Object result) { assert (result != null); diff --git a/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java b/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java rename to libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsUnitTest.java index e9d5b8ede5..871a8a1935 100644 --- a/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java +++ b/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsUnitTest.java @@ -13,7 +13,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -public class CollectorUtilsTests { +public class CollectorUtilsUnitTest { @Test public void givenIntegerStream_whenCollectOnMaxByProjection_shouldReturnOptionalMaxValue() { diff --git a/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java b/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsUnitTest.java similarity index 98% rename from libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java rename to libraries/src/test/java/com/baeldung/protonpack/StreamUtilsUnitTest.java index ccd43b7777..889641502e 100644 --- a/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java +++ b/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsUnitTest.java @@ -18,7 +18,7 @@ import static java.util.stream.Collectors.toList; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -public class StreamUtilsTests { +public class StreamUtilsUnitTest { @Test public void givenStream_whenZipWithIndex_shouldReturnZippedStreamWithIndex() { @@ -174,7 +174,7 @@ public class StreamUtilsTests { public void givenLimit_withIndices_shouldReturnLongStreamUptoLimit() { LongStream indices = StreamUtils.indices().limit(500); - assertThat(indices.count(), equalTo(500)); + assertThat(indices.count(), equalTo(500L)); } } diff --git a/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java b/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java new file mode 100644 index 0000000000..ced95c99cb --- /dev/null +++ b/libraries/src/test/java/com/baeldung/resilience4j/Resilience4jUnitTest.java @@ -0,0 +1,126 @@ +package com.baeldung.resilience4j; + +import io.github.resilience4j.bulkhead.Bulkhead; +import io.github.resilience4j.bulkhead.BulkheadConfig; +import io.github.resilience4j.bulkhead.BulkheadRegistry; +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.retry.Retry; +import io.github.resilience4j.retry.RetryConfig; +import io.github.resilience4j.retry.RetryRegistry; +import io.github.resilience4j.timelimiter.TimeLimiter; +import io.github.resilience4j.timelimiter.TimeLimiterConfig; +import org.junit.Before; +import org.junit.Test; + +import java.time.Duration; +import java.util.concurrent.*; +import java.util.function.Function; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class Resilience4jUnitTest { + + interface RemoteService { + + int process(int i); + } + + private RemoteService service; + + @Before + public void setUp() { + service = mock(RemoteService.class); + } + + @Test + public void whenCircuitBreakerIsUsed_thenItWorksAsExpected() { + CircuitBreakerConfig config = CircuitBreakerConfig.custom() + // Percentage of failures to start short-circuit + .failureRateThreshold(20) + // Min number of call attempts + .ringBufferSizeInClosedState(5) + .build(); + CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config); + CircuitBreaker circuitBreaker = registry.circuitBreaker("my"); + Function decorated = CircuitBreaker.decorateFunction(circuitBreaker, service::process); + + when(service.process(anyInt())).thenThrow(new RuntimeException()); + + for (int i = 0; i < 10; i++) { + try { + decorated.apply(i); + } catch (Exception ignore) { + } + } + + verify(service, times(5)).process(any(Integer.class)); + } + + @Test + public void whenBulkheadIsUsed_thenItWorksAsExpected() throws InterruptedException { + BulkheadConfig config = BulkheadConfig.custom().maxConcurrentCalls(1).build(); + BulkheadRegistry registry = BulkheadRegistry.of(config); + Bulkhead bulkhead = registry.bulkhead("my"); + Function decorated = Bulkhead.decorateFunction(bulkhead, service::process); + + Future taskInProgress = callAndBlock(decorated); + try { + assertThat(bulkhead.isCallPermitted()).isFalse(); + } finally { + taskInProgress.cancel(true); + } + } + + private Future callAndBlock(Function decoratedService) throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + when(service.process(anyInt())).thenAnswer(invocation -> { + latch.countDown(); + Thread.currentThread().join(); + return null; + }); + + ForkJoinTask result = ForkJoinPool.commonPool().submit(() -> { + decoratedService.apply(1); + }); + latch.await(); + return result; + } + + @Test + public void whenRetryIsUsed_thenItWorksAsExpected() { + RetryConfig config = RetryConfig.custom().maxAttempts(2).build(); + RetryRegistry registry = RetryRegistry.of(config); + Retry retry = registry.retry("my"); + Function decorated = Retry.decorateFunction(retry, (Integer s) -> { + service.process(s); + return null; + }); + + when(service.process(anyInt())).thenThrow(new RuntimeException()); + try { + decorated.apply(1); + fail("Expected an exception to be thrown if all retries failed"); + } catch (Exception e) { + verify(service, times(2)).process(any(Integer.class)); + } + } + + @SuppressWarnings("unchecked") + @Test + public void whenTimeLimiterIsUsed_thenItWorksAsExpected() throws Exception { + long ttl = 1; + TimeLimiterConfig config = TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(ttl)).build(); + TimeLimiter timeLimiter = TimeLimiter.of(config); + + Future futureMock = mock(Future.class); + Callable restrictedCall = TimeLimiter.decorateFutureSupplier(timeLimiter, () -> futureMock); + restrictedCall.call(); + + verify(futureMock).get(ttl, TimeUnit.MILLISECONDS); + } +} diff --git a/libraries/src/test/java/com/baeldung/snakeyaml/JavaToYAMLSerializationUnitTest.java b/libraries/src/test/java/com/baeldung/snakeyaml/JavaToYAMLSerializationUnitTest.java new file mode 100644 index 0000000000..f6836f6d56 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/snakeyaml/JavaToYAMLSerializationUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.snakeyaml; + +import static org.junit.Assert.assertEquals; + +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Test; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.nodes.Tag; + +import com.baeldung.snakeyaml.Customer; + +public class JavaToYAMLSerializationUnitTest { + + @Test + public void whenDumpMap_thenGenerateCorrectYAML() { + Map data = new LinkedHashMap(); + data.put("name", "Silenthand Olleander"); + data.put("race", "Human"); + data.put("traits", new String[] { "ONE_HAND", "ONE_EYE" }); + Yaml yaml = new Yaml(); + StringWriter writer = new StringWriter(); + yaml.dump(data, writer); + String expectedYaml = "name: Silenthand Olleander\nrace: Human\ntraits: [ONE_HAND, ONE_EYE]\n"; + assertEquals(expectedYaml, writer.toString()); + } + + @Test + public void whenDumpACustomType_thenGenerateCorrectYAML() { + Customer customer = new Customer(); + customer.setAge(45); + customer.setFirstName("Greg"); + customer.setLastName("McDowell"); + Yaml yaml = new Yaml(); + StringWriter writer = new StringWriter(); + yaml.dump(customer, writer); + String expectedYaml = "!!com.baeldung.snakeyaml.Customer {age: 45, contactDetails: null, firstName: Greg,\n homeAddress: null, lastName: McDowell}\n"; + assertEquals(expectedYaml, writer.toString()); + } + + @Test + public void whenDumpAsCustomType_thenGenerateCorrectYAML() { + Customer customer = new Customer(); + customer.setAge(45); + customer.setFirstName("Greg"); + customer.setLastName("McDowell"); + Yaml yaml = new Yaml(); + String expectedYaml = "{age: 45, contactDetails: null, firstName: Greg, homeAddress: null, lastName: McDowell}\n"; + assertEquals(expectedYaml, yaml.dumpAs(customer, Tag.MAP, null)); + } + +} diff --git a/libraries/src/test/java/com/baeldung/snakeyaml/YAMLToJavaDeserialisationUnitTest.java b/libraries/src/test/java/com/baeldung/snakeyaml/YAMLToJavaDeserialisationUnitTest.java new file mode 100644 index 0000000000..56cd3c2b2e --- /dev/null +++ b/libraries/src/test/java/com/baeldung/snakeyaml/YAMLToJavaDeserialisationUnitTest.java @@ -0,0 +1,131 @@ +package com.baeldung.snakeyaml; + +import org.junit.Test; +import org.yaml.snakeyaml.TypeDescription; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +import java.io.InputStream; +import java.util.Date; +import java.util.Map; + +import static org.junit.Assert.*; + +public class YAMLToJavaDeserialisationUnitTest { + + @Test + public void whenLoadYAMLDocument_thenLoadCorrectMap() { + Yaml yaml = new Yaml(); + InputStream inputStream = this.getClass() + .getClassLoader() + .getResourceAsStream("yaml/customer.yaml"); + Map obj = yaml.load(inputStream); + assertEquals("John", obj.get("firstName")); + assertEquals("Doe", obj.get("lastName")); + assertEquals(20, obj.get("age")); + } + + @Test + public void whenLoadYAMLDocumentWithTopLevelClass_thenLoadCorrectJavaObject() { + Yaml yaml = new Yaml(new Constructor(Customer.class)); + InputStream inputStream = this.getClass() + .getClassLoader() + .getResourceAsStream("yaml/customer.yaml"); + Customer customer = yaml.load(inputStream); + assertEquals("John", customer.getFirstName()); + assertEquals("Doe", customer.getLastName()); + assertEquals(20, customer.getAge()); + } + + @Test + public void whenLoadYAMLDocumentWithAssumedClass_thenLoadCorrectJavaObject() { + Yaml yaml = new Yaml(); + InputStream inputStream = this.getClass() + .getClassLoader() + .getResourceAsStream("yaml/customer_with_type.yaml"); + Customer customer = yaml.load(inputStream); + assertEquals("John", customer.getFirstName()); + assertEquals("Doe", customer.getLastName()); + assertEquals(20, customer.getAge()); + } + + @Test + public void whenLoadYAML_thenLoadCorrectImplicitTypes() { + Yaml yaml = new Yaml(); + Map document = yaml.load("3.0: 2018-07-22"); + assertNotNull(document); + assertEquals(1, document.size()); + assertTrue(document.containsKey(3.0d)); + assertTrue(document.get(3.0d) instanceof Date); + } + + @Test + public void whenLoadYAMLDocumentWithTopLevelClass_thenLoadCorrectJavaObjectWithNestedObjects() { + Yaml yaml = new Yaml(new Constructor(Customer.class)); + InputStream inputStream = this.getClass() + .getClassLoader() + .getResourceAsStream("yaml/customer_with_contact_details_and_address.yaml"); + Customer customer = yaml.load(inputStream); + assertNotNull(customer); + assertEquals("John", customer.getFirstName()); + assertEquals("Doe", customer.getLastName()); + assertEquals(31, customer.getAge()); + assertNotNull(customer.getContactDetails()); + assertEquals(2, customer.getContactDetails().size()); + assertEquals("mobile", customer.getContactDetails() + .get(0) + .getType()); + assertEquals(123456789,customer.getContactDetails() + .get(0) + .getNumber()); + assertEquals("landline", customer.getContactDetails() + .get(1) + .getType()); + assertEquals(456786868, customer.getContactDetails() + .get(1) + .getNumber()); + assertNotNull(customer.getHomeAddress()); + assertEquals("Xyz, DEF Street", customer.getHomeAddress() + .getLine()); + } + + @Test + public void whenLoadYAMLDocumentWithTypeDescription_thenLoadCorrectJavaObjectWithCorrectGenericType() { + Constructor constructor = new Constructor(Customer.class); + TypeDescription customTypeDescription = new TypeDescription(Customer.class); + customTypeDescription.addPropertyParameters("contactDetails", Contact.class); + constructor.addTypeDescription(customTypeDescription); + Yaml yaml = new Yaml(constructor); + InputStream inputStream = this.getClass() + .getClassLoader() + .getResourceAsStream("yaml/customer_with_contact_details.yaml"); + Customer customer = yaml.load(inputStream); + assertNotNull(customer); + assertEquals("John", customer.getFirstName()); + assertEquals("Doe", customer.getLastName()); + assertEquals(31, customer.getAge()); + assertNotNull(customer.getContactDetails()); + assertEquals(2, customer.getContactDetails().size()); + assertEquals("mobile", customer.getContactDetails() + .get(0) + .getType()); + assertEquals("landline", customer.getContactDetails() + .get(1) + .getType()); + } + + @Test + public void whenLoadMultipleYAMLDocuments_thenLoadCorrectJavaObjects() { + Yaml yaml = new Yaml(new Constructor(Customer.class)); + InputStream inputStream = this.getClass() + .getClassLoader() + .getResourceAsStream("yaml/customers.yaml"); + int count = 0; + for (Object object : yaml.loadAll(inputStream)) { + count++; + assertTrue(object instanceof Customer); + } + assertEquals(2, count); + } + +} diff --git a/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsUnitTest.java similarity index 96% rename from libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java rename to libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsUnitTest.java index 4cda0b5940..31f3a04362 100644 --- a/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsUnitTest.java @@ -10,7 +10,7 @@ import java.util.stream.Stream; import static junit.framework.TestCase.assertEquals; -public class JoolMergeStreamsTest { +public class JoolMergeStreamsUnitTest { @Test public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { Stream seq1 = Stream.of(1, 3, 5); diff --git a/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/MergeStreamsUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java rename to libraries/src/test/java/com/baeldung/stream/MergeStreamsUnitTest.java index b8748abe03..38ddb47d87 100644 --- a/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/MergeStreamsUnitTest.java @@ -9,7 +9,7 @@ import java.util.stream.Stream; import static org.junit.Assert.assertEquals; -public class MergeStreamsTest { +public class MergeStreamsUnitTest { @Test public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { diff --git a/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsUnitTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java rename to libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsUnitTest.java index e5392dff2a..220348bf36 100644 --- a/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java +++ b/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsUnitTest.java @@ -9,7 +9,7 @@ import java.util.stream.Stream; import static org.junit.Assert.assertEquals; -public class StreamExMergeStreamsTest { +public class StreamExMergeStreamsUnitTest { @Test public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { diff --git a/libraries/src/test/java/com/baeldung/streamutils/CopyStreamTest.java b/libraries/src/test/java/com/baeldung/streamutils/CopyStreamUnitTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/streamutils/CopyStreamTest.java rename to libraries/src/test/java/com/baeldung/streamutils/CopyStreamUnitTest.java index 3ed797ccaa..5af914afea 100644 --- a/libraries/src/test/java/com/baeldung/streamutils/CopyStreamTest.java +++ b/libraries/src/test/java/com/baeldung/streamutils/CopyStreamUnitTest.java @@ -16,7 +16,7 @@ import org.springframework.util.StreamUtils; import static com.baeldung.streamutils.CopyStream.getStringFromInputStream; -public class CopyStreamTest { +public class CopyStreamUnitTest { @Test public void whenCopyInputStreamToOutputStream_thenCorrect() throws IOException { diff --git a/libraries/src/test/java/com/baeldung/text/DiffTest.java b/libraries/src/test/java/com/baeldung/text/DiffUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/text/DiffTest.java rename to libraries/src/test/java/com/baeldung/text/DiffUnitTest.java index 932fc96f21..f8a5d6fc0c 100644 --- a/libraries/src/test/java/com/baeldung/text/DiffTest.java +++ b/libraries/src/test/java/com/baeldung/text/DiffUnitTest.java @@ -5,7 +5,7 @@ import org.apache.commons.text.diff.StringsComparator; import org.junit.Assert; import org.junit.Test; -public class DiffTest { +public class DiffUnitTest { @Test public void whenEditScript_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceTest.java b/libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceUnitTest.java similarity index 93% rename from libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceTest.java rename to libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceUnitTest.java index e0a00afd84..47cfda1863 100644 --- a/libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceTest.java +++ b/libraries/src/test/java/com/baeldung/text/LongestCommonSubsequenceUnitTest.java @@ -5,7 +5,7 @@ import org.apache.commons.text.similarity.LongestCommonSubsequenceDistance; import org.junit.Assert; import org.junit.Test; -public class LongestCommonSubsequenceTest { +public class LongestCommonSubsequenceUnitTest { @Test public void whenCompare_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/text/StrBuilderTest.java b/libraries/src/test/java/com/baeldung/text/StrBuilderUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/text/StrBuilderTest.java rename to libraries/src/test/java/com/baeldung/text/StrBuilderUnitTest.java index 4ebf00e1ed..09bb7f9a3f 100644 --- a/libraries/src/test/java/com/baeldung/text/StrBuilderTest.java +++ b/libraries/src/test/java/com/baeldung/text/StrBuilderUnitTest.java @@ -4,7 +4,7 @@ import org.apache.commons.text.StrBuilder; import org.junit.Assert; import org.junit.Test; -public class StrBuilderTest { +public class StrBuilderUnitTest { @Test public void whenReplaced_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/text/StrSubstitutorTest.java b/libraries/src/test/java/com/baeldung/text/StrSubstitutorUnitTest.java similarity index 94% rename from libraries/src/test/java/com/baeldung/text/StrSubstitutorTest.java rename to libraries/src/test/java/com/baeldung/text/StrSubstitutorUnitTest.java index 24e6ff59c8..85f5084485 100644 --- a/libraries/src/test/java/com/baeldung/text/StrSubstitutorTest.java +++ b/libraries/src/test/java/com/baeldung/text/StrSubstitutorUnitTest.java @@ -7,7 +7,7 @@ import org.apache.commons.text.StrSubstitutor; import org.junit.Assert; import org.junit.Test; -public class StrSubstitutorTest { +public class StrSubstitutorUnitTest { @Test public void whenSubstituted_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/text/UnicodeEscaperTest.java b/libraries/src/test/java/com/baeldung/text/UnicodeEscaperUnitTest.java similarity index 90% rename from libraries/src/test/java/com/baeldung/text/UnicodeEscaperTest.java rename to libraries/src/test/java/com/baeldung/text/UnicodeEscaperUnitTest.java index 5a52bfd0db..5614566949 100644 --- a/libraries/src/test/java/com/baeldung/text/UnicodeEscaperTest.java +++ b/libraries/src/test/java/com/baeldung/text/UnicodeEscaperUnitTest.java @@ -4,7 +4,7 @@ import org.apache.commons.text.translate.UnicodeEscaper; import org.junit.Assert; import org.junit.Test; -public class UnicodeEscaperTest { +public class UnicodeEscaperUnitTest { @Test public void whenTranslate_thenCorrect() { diff --git a/libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java b/libraries/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java similarity index 99% rename from libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java rename to libraries/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java index 82093ad297..7d3bce5cfe 100644 --- a/libraries/src/test/java/com/baeldung/unirest/HttpClientTest.java +++ b/libraries/src/test/java/com/baeldung/unirest/HttpClientLiveTest.java @@ -27,7 +27,7 @@ import com.mashape.unirest.http.Unirest; import com.mashape.unirest.http.async.Callback; import com.mashape.unirest.http.exceptions.UnirestException; -public class HttpClientTest { +public class HttpClientLiveTest { @BeforeClass public static void setup() { diff --git a/libraries/src/test/resources/yaml/customer.yaml b/libraries/src/test/resources/yaml/customer.yaml new file mode 100644 index 0000000000..aa76141c7d --- /dev/null +++ b/libraries/src/test/resources/yaml/customer.yaml @@ -0,0 +1,3 @@ +firstName: "John" +lastName: "Doe" +age: 20 \ No newline at end of file diff --git a/libraries/src/test/resources/yaml/customer_with_contact_details.yaml b/libraries/src/test/resources/yaml/customer_with_contact_details.yaml new file mode 100644 index 0000000000..34563cbd21 --- /dev/null +++ b/libraries/src/test/resources/yaml/customer_with_contact_details.yaml @@ -0,0 +1,7 @@ +firstName: "John" +lastName: "Doe" +age: 31 +contactDetails: + - { type: "mobile", number: 123456789} + - { type: "landline", number: 456786868} + \ No newline at end of file diff --git a/libraries/src/test/resources/yaml/customer_with_contact_details_and_address.yaml b/libraries/src/test/resources/yaml/customer_with_contact_details_and_address.yaml new file mode 100644 index 0000000000..664afe8594 --- /dev/null +++ b/libraries/src/test/resources/yaml/customer_with_contact_details_and_address.yaml @@ -0,0 +1,13 @@ +firstName: "John" +lastName: "Doe" +age: 31 +contactDetails: + - type: "mobile" + number: 123456789 + - type: "landline" + number: 456786868 +homeAddress: + line: "Xyz, DEF Street" + city: "City Y" + state: "State Y" + zip: 345657 diff --git a/libraries/src/test/resources/yaml/customer_with_contact_details_and_tags.yaml b/libraries/src/test/resources/yaml/customer_with_contact_details_and_tags.yaml new file mode 100644 index 0000000000..145da256d9 --- /dev/null +++ b/libraries/src/test/resources/yaml/customer_with_contact_details_and_tags.yaml @@ -0,0 +1,6 @@ +firstName: "John" +lastName: "Doe" +age: 31 +contactDetails: + - !contact { type: "mobile", number: 123456789} + - !contact { type: "landline", number: 456786868} diff --git a/libraries/src/test/resources/yaml/customer_with_type.yaml b/libraries/src/test/resources/yaml/customer_with_type.yaml new file mode 100644 index 0000000000..6e13c26cea --- /dev/null +++ b/libraries/src/test/resources/yaml/customer_with_type.yaml @@ -0,0 +1,4 @@ +!!com.baeldung.snakeyaml.Customer +firstName: "John" +lastName: "Doe" +age: 20 \ No newline at end of file diff --git a/libraries/src/test/resources/yaml/customers.yaml b/libraries/src/test/resources/yaml/customers.yaml new file mode 100644 index 0000000000..23b9039c2e --- /dev/null +++ b/libraries/src/test/resources/yaml/customers.yaml @@ -0,0 +1,8 @@ +--- +firstName: "John" +lastName: "Doe" +age: 20 +--- +firstName: "Jack" +lastName: "Jones" +age: 25 \ No newline at end of file diff --git a/linkrest/pom.xml b/linkrest/pom.xml index 5a8b39e7df..a27caea1ff 100644 --- a/linkrest/pom.xml +++ b/linkrest/pom.xml @@ -1,5 +1,5 @@ + 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 linkrest diff --git a/linkrest/src/main/resources/logback.xml b/linkrest/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/linkrest/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/logging-modules/log-mdc/pom.xml b/logging-modules/log-mdc/pom.xml index 6cfef12980..8e9968085e 100644 --- a/logging-modules/log-mdc/pom.xml +++ b/logging-modules/log-mdc/pom.xml @@ -1,5 +1,5 @@ + 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 log-mdc @@ -9,11 +9,11 @@ tutorial on logging with MDC and NDC - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../../parent-spring-4 + @@ -79,22 +79,13 @@ - - 1.2.17 - 2.7 - 3.3.6 - 3.3.0.Final - 3.1.0 - 2.8.5 - - org.apache.maven.plugins maven-war-plugin - 2.4 + ${maven-war-plugin.version} src/main/webapp logging-service @@ -105,4 +96,15 @@ logging-service + + + 1.2.17 + 2.7 + 3.3.6 + 3.3.0.Final + 3.1.0 + 2.8.5 + 2.4 + + diff --git a/logging-modules/log4j/README.md b/logging-modules/log4j/README.md index 8aae1b5826..9f4184ccba 100644 --- a/logging-modules/log4j/README.md +++ b/logging-modules/log4j/README.md @@ -4,3 +4,4 @@ - [Generate equals() and hashCode() with Eclipse](http://www.baeldung.com/java-eclipse-equals-and-hashcode) - [Introduction to SLF4J](http://www.baeldung.com/slf4j-with-log4j2-logback) - [A Guide to Rolling File Appenders](http://www.baeldung.com/java-logging-rolling-file-appenders) +- [Logging Exceptions Using SLF4J](https://www.baeldung.com/slf4j-log-exceptions) diff --git a/logging-modules/log4j/pom.xml b/logging-modules/log4j/pom.xml index 5e2f413e09..432295fc62 100644 --- a/logging-modules/log4j/pom.xml +++ b/logging-modules/log4j/pom.xml @@ -1,6 +1,6 @@ + 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 log4j diff --git a/logging-modules/log4j/src/main/java/com/baeldung/slf4j/SLF4JLogExceptions.java b/logging-modules/log4j/src/main/java/com/baeldung/slf4j/SLF4JLogExceptions.java new file mode 100644 index 0000000000..bd572770ab --- /dev/null +++ b/logging-modules/log4j/src/main/java/com/baeldung/slf4j/SLF4JLogExceptions.java @@ -0,0 +1,16 @@ +package com.baeldung.slf4j; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SLF4JLogExceptions { + + public static void main(String[] args) { + Logger logger = LoggerFactory.getLogger(SLF4JLogExceptions.class); + + logger.error("An exception occurred!"); + logger.error("An exception occurred!", new Exception("Custom exception")); + logger.error("{}, {}! An exception occurred!", "Hello", "World", new Exception("Custom exception")); + } + +} diff --git a/logging-modules/log4j2/${sys b/logging-modules/log4j2/${sys new file mode 100644 index 0000000000..e69de29bb2 diff --git a/logging-modules/log4j2/README.md b/logging-modules/log4j2/README.md index e209c6f035..2cf6f9768f 100644 --- a/logging-modules/log4j2/README.md +++ b/logging-modules/log4j2/README.md @@ -3,3 +3,4 @@ - [Intro to Log4j2 – Appenders, Layouts and Filters](http://www.baeldung.com/log4j2-appenders-layouts-filters) - [Log4j 2 and Lambda Expressions](http://www.baeldung.com/log4j-2-lazy-logging) - [Programmatic Configuration with Log4j 2](http://www.baeldung.com/log4j2-programmatic-config) +- [Creating a Custom Log4j2 Appender](https://www.baeldung.com/log4j2-custom-appender) diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml index 03f9a16de5..65da318636 100644 --- a/logging-modules/log4j2/pom.xml +++ b/logging-modules/log4j2/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 log4j2 @@ -18,6 +18,13 @@ log4j-core ${log4j-core.version} + + + + org.apache.logging.log4j + log4j-api + ${log4j-core.version} + @@ -53,29 +60,21 @@ test-jar test - - - - 2.9.5 - 1.4.193 - 2.1.1 - 2.11.0 - yyyyMMddHHmmss - + org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + ${maven-compiler-plugin.version} none - + integration @@ -113,4 +112,13 @@ - + + + 2.9.5 + 1.4.193 + 2.1.1 + 2.11.0 + yyyyMMddHHmmss + + + \ No newline at end of file diff --git a/logging-modules/log4j2/src/main/java/com/baeldung/logging/log4j2/appender/MapAppender.java b/logging-modules/log4j2/src/main/java/com/baeldung/logging/log4j2/appender/MapAppender.java new file mode 100644 index 0000000000..2015b6d573 --- /dev/null +++ b/logging-modules/log4j2/src/main/java/com/baeldung/logging/log4j2/appender/MapAppender.java @@ -0,0 +1,54 @@ +/** + * + */ +package com.baeldung.logging.log4j2.appender; + +import java.time.Instant; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Core; +import org.apache.logging.log4j.core.Filter; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.appender.AbstractAppender; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginAttribute; +import org.apache.logging.log4j.core.config.plugins.PluginElement; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; + +@Plugin(name = "MapAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE) +public class MapAppender extends AbstractAppender { + + private ConcurrentMap eventMap = new ConcurrentHashMap<>(); + + protected MapAppender(String name, Filter filter) { + super(name, filter, null); + } + + @PluginFactory + public static MapAppender createAppender(@PluginAttribute("name") String name, @PluginElement("Filter") final Filter filter) { + return new MapAppender(name, filter); + } + + @Override + public void append(LogEvent event) { + if (event.getLevel() + .isLessSpecificThan(Level.WARN)) { + error("Unable to log less than WARN level."); + return; + } + eventMap.put(Instant.now() + .toString(), event); + } + + public ConcurrentMap getEventMap() { + return eventMap; + } + + public void setEventMap(ConcurrentMap eventMap) { + this.eventMap = eventMap; + } + +} diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/appender/MapAppenderIntegrationTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/appender/MapAppenderIntegrationTest.java new file mode 100644 index 0000000000..020aaafc74 --- /dev/null +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/appender/MapAppenderIntegrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.logging.log4j2.appender; + +import static org.junit.Assert.assertEquals; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.Configuration; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class MapAppenderIntegrationTest { + + private Logger logger; + + @Before + public void setup() { + logger = LogManager.getLogger(MapAppenderIntegrationTest.class); + } + + @Test + public void whenLoggerEmitsLoggingEvent_thenAppenderReceivesEvent() throws Exception { + logger.info("Test from {}", this.getClass() + .getSimpleName()); + LoggerContext context = LoggerContext.getContext(false); + Configuration config = context.getConfiguration(); + MapAppender appender = config.getAppender("MapAppender"); + assertEquals(appender.getEventMap() + .size(), 1); + } + +} diff --git a/logging-modules/log4j2/src/test/resources/log4j2.xml b/logging-modules/log4j2/src/test/resources/log4j2.xml index 83b664a507..246ffb0707 100644 --- a/logging-modules/log4j2/src/test/resources/log4j2.xml +++ b/logging-modules/log4j2/src/test/resources/log4j2.xml @@ -1,6 +1,6 @@ - + @@ -50,6 +50,7 @@ size="17 kB" /> + + \ No newline at end of file diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml index 2ffcd0dbf8..e917754b3c 100644 --- a/logging-modules/logback/pom.xml +++ b/logging-modules/logback/pom.xml @@ -1,6 +1,6 @@ 4.0.0 @@ -40,7 +40,6 @@ - UTF-8 1.2.3 0.1.5 2.9.3 diff --git a/lombok/README.md b/lombok/README.md index 1a787e32c7..d12c14416d 100644 --- a/lombok/README.md +++ b/lombok/README.md @@ -1,3 +1,5 @@ ## Relevant Articles: - [Introduction to Project Lombok](http://www.baeldung.com/intro-to-project-lombok) - [Using Lombok’s @Builder Annotation](http://www.baeldung.com/lombok-builder) +- [Using Lombok’s @Getter for Boolean Fields](https://www.baeldung.com/lombok-getter-boolean) +- [Lombok @Builder with Inheritance](https://www.baeldung.com/lombok-builder-inheritance) diff --git a/lombok/pom.xml b/lombok/pom.xml index e0b0426c58..eba140122a 100644 --- a/lombok/pom.xml +++ b/lombok/pom.xml @@ -1,6 +1,6 @@ 4.0.0 @@ -66,8 +66,7 @@ false - @@ -75,7 +74,6 @@ - UTF-8 1.16.18 diff --git a/lombok/src/main/java/com/baeldung/lombok/builder/Child.java b/lombok/src/main/java/com/baeldung/lombok/builder/Child.java new file mode 100644 index 0000000000..70f6d9c46e --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/builder/Child.java @@ -0,0 +1,19 @@ +package com.baeldung.lombok.builder; + +import lombok.Builder; +import lombok.Getter; + +@Getter +public class Child extends Parent { + + private final String childName; + private final int childAge; + + @Builder(builderMethodName = "childBuilder") + public Child(String parentName, int parentAge, String childName, int childAge) { + super(parentName, parentAge); + this.childName = childName; + this.childAge = childAge; + } + +} diff --git a/lombok/src/main/java/com/baeldung/lombok/builder/Parent.java b/lombok/src/main/java/com/baeldung/lombok/builder/Parent.java new file mode 100644 index 0000000000..0cf76d4b00 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/builder/Parent.java @@ -0,0 +1,11 @@ +package com.baeldung.lombok.builder; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class Parent { + private final String parentName; + private final int parentAge; +} \ No newline at end of file diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java new file mode 100644 index 0000000000..2191396e5d --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.getter; + + +import lombok.Getter; + +/** + * Related Article Sections: + * 4. Using @Getter on a Boolean Field + * + */ +public class GetterBoolean { + + @Getter + private Boolean running = true; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java new file mode 100644 index 0000000000..5601f85b8b --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java @@ -0,0 +1,16 @@ +package com.baeldung.lombok.getter; + + +import lombok.Getter; + +/** + * Related Article Sections: + * 3. Using @Getter on a boolean Field + * + */ +public class GetterBooleanPrimitive { + + @Getter + private boolean running; + +} diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java new file mode 100644 index 0000000000..af29a33c20 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java @@ -0,0 +1,18 @@ +package com.baeldung.lombok.getter; + + +import lombok.Getter; + +/** + * Related Article Sections: + * 3.2. Two boolean Fields With the Same Accessor Name + * + */ +public class GetterBooleanPrimitiveSameAccessor { + + @Getter + boolean running = true; + + @Getter + boolean isRunning = false; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java new file mode 100644 index 0000000000..d972273b71 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java @@ -0,0 +1,13 @@ +package com.baeldung.lombok.getter; + +import lombok.Getter; + +/** + * Related Article Sections: + * 3.1. A boolean Field Having the Same Name With Its Accessor + * + */ +public class GetterBooleanSameAccessor { + @Getter + private boolean isRunning = true; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java new file mode 100644 index 0000000000..0d3b9a928a --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.getter; + + +import lombok.Getter; + +/** + * Related Article Sections: + * 4. Using @Getter on a Boolean Field + * + */ +public class GetterBooleanType { + + @Getter + private Boolean running = true; +} diff --git a/lombok/src/main/resources/logback.xml b/lombok/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/lombok/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/lombok/src/test/java/com/baeldung/lombok/builder/BuilderUnitTest.java b/lombok/src/test/java/com/baeldung/lombok/builder/BuilderUnitTest.java index acad7d6c04..56a380569d 100644 --- a/lombok/src/test/java/com/baeldung/lombok/builder/BuilderUnitTest.java +++ b/lombok/src/test/java/com/baeldung/lombok/builder/BuilderUnitTest.java @@ -1,42 +1,59 @@ package com.baeldung.lombok.builder; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.*; - -public class BuilderUnitTest -{ +public class BuilderUnitTest { @Test public void givenBuilder_WidgetIsBuilt() { - Widget testWidget = Widget.builder().name("foo").id(1).build(); - assertThat(testWidget.getName()) - .isEqualTo("foo"); - assertThat(testWidget.getId()) - .isEqualTo(1); + Widget testWidget = Widget.builder() + .name("foo") + .id(1) + .build(); + assertThat(testWidget.getName()).isEqualTo("foo"); + assertThat(testWidget.getId()).isEqualTo(1); } @Test public void givenToBuilder_whenToBuilder_BuilderIsCreated() { - Widget testWidget = Widget.builder().name("foo").id(1).build(); + Widget testWidget = Widget.builder() + .name("foo") + .id(1) + .build(); Widget.WidgetBuilder widgetBuilder = testWidget.toBuilder(); - Widget newWidget = widgetBuilder.id(2).build(); - assertThat(newWidget.getName()) - .isEqualTo("foo"); - assertThat(newWidget.getId()) - .isEqualTo(2); + Widget newWidget = widgetBuilder.id(2) + .build(); + assertThat(newWidget.getName()).isEqualTo("foo"); + assertThat(newWidget.getId()).isEqualTo(2); } - - @Test public void givenBuilderMethod_ClientIsBuilt() { - ImmutableClient testImmutableClient = ClientBuilder.builder().name("foo").id(1).build(); - assertThat(testImmutableClient.getName()) - .isEqualTo("foo"); - assertThat(testImmutableClient.getId()) - .isEqualTo(1); + ImmutableClient testImmutableClient = ClientBuilder.builder() + .name("foo") + .id(1) + .build(); + assertThat(testImmutableClient.getName()).isEqualTo("foo"); + assertThat(testImmutableClient.getId()).isEqualTo(1); } + + @Test + public void givenBuilderAtMethodLevel_ChildInheritingParentIsBuilt() { + Child child = Child.childBuilder() + .parentName("Andrea") + .parentAge(38) + .childName("Emma") + .childAge(6) + .build(); + + assertThat(child.getChildName()).isEqualTo("Emma"); + assertThat(child.getChildAge()).isEqualTo(6); + assertThat(child.getParentName()).isEqualTo("Andrea"); + assertThat(child.getParentAge()).isEqualTo(38); + } + } diff --git a/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java b/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java new file mode 100644 index 0000000000..632594d575 --- /dev/null +++ b/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.lombok.getter; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class GetterBooleanUnitTest { + + @Test + public void whenBasicBooleanField_thenMethodNamePrefixedWithIsFollowedByFieldName() { + GetterBooleanPrimitive lombokExamples = new GetterBooleanPrimitive(); + assertFalse(lombokExamples.isRunning()); + } + + @Test + public void whenBooleanFieldPrefixedWithIs_thenMethodNameIsSameAsFieldName() { + GetterBooleanSameAccessor lombokExamples = new GetterBooleanSameAccessor(); + assertTrue(lombokExamples.isRunning()); + } + + @Test + public void whenTwoBooleanFieldsCauseNamingConflict_thenLombokMapsToFirstDeclaredField() { + GetterBooleanPrimitiveSameAccessor lombokExamples = new GetterBooleanPrimitiveSameAccessor(); + assertTrue(lombokExamples.isRunning() == lombokExamples.running); + assertFalse(lombokExamples.isRunning() == lombokExamples.isRunning); + } + + @Test + public void whenFieldOfBooleanType_thenLombokPrefixesMethodWithGetInsteadOfIs() { + GetterBooleanType lombokExamples = new GetterBooleanType(); + assertTrue(lombokExamples.getRunning()); + } +} diff --git a/lucene/README.md b/lucene/README.md index b1d33472f4..ea7f715480 100644 --- a/lucene/README.md +++ b/lucene/README.md @@ -2,3 +2,4 @@ - [Introduction to Apache Lucene](http://www.baeldung.com/lucene) - [A Simple File Search with Lucene](http://www.baeldung.com/lucene-file-search) +- [Guide to Lucene Analyzers](https://www.baeldung.com/lucene-analyzers) diff --git a/lucene/pom.xml b/lucene/pom.xml index b8786fadc7..f427cfd8a7 100644 --- a/lucene/pom.xml +++ b/lucene/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 lucene 0.0.1-SNAPSHOT @@ -23,24 +23,22 @@ lucene-queryparser ${lucene.version} - - junit - junit - ${junit.version} - test + org.apache.lucene + lucene-analyzers-common + ${lucene.version} + - UTF-8 1.16.18 1.0.0.Final 1.16.10.0 - 7.1.0 + 7.4.0 \ No newline at end of file diff --git a/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java b/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java index 97b1ec7b5d..8a31d3cb5b 100644 --- a/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java +++ b/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java @@ -4,7 +4,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.SortedDocValuesField; @@ -27,9 +27,9 @@ import org.apache.lucene.util.BytesRef; public class InMemoryLuceneIndex { private Directory memoryIndex; - private StandardAnalyzer analyzer; + private Analyzer analyzer; - public InMemoryLuceneIndex(Directory memoryIndex, StandardAnalyzer analyzer) { + public InMemoryLuceneIndex(Directory memoryIndex, Analyzer analyzer) { super(); this.memoryIndex = memoryIndex; this.analyzer = analyzer; diff --git a/lucene/src/main/java/com/baeldung/lucene/MyCustomAnalyzer.java b/lucene/src/main/java/com/baeldung/lucene/MyCustomAnalyzer.java new file mode 100644 index 0000000000..609e2d09d3 --- /dev/null +++ b/lucene/src/main/java/com/baeldung/lucene/MyCustomAnalyzer.java @@ -0,0 +1,26 @@ +package com.baeldung.lucene; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.LowerCaseFilter; +import org.apache.lucene.analysis.StopFilter; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.en.PorterStemFilter; +import org.apache.lucene.analysis.miscellaneous.CapitalizationFilter; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.analysis.standard.StandardFilter; +import org.apache.lucene.analysis.standard.StandardTokenizer; + +public class MyCustomAnalyzer extends Analyzer{ + + @Override + protected TokenStreamComponents createComponents(String fieldName) { + final StandardTokenizer src = new StandardTokenizer(); + TokenStream result = new StandardFilter(src); + result = new LowerCaseFilter(result); + result = new StopFilter(result, StandardAnalyzer.STOP_WORDS_SET); + result = new PorterStemFilter(result); + result = new CapitalizationFilter(result); + return new TokenStreamComponents(src, result); + } + +} diff --git a/lucene/src/main/resources/logback.xml b/lucene/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/lucene/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/lucene/src/test/java/com/baeldung/lucene/LuceneAnalyzerIntegrationTest.java b/lucene/src/test/java/com/baeldung/lucene/LuceneAnalyzerIntegrationTest.java new file mode 100644 index 0000000000..28a87bba8c --- /dev/null +++ b/lucene/src/test/java/com/baeldung/lucene/LuceneAnalyzerIntegrationTest.java @@ -0,0 +1,147 @@ +package com.baeldung.lucene; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.core.KeywordAnalyzer; +import org.apache.lucene.analysis.core.SimpleAnalyzer; +import org.apache.lucene.analysis.core.StopAnalyzer; +import org.apache.lucene.analysis.core.WhitespaceAnalyzer; +import org.apache.lucene.analysis.custom.CustomAnalyzer; +import org.apache.lucene.analysis.en.EnglishAnalyzer; +import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.store.RAMDirectory; +import org.junit.Test; + +public class LuceneAnalyzerIntegrationTest { + + private static final String SAMPLE_TEXT = "This is baeldung.com Lucene Analyzers test"; + private static final String FIELD_NAME = "sampleName"; + + @Test + public void whenUseStandardAnalyzer_thenAnalyzed() throws IOException { + List result = analyze(SAMPLE_TEXT, new StandardAnalyzer()); + + assertThat(result, contains("baeldung.com", "lucene", "analyzers", "test")); + } + + @Test + public void whenUseStopAnalyzer_thenAnalyzed() throws IOException { + List result = analyze(SAMPLE_TEXT, new StopAnalyzer()); + + assertThat(result, contains("baeldung", "com", "lucene", "analyzers", "test")); + } + + @Test + public void whenUseSimpleAnalyzer_thenAnalyzed() throws IOException { + List result = analyze(SAMPLE_TEXT, new SimpleAnalyzer()); + + assertThat(result, contains("this", "is", "baeldung", "com", "lucene", "analyzers", "test")); + } + + @Test + public void whenUseWhiteSpaceAnalyzer_thenAnalyzed() throws IOException { + List result = analyze(SAMPLE_TEXT, new WhitespaceAnalyzer()); + + assertThat(result, contains("This", "is", "baeldung.com", "Lucene", "Analyzers", "test")); + } + + @Test + public void whenUseKeywordAnalyzer_thenAnalyzed() throws IOException { + List result = analyze(SAMPLE_TEXT, new KeywordAnalyzer()); + + assertThat(result, contains("This is baeldung.com Lucene Analyzers test")); + } + + @Test + public void whenUseEnglishAnalyzer_thenAnalyzed() throws IOException { + List result = analyze(SAMPLE_TEXT, new EnglishAnalyzer()); + + assertThat(result, contains("baeldung.com", "lucen", "analyz", "test")); + } + + @Test + public void whenUseCustomAnalyzerBuilder_thenAnalyzed() throws IOException { + Analyzer analyzer = CustomAnalyzer.builder() + .withTokenizer("standard") + .addTokenFilter("lowercase") + .addTokenFilter("stop") + .addTokenFilter("porterstem") + .addTokenFilter("capitalization") + .build(); + List result = analyze(SAMPLE_TEXT, analyzer); + + assertThat(result, contains("Baeldung.com", "Lucen", "Analyz", "Test")); + } + + @Test + public void whenUseCustomAnalyzer_thenAnalyzed() throws IOException { + List result = analyze(SAMPLE_TEXT, new MyCustomAnalyzer()); + + assertThat(result, contains("Baeldung.com", "Lucen", "Analyz", "Test")); + } + + // ================= usage example + + @Test + public void givenTermQuery_whenUseCustomAnalyzer_thenCorrect() { + InMemoryLuceneIndex luceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new MyCustomAnalyzer()); + luceneIndex.indexDocument("introduction", "introduction to lucene"); + luceneIndex.indexDocument("analyzers", "guide to lucene analyzers"); + Query query = new TermQuery(new Term("body", "Introduct")); + + List documents = luceneIndex.searchIndex(query); + assertEquals(1, documents.size()); + } + + @Test + public void givenTermQuery_whenUsePerFieldAnalyzerWrapper_thenCorrect() { + Map analyzerMap = new HashMap<>(); + analyzerMap.put("title", new MyCustomAnalyzer()); + analyzerMap.put("body", new EnglishAnalyzer()); + + PerFieldAnalyzerWrapper wrapper = + new PerFieldAnalyzerWrapper(new StandardAnalyzer(), analyzerMap); + InMemoryLuceneIndex luceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), wrapper); + luceneIndex.indexDocument("introduction", "introduction to lucene"); + luceneIndex.indexDocument("analyzers", "guide to lucene analyzers"); + + Query query = new TermQuery(new Term("body", "introduct")); + List documents = luceneIndex.searchIndex(query); + assertEquals(1, documents.size()); + + query = new TermQuery(new Term("title", "Introduct")); + + documents = luceneIndex.searchIndex(query); + assertEquals(1, documents.size()); + } + + // =================================================================== + + public List analyze(String text, Analyzer analyzer) throws IOException { + List result = new ArrayList(); + TokenStream tokenStream = analyzer.tokenStream(FIELD_NAME, text); + CharTermAttribute attr = tokenStream.addAttribute(CharTermAttribute.class); + tokenStream.reset(); + while (tokenStream.incrementToken()) { + result.add(attr.toString()); + } + return result; + } + +} diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml index be105b8aa8..6c274dfcf2 100644 --- a/mapstruct/pom.xml +++ b/mapstruct/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 mapstruct mapstruct diff --git a/mapstruct/src/main/resources/logback.xml b/mapstruct/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/mapstruct/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/maven-archetype/README.md b/maven-archetype/README.md new file mode 100644 index 0000000000..71821e3348 --- /dev/null +++ b/maven-archetype/README.md @@ -0,0 +1,4 @@ +### Relevant Articles: +================================ + +- [Guide to Maven Archetype](http://www.baeldung.com/maven-archetype) diff --git a/maven-archetype/pom.xml b/maven-archetype/pom.xml index df0aa768d8..f7871c81ea 100644 --- a/maven-archetype/pom.xml +++ b/maven-archetype/pom.xml @@ -1,29 +1,28 @@ - + 4.0.0 - com.baeldung.archetypes maven-archetype 1.0-SNAPSHOT maven-archetype Archetype used to generate rest application based on jaxrs 2.1 - - 1.8 - 1.8 - - org.apache.maven.archetype archetype-packaging - 3.0.1 + ${archetype-packaging.version} - + + + 1.8 + 1.8 + 3.0.1 + + diff --git a/maven-archetype/src/main/resources/logback.xml b/maven-archetype/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/maven-archetype/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/maven-polyglot/README.md b/maven-polyglot/README.md new file mode 100644 index 0000000000..589315efd1 --- /dev/null +++ b/maven-polyglot/README.md @@ -0,0 +1,3 @@ +To run the maven-polyglot-json-app successfully, you first have to build the maven-polyglot-json-extension module using: mvn clean install. + +Related Articles: diff --git a/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml b/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml new file mode 100644 index 0000000000..c06b76e1b2 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-app/.mvn/extensions.xml @@ -0,0 +1,8 @@ + + + + com.baeldung.maven.polyglot + maven-polyglot-json-extension + 1.0-SNAPSHOT + + \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-json-app/pom.json b/maven-polyglot/maven-polyglot-json-app/pom.json new file mode 100644 index 0000000000..abd58f3127 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-app/pom.json @@ -0,0 +1,34 @@ +{ + "modelVersion": "4.0.0", + "groupId": "com.baeldung.maven.polyglot", + "artifactId": "maven-polyglot-json-app", + "version": "1.0-SNAPSHOT", + "name": "Json Maven Polyglot", + "parent": { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-parent", + "version": "2.0.5.RELEASE", + "relativePath": null + }, + "properties": { + "project.build.sourceEncoding": "UTF-8", + "project.reporting.outputEncoding": "UTF-8", + "maven.compiler.source": "1.8", + "maven.compiler.target": "1.8", + "java.version": "1.8" + }, + "dependencies": [ + { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-web" + } + ], + "build": { + "plugins": [ + { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-maven-plugin" + } + ] + } +} \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java b/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java new file mode 100644 index 0000000000..d03116889f --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-app/src/main/java/com/baeldung/maven/polyglot/MavenPolyglotApplication.java @@ -0,0 +1,19 @@ +package com.baeldung.maven.polyglot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.GetMapping; + +@RestController +@SpringBootApplication +public class MavenPolyglotApplication { + public static void main(String[] args) { + SpringApplication.run(MavenPolyglotApplication.class, args); + } + + @GetMapping("/") + public String home(){ + return "Hello JSON Maven Model !"; + } +} diff --git a/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json b/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json new file mode 100644 index 0000000000..f006582c12 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-app/src/main/resources/model.json @@ -0,0 +1,109 @@ +{ + "modules": [], + "distributionManagement": null, + "properties": { + "project.reporting.outputEncoding": "UTF-8", + "java.version": "1.8", + "maven.compiler.source": "1.8", + "project.build.sourceEncoding": "UTF-8", + "maven.compiler.target": "1.8" + }, + "dependencyManagement": null, + "dependencies": [ + { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-web", + "version": null, + "type": "jar", + "classifier": null, + "scope": null, + "systemPath": null, + "exclusions": [], + "optional": null, + "managementKey": "org.springframework.boot:spring-boot-starter-web:jar" + } + ], + "repositories": [], + "pluginRepositories": [], + "reports": null, + "reporting": null, + "modelVersion": "4.0.0", + "parent": { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-parent", + "version": "2.0.5.RELEASE", + "relativePath": "", + "id": "org.springframework.boot:spring-boot-starter-parent:pom:2.0.5.RELEASE" + }, + "groupId": "com.demo.polyglot", + "artifactId": "maven-polyglot-app", + "version": "1.0.1", + "packaging": "jar", + "name": "Json Maven Polyglot", + "description": null, + "url": null, + "inceptionYear": null, + "organization": null, + "licenses": [], + "developers": [], + "contributors": [], + "mailingLists": [], + "prerequisites": null, + "scm": null, + "issueManagement": null, + "ciManagement": null, + "build": { + "plugins": [ + { + "inherited": null, + "configuration": null, + "inheritanceApplied": true, + "groupId": "org.liquibase", + "artifactId": "liquibase-maven-plugin", + "version": "3.0.5", + "extensions": null, + "executions": [], + "dependencies": [], + "goals": null, + "key": "org.liquibase:liquibase-maven-plugin", + "id": "org.liquibase:liquibase-maven-plugin:3.0.5", + "executionsAsMap": {} + } + ], + "pluginManagement": null, + "defaultGoal": null, + "resources": [], + "testResources": [], + "directory": null, + "finalName": null, + "filters": [], + "sourceDirectory": null, + "scriptSourceDirectory": null, + "testSourceDirectory": null, + "outputDirectory": null, + "testOutputDirectory": null, + "extensions": [], + "pluginsAsMap": { + "org.liquibase:liquibase-maven-plugin": { + "inherited": null, + "configuration": null, + "inheritanceApplied": true, + "groupId": "org.liquibase", + "artifactId": "liquibase-maven-plugin", + "version": "3.0.5", + "extensions": null, + "executions": [], + "dependencies": [], + "goals": null, + "key": "org.liquibase:liquibase-maven-plugin", + "id": "org.liquibase:liquibase-maven-plugin:3.0.5", + "executionsAsMap": {} + } + } + }, + "profiles": [], + "modelEncoding": "UTF-8", + "pomFile": null, + "id": "com.demo.polyglot:maven-polyglot-app:jar:1.0.1", + "projectDirectory": null +} diff --git a/maven-polyglot/maven-polyglot-json-extension/pom.xml b/maven-polyglot/maven-polyglot-json-extension/pom.xml new file mode 100644 index 0000000000..d5c5b7ab55 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-extension/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + + com.baeldung.maven.polyglot + maven-polyglot-json-extension + 1.0-SNAPSHOT + + + 1.8 + 1.8 + + + + + org.apache.maven + maven-core + 3.5.4 + provided + + + com.fasterxml.jackson.core + jackson-databind + 2.9.6 + + + + + + + org.codehaus.plexus + plexus-component-metadata + 1.7.1 + + + + generate-metadata + + + + + + + + \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java b/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java new file mode 100644 index 0000000000..a1756192e9 --- /dev/null +++ b/maven-polyglot/maven-polyglot-json-extension/src/main/java/com/demo/polyglot/CustomModelProcessor.java @@ -0,0 +1,62 @@ +package com.demo.polyglot; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.maven.model.Model; +import org.apache.maven.model.building.FileModelSource; +import org.apache.maven.model.building.ModelProcessor; +import org.apache.maven.model.io.ModelParseException; +import org.apache.maven.model.io.ModelReader; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.util.ReaderFactory; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.util.Map; + +@Component(role = ModelProcessor.class) +public class CustomModelProcessor implements ModelProcessor { + + private static final String XML_POM = "pom.xml"; + private static final String JSON_POM = "pom.json"; + private static final String JSON_EXT = ".json"; + + ObjectMapper objectMapper = new ObjectMapper(); + + @Requirement + private ModelReader modelReader; + + @Override + public File locatePom(File projectDirectory) { + File pomFile = new File(projectDirectory, JSON_POM); + if (!pomFile.exists()) { + pomFile = new File(projectDirectory, XML_POM); + } + return pomFile; + } + + @Override + public Model read(InputStream input, Map options) throws IOException, ModelParseException { + try (final Reader in = ReaderFactory.newPlatformReader(input)) { + return read(in, options); + } + } + + @Override + public Model read(Reader reader, Map options) throws IOException, ModelParseException { + FileModelSource source = (options != null) ? (FileModelSource) options.get(SOURCE) : null; + if (source != null && source.getLocation().endsWith(JSON_EXT)) { + Model model = objectMapper.readValue(reader, Model.class); + return model; + } + //It's a normal maven project with a pom.xml file + return modelReader.read(reader, options); + } + + @Override + public Model read(File input, Map options) throws IOException, ModelParseException { + return null; + } +} \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml b/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml new file mode 100644 index 0000000000..cfc6275681 --- /dev/null +++ b/maven-polyglot/maven-polyglot-yml-app/.mvn/extensions.xml @@ -0,0 +1,8 @@ + + + + io.takari.polyglot + polyglot-yaml + 0.3.1 + + \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-yml-app/pom.yml b/maven-polyglot/maven-polyglot-yml-app/pom.yml new file mode 100644 index 0000000000..445e2eec3b --- /dev/null +++ b/maven-polyglot/maven-polyglot-yml-app/pom.yml @@ -0,0 +1,7 @@ +modelVersion: 4.0.0 +groupId: com.baeldung.maven.polyglot +artifactId: maven-polyglot-yml-app +version: 1.0-SNAPSHOT +name: 'YAML Demo' + +properties: {maven.compiler.source: 1.8, maven.compiler.target: 1.8} \ No newline at end of file diff --git a/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java b/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java new file mode 100644 index 0000000000..2142c7f9b8 --- /dev/null +++ b/maven-polyglot/maven-polyglot-yml-app/src/main/java/com/baeldung/maven/polyglot/YamlDemoApplication.java @@ -0,0 +1,7 @@ +package com.baeldung.maven.polyglot; + +public class YamlDemoApplication { + public static void main(String[] args) { + System.out.println("Hello Maven Polyglot YAML !"); + } +} diff --git a/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json b/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json new file mode 100644 index 0000000000..f006582c12 --- /dev/null +++ b/maven-polyglot/maven-polyglot-yml-app/src/main/resources/model.json @@ -0,0 +1,109 @@ +{ + "modules": [], + "distributionManagement": null, + "properties": { + "project.reporting.outputEncoding": "UTF-8", + "java.version": "1.8", + "maven.compiler.source": "1.8", + "project.build.sourceEncoding": "UTF-8", + "maven.compiler.target": "1.8" + }, + "dependencyManagement": null, + "dependencies": [ + { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-web", + "version": null, + "type": "jar", + "classifier": null, + "scope": null, + "systemPath": null, + "exclusions": [], + "optional": null, + "managementKey": "org.springframework.boot:spring-boot-starter-web:jar" + } + ], + "repositories": [], + "pluginRepositories": [], + "reports": null, + "reporting": null, + "modelVersion": "4.0.0", + "parent": { + "groupId": "org.springframework.boot", + "artifactId": "spring-boot-starter-parent", + "version": "2.0.5.RELEASE", + "relativePath": "", + "id": "org.springframework.boot:spring-boot-starter-parent:pom:2.0.5.RELEASE" + }, + "groupId": "com.demo.polyglot", + "artifactId": "maven-polyglot-app", + "version": "1.0.1", + "packaging": "jar", + "name": "Json Maven Polyglot", + "description": null, + "url": null, + "inceptionYear": null, + "organization": null, + "licenses": [], + "developers": [], + "contributors": [], + "mailingLists": [], + "prerequisites": null, + "scm": null, + "issueManagement": null, + "ciManagement": null, + "build": { + "plugins": [ + { + "inherited": null, + "configuration": null, + "inheritanceApplied": true, + "groupId": "org.liquibase", + "artifactId": "liquibase-maven-plugin", + "version": "3.0.5", + "extensions": null, + "executions": [], + "dependencies": [], + "goals": null, + "key": "org.liquibase:liquibase-maven-plugin", + "id": "org.liquibase:liquibase-maven-plugin:3.0.5", + "executionsAsMap": {} + } + ], + "pluginManagement": null, + "defaultGoal": null, + "resources": [], + "testResources": [], + "directory": null, + "finalName": null, + "filters": [], + "sourceDirectory": null, + "scriptSourceDirectory": null, + "testSourceDirectory": null, + "outputDirectory": null, + "testOutputDirectory": null, + "extensions": [], + "pluginsAsMap": { + "org.liquibase:liquibase-maven-plugin": { + "inherited": null, + "configuration": null, + "inheritanceApplied": true, + "groupId": "org.liquibase", + "artifactId": "liquibase-maven-plugin", + "version": "3.0.5", + "extensions": null, + "executions": [], + "dependencies": [], + "goals": null, + "key": "org.liquibase:liquibase-maven-plugin", + "id": "org.liquibase:liquibase-maven-plugin:3.0.5", + "executionsAsMap": {} + } + } + }, + "profiles": [], + "modelEncoding": "UTF-8", + "pomFile": null, + "id": "com.demo.polyglot:maven-polyglot-app:jar:1.0.1", + "projectDirectory": null +} diff --git a/maven/README.md b/maven/README.md index 7c3779143a..2d838bcb76 100644 --- a/maven/README.md +++ b/maven/README.md @@ -7,3 +7,6 @@ - [The Maven Failsafe Plugin](http://www.baeldung.com/maven-failsafe-plugin) - [The Maven Verifier Plugin](http://www.baeldung.com/maven-verifier-plugin) - [The Maven Clean Plugin](http://www.baeldung.com/maven-clean-plugin) +- [Build a Jar with Maven and Ignore the Test Results](http://www.baeldung.com/maven-ignore-test-results) +- [Maven Project with Multiple Source Directories](https://www.baeldung.com/maven-project-multiple-src-directories) +- [Integration Testing with Maven](https://www.baeldung.com/maven-integration-test) diff --git a/maven/pom.xml b/maven/pom.xml index fb7233e7e9..4bec533226 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -4,14 +4,19 @@ com.baeldung maven 0.0.1-SNAPSHOT - - - parent-modules - com.baeldung - 1.0.0-SNAPSHOT - + war + + org.glassfish.jersey.containers + jersey-container-servlet-core + ${jersey.version} + + + org.glassfish.jersey.inject + jersey-hk2 + ${jersey.version} + junit junit @@ -22,6 +27,34 @@ + + org.eclipse.jetty + jetty-maven-plugin + ${jetty.version} + + + 8999 + + quit + 9000 + + + + start-jetty + pre-integration-test + + start + + + + stop-jetty + post-integration-test + + stop + + + + maven-resources-plugin ${maven.resources.version} @@ -42,8 +75,8 @@ maven-compiler-plugin ${maven.compiler.version} - ${maven.compiler.source} - ${maven.compiler.target} + ${java.version} + ${java.version} -Xlint:unchecked @@ -55,10 +88,14 @@ DataTest.java + **/*IntegrationTest + com.baeldung.maven.it.Integration + TestFail.java DataCheck.java + true @@ -101,19 +138,166 @@ + + org.codehaus.mojo + build-helper-maven-plugin + ${maven.build.helper.version} + + + generate-sources + + add-source + + + + src/main/another-src + + + + + add-integration-test-source + generate-test-sources + + add-test-source + + + + src/integration-test/java + + + + + add-integration-test-resource + generate-test-resources + + add-test-resource + + + + + src/integration-test/resources + + + + + + + + + default + + + + maven-surefire-plugin + ${maven.surefire.version} + + + DataTest.java + + + TestFail.java + DataCheck.java + + true + + + + + + + failsafe + + + + maven-failsafe-plugin + ${maven.failsafe.version} + + + **/*RestIT + **/RestITCase + + + + + + integration-test + verify + + + + + + + + + surefire + + + + maven-surefire-plugin + ${maven.surefire.version} + + + integration-test + + test + + + + none + + + **/*IntegrationTest + + + + + + + + + + category + + + + maven-failsafe-plugin + ${maven.failsafe.version} + + + **/* + + com.baeldung.maven.it.Integration + + + + + integration-test + verify + + + + + + + + + + 1.8 3.0.2 - 3.7.0 - 2.21.0 - 2.21.0 + 3.8.0 + 2.22.0 + 2.22.0 1.1 3.0.0 + 3.0.0 Baeldung - 1.8 - 1.8 + 9.4.11.v20180605 + 2.27 + 4.12 - \ No newline at end of file diff --git a/maven/src/integration-test/java/com/baeldung/maven/it/RestITCase.java b/maven/src/integration-test/java/com/baeldung/maven/it/RestITCase.java new file mode 100644 index 0000000000..aaeeedb661 --- /dev/null +++ b/maven/src/integration-test/java/com/baeldung/maven/it/RestITCase.java @@ -0,0 +1,24 @@ +package com.baeldung.maven.it; + +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Scanner; + +import static org.junit.Assert.assertEquals; + +public class RestITCase { + @Test + public void whenSendingGet_thenMessageIsReturned() throws IOException { + String url = "http://localhost:8999"; + URLConnection connection = new URL(url).openConnection(); + try (InputStream response = connection.getInputStream(); + Scanner scanner = new Scanner(response)) { + String responseBody = scanner.nextLine(); + assertEquals("Welcome to Baeldung!", responseBody); + } + } +} diff --git a/maven/src/main/another-src/com/baeldung/maven/plugins/Foo.java b/maven/src/main/another-src/com/baeldung/maven/plugins/Foo.java new file mode 100644 index 0000000000..f8a6fe9853 --- /dev/null +++ b/maven/src/main/another-src/com/baeldung/maven/plugins/Foo.java @@ -0,0 +1,10 @@ +package com.baeldung.maven.plugins; + +public class Foo { + + public static String foo() { + return "foo"; + } + +} + diff --git a/maven/src/main/java/com/baeldung/maven/it/EndpointConfig.java b/maven/src/main/java/com/baeldung/maven/it/EndpointConfig.java new file mode 100644 index 0000000000..919210ccff --- /dev/null +++ b/maven/src/main/java/com/baeldung/maven/it/EndpointConfig.java @@ -0,0 +1,9 @@ +package com.baeldung.maven.it; + +import org.glassfish.jersey.server.ResourceConfig; + +public class EndpointConfig extends ResourceConfig { + public EndpointConfig() { + register(RestEndpoint.class); + } +} diff --git a/maven/src/main/java/com/baeldung/maven/it/RestEndpoint.java b/maven/src/main/java/com/baeldung/maven/it/RestEndpoint.java new file mode 100644 index 0000000000..c234891865 --- /dev/null +++ b/maven/src/main/java/com/baeldung/maven/it/RestEndpoint.java @@ -0,0 +1,12 @@ +package com.baeldung.maven.it; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +@Path("/") +public class RestEndpoint { + @GET + public String hello() { + return "Welcome to Baeldung!"; + } +} diff --git a/maven/src/main/java/com/baeldung/maven/plugins/MultipleSrcFolders.java b/maven/src/main/java/com/baeldung/maven/plugins/MultipleSrcFolders.java new file mode 100644 index 0000000000..d403918dd3 --- /dev/null +++ b/maven/src/main/java/com/baeldung/maven/plugins/MultipleSrcFolders.java @@ -0,0 +1,9 @@ +package com.baeldung.maven.plugins; + +public class MultipleSrcFolders { + + public static void callFoo() { + Foo.foo(); + } + +} diff --git a/maven/src/main/resources/logback.xml b/maven/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/maven/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/maven/src/main/webapp/WEB-INF/web.xml b/maven/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..1751ad17a5 --- /dev/null +++ b/maven/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,17 @@ + + + rest-servlet + org.glassfish.jersey.servlet.ServletContainer + + javax.ws.rs.Application + com.baeldung.maven.it.EndpointConfig + + + + rest-servlet + /* + + \ No newline at end of file diff --git a/maven/src/test/java/com/baeldung/maven/it/Integration.java b/maven/src/test/java/com/baeldung/maven/it/Integration.java new file mode 100644 index 0000000000..112ce178ce --- /dev/null +++ b/maven/src/test/java/com/baeldung/maven/it/Integration.java @@ -0,0 +1,4 @@ +package com.baeldung.maven.it; + +public interface Integration { +} diff --git a/maven/src/test/java/com/baeldung/maven/it/RestIT.java b/maven/src/test/java/com/baeldung/maven/it/RestIT.java new file mode 100644 index 0000000000..0115d34f1e --- /dev/null +++ b/maven/src/test/java/com/baeldung/maven/it/RestIT.java @@ -0,0 +1,24 @@ +package com.baeldung.maven.it; + +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Scanner; + +import static org.junit.Assert.assertEquals; + +public class RestIT { + @Test + public void whenSendingGet_thenMessageIsReturned() throws IOException { + String url = "http://localhost:8999"; + URLConnection connection = new URL(url).openConnection(); + try (InputStream response = connection.getInputStream(); + Scanner scanner = new Scanner(response)) { + String responseBody = scanner.nextLine(); + assertEquals("Welcome to Baeldung!", responseBody); + } + } +} diff --git a/maven/src/test/java/com/baeldung/maven/it/RestIntegrationTest.java b/maven/src/test/java/com/baeldung/maven/it/RestIntegrationTest.java new file mode 100644 index 0000000000..2f913c8429 --- /dev/null +++ b/maven/src/test/java/com/baeldung/maven/it/RestIntegrationTest.java @@ -0,0 +1,24 @@ +package com.baeldung.maven.it; + +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Scanner; + +import static org.junit.Assert.assertEquals; + +public class RestIntegrationTest { + @Test + public void whenSendingGet_thenMessageIsReturned() throws IOException { + String url = "http://localhost:8999"; + URLConnection connection = new URL(url).openConnection(); + try (InputStream response = connection.getInputStream(); + Scanner scanner = new Scanner(response)) { + String responseBody = scanner.nextLine(); + assertEquals("Welcome to Baeldung!", responseBody); + } + } +} diff --git a/maven/src/test/java/com/baeldung/maven/it/RestJUnitTest.java b/maven/src/test/java/com/baeldung/maven/it/RestJUnitTest.java new file mode 100644 index 0000000000..60995d75bd --- /dev/null +++ b/maven/src/test/java/com/baeldung/maven/it/RestJUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.maven.it; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Scanner; + +import static org.junit.Assert.assertEquals; + +@Category(Integration.class) +public class RestJUnitTest { + @Test + public void whenSendingGet_thenMessageIsReturned() throws IOException { + String url = "http://localhost:8999"; + URLConnection connection = new URL(url).openConnection(); + try (InputStream response = connection.getInputStream(); + Scanner scanner = new Scanner(response)) { + String responseBody = scanner.nextLine(); + assertEquals("Welcome to Baeldung!", responseBody); + } + } +} diff --git a/maven/src/test/java/testfail/TestFail.java b/maven/src/test/java/testfail/TestFail.java new file mode 100644 index 0000000000..3febd21031 --- /dev/null +++ b/maven/src/test/java/testfail/TestFail.java @@ -0,0 +1,18 @@ +package testfail; + +import org.junit.Test; +import org.junit.Ignore; + +import static org.junit.Assert.assertNotNull; + +public class TestFail { + + @Ignore //ignored so the entire tutorials build passes + @Test + public void whenMessageAssigned_thenItIsNotNull() { + String message = "hello there"; + message = null; + assertNotNull(message); + } + +} diff --git a/maven/versions-maven-plugin/original/pom.xml b/maven/versions-maven-plugin/original/pom.xml new file mode 100644 index 0000000000..295c77b860 --- /dev/null +++ b/maven/versions-maven-plugin/original/pom.xml @@ -0,0 +1,76 @@ + + 4.0.0 + com.baeldung + versions-maven-plugin-example + 0.0.1-SNAPSHOT + + + 1.15 + + + + + + commons-io + commons-io + 2.3 + + + + org.apache.commons + commons-collections4 + 4.0 + + + + org.apache.commons + commons-lang3 + 3.0 + + + + org.apache.commons + commons-compress + ${commons-compress-version} + + + + commons-beanutils + commons-beanutils + 1.9.1-SNAPSHOT + + + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.7 + + + org.apache.commons:commons-collections4 + + + + + + + + + apache.snapshots + Apache Development Snapshot Repository + https://repository.apache.org/content/repositories/snapshots/ + + false + + + true + + + + + \ No newline at end of file diff --git a/maven/versions-maven-plugin/pom.xml b/maven/versions-maven-plugin/pom.xml new file mode 100644 index 0000000000..295c77b860 --- /dev/null +++ b/maven/versions-maven-plugin/pom.xml @@ -0,0 +1,76 @@ + + 4.0.0 + com.baeldung + versions-maven-plugin-example + 0.0.1-SNAPSHOT + + + 1.15 + + + + + + commons-io + commons-io + 2.3 + + + + org.apache.commons + commons-collections4 + 4.0 + + + + org.apache.commons + commons-lang3 + 3.0 + + + + org.apache.commons + commons-compress + ${commons-compress-version} + + + + commons-beanutils + commons-beanutils + 1.9.1-SNAPSHOT + + + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.7 + + + org.apache.commons:commons-collections4 + + + + + + + + + apache.snapshots + Apache Development Snapshot Repository + https://repository.apache.org/content/repositories/snapshots/ + + false + + + true + + + + + \ No newline at end of file diff --git a/maven/versions-maven-plugin/run-the-demo.sh b/maven/versions-maven-plugin/run-the-demo.sh new file mode 100755 index 0000000000..89ca871e01 --- /dev/null +++ b/maven/versions-maven-plugin/run-the-demo.sh @@ -0,0 +1,74 @@ +#!/bin/bash +#function to display commands +exe() { echo -e "\$ $@\n" ; "$@" ; } + +TEXT_COLOR='\033[1;33m' #Yellow +NO_COLOR='\033[0m' # No Color + +clear + +echo -e "======================================================================================" +echo -e " Showcase for the BAELDUNG tutorial \"Use the latest version of a dependency in Maven\"" +echo -e " Author: Andrea Ligios" +echo -e "======================================================================================" + +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " Resetting the demo environment (which will be altered during the run): " +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +rm -f pom.xml.versionsBackup +cp original/pom.xml pom.xml +ls -lt pom.* +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " Checking for newer versions of the Maven dependencies:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +exe mvn versions:display-dependency-updates +echo +read -p "Press enter to continue" + +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " Updating SNAPSHOT dependencies to their RELEASE version, if any:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +exe mvn versions:use-releases +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " A backup has been created automatically:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +ls -lt pom.* +echo +read -p "Press enter to continue" + +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " Updating RELEASE dependencies to their *next* RELEASE version:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +exe mvn versions:use-next-releases +echo +read -p "Press enter to continue" + +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " Reverting every modification made since the beginning:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +exe mvn versions:revert +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " The backup is gone, and the pom.xml contains the initial dependencies:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +ls -lt pom.* +echo +read -p "Press enter to continue" + +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " Updating RELEASE dependencies to their *latest* RELEASE version:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +exe mvn versions:use-latest-releases +echo +read -p "Press enter to continue" + +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " Committing the modifications to pom.xml:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +exe mvn versions:commit +echo -e "${TEXT_COLOR}\n--------------------------------------------------------------------------------------" +echo -e " The backup is gone, and the pom.xml contains the latest dependencies:" +echo -e "--------------------------------------------------------------------------------------${NO_COLOR}" +ls -lt pom.* +echo + +echo -e "${TEXT_COLOR}\nThat's all folks!${NO_COLOR}\n" diff --git a/mesos-marathon/pom.xml b/mesos-marathon/pom.xml index 77d13cd5c6..f92c00892b 100644 --- a/mesos-marathon/pom.xml +++ b/mesos-marathon/pom.xml @@ -1,6 +1,6 @@ + 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 mesos-marathon @@ -25,7 +25,6 @@ org.springframework.boot spring-boot-maven-plugin - 1.5.1.RELEASE diff --git a/mesos-marathon/src/main/resources/logback.xml b/mesos-marathon/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/mesos-marathon/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/metrics/pom.xml b/metrics/pom.xml index e3868eddef..9cf1ec588f 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 metrics @@ -84,6 +84,13 @@ spectator-api ${spectator-api.version} + + + org.assertj + assertj-core + test + + diff --git a/metrics/src/main/resources/logback.xml b/metrics/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/metrics/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java index e7f3d7ec72..689e23ad6d 100644 --- a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java +++ b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java @@ -1,8 +1,12 @@ package com.baeldung.metrics.micrometer; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.within; +import static org.assertj.core.api.Assertions.withinPercentage; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.collection.IsMapContaining.hasEntry; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import io.micrometer.atlas.AtlasMeterRegistry; @@ -31,8 +35,10 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import org.assertj.core.data.Percentage; import org.junit.Before; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import com.netflix.spectator.atlas.AtlasConfig; @@ -156,7 +162,8 @@ public class MicrometerAtlasIntegrationTest { timer.record(30, TimeUnit.MILLISECONDS); assertTrue(2 == timer.count()); - assertTrue(50 > timer.totalTime(TimeUnit.MILLISECONDS) && 45 <= timer.totalTime(TimeUnit.MILLISECONDS)); + + assertThat(timer.totalTime(TimeUnit.MILLISECONDS)).isBetween(40.0, 55.0); } @Test @@ -173,7 +180,7 @@ public class MicrometerAtlasIntegrationTest { } long timeElapsed = longTaskTimer.stop(currentTaskId); - assertTrue(timeElapsed / (int) 1e6 == 2); + assertEquals(2L, timeElapsed/((int) 1e6),1L); } @Test diff --git a/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java b/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java index 134c3c91cf..b8a5b93e49 100644 --- a/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java +++ b/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java @@ -27,6 +27,9 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; +/** + * Atlas server needs to be up and running for this live test to work. + */ public class AtlasObserverLiveTest { private final String atlasUri = "http://localhost:7101/api/v1"; diff --git a/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java b/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java index d810de155a..92bbd615b9 100644 --- a/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java +++ b/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java @@ -109,20 +109,20 @@ public class MetricTypeManualTest { .build(), MILLISECONDS); Stopwatch stopwatch = timer.start(); - MILLISECONDS.sleep(1); - timer.record(2, MILLISECONDS); + SECONDS.sleep(1); + timer.record(2, SECONDS); stopwatch.stop(); - assertEquals("timer should count 1 millisecond", 1, timer + assertEquals("timer should count 1 second", 1000, timer .getValue() - .intValue()); - assertEquals("timer should count 3 millisecond in total", 3, timer.getTotalTime() - .intValue()); + .intValue(),1000); + assertEquals("timer should count 3 second in total", 3000, timer.getTotalTime() + .intValue(),1000); assertEquals("timer should record 2 updates", 2, timer .getCount() .intValue()); - assertEquals("timer should have max 2", 2, timer.getMax(), 0.01); + assertEquals("timer should have max 2", 2000, timer.getMax(), 0.01); } @Test @@ -161,7 +161,6 @@ public class MetricTypeManualTest { } @Test - //== public void givenStatsTimer_whenExecuteTask_thenStatsCalculated() throws Exception { System.setProperty("netflix.servo", "1000"); StatsTimer timer = new StatsTimer(MonitorConfig @@ -178,21 +177,21 @@ public class MetricTypeManualTest { .build(), MILLISECONDS); Stopwatch stopwatch = timer.start(); - MILLISECONDS.sleep(1); - timer.record(3, MILLISECONDS); + SECONDS.sleep(1); + timer.record(3, SECONDS); stopwatch.stop(); stopwatch = timer.start(); - timer.record(6, MILLISECONDS); - MILLISECONDS.sleep(2); + timer.record(6, SECONDS); + SECONDS.sleep(2); stopwatch.stop(); - assertEquals("timer should count 12 milliseconds in total", 12, timer.getTotalTime()); - assertEquals("timer should count 12 milliseconds in total", 12, timer.getTotalMeasurement()); + assertEquals("timer should count 12 seconds in total", 12000, timer.getTotalTime(),500); + assertEquals("timer should count 12 seconds in total", 12000, timer.getTotalMeasurement(),500); assertEquals("timer should record 4 updates", 4, timer.getCount()); - assertEquals("stats timer value time-cost/update should be 2", 3, timer + assertEquals("stats timer value time-cost/update should be 2", 3000, timer .getValue() - .intValue()); + .intValue(),500); final Map metricMap = timer .getMonitors() @@ -235,4 +234,4 @@ public class MetricTypeManualTest { assertEquals("information collected", informational.getValue()); } -} +} \ No newline at end of file diff --git a/micronaut/.mvn/jvm.config b/micronaut/.mvn/jvm.config new file mode 100644 index 0000000000..4967c447ae --- /dev/null +++ b/micronaut/.mvn/jvm.config @@ -0,0 +1 @@ +-noverify -XX:TieredStopAtLevel=1 \ No newline at end of file diff --git a/micronaut/.mvn/wrapper/MavenWrapperDownloader.java b/micronaut/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000000..66a3132a52 --- /dev/null +++ b/micronaut/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,109 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } +} diff --git a/micronaut/.mvn/wrapper/maven-wrapper.jar b/micronaut/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000..08ebbb67f0 Binary files /dev/null and b/micronaut/.mvn/wrapper/maven-wrapper.jar differ diff --git a/micronaut/.mvn/wrapper/maven-wrapper.properties b/micronaut/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..42fa4da219 --- /dev/null +++ b/micronaut/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip \ No newline at end of file diff --git a/micronaut/Dockerfile b/micronaut/Dockerfile new file mode 100644 index 0000000000..ed4be82e8e --- /dev/null +++ b/micronaut/Dockerfile @@ -0,0 +1,4 @@ +FROM java:openjdk-8u111-alpine +RUN apk --no-cache add curl +COPY build/libs/*-all.jar hello-world-server.jar +CMD java ${JAVA_OPTS} -jar hello-world-server.jar \ No newline at end of file diff --git a/micronaut/README.md b/micronaut/README.md new file mode 100644 index 0000000000..10a68ff2f8 --- /dev/null +++ b/micronaut/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to Micronaut Framework](http://www.baeldung.com/micronaut) diff --git a/micronaut/micronaut-cli.yml b/micronaut/micronaut-cli.yml new file mode 100644 index 0000000000..fe56560074 --- /dev/null +++ b/micronaut/micronaut-cli.yml @@ -0,0 +1,5 @@ +profile: service +defaultPackage: hello.world.server +--- +testFramework: junit +sourceLanguage: java \ No newline at end of file diff --git a/micronaut/mvnw b/micronaut/mvnw new file mode 100755 index 0000000000..961a825001 --- /dev/null +++ b/micronaut/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/micronaut/mvnw.cmd b/micronaut/mvnw.cmd new file mode 100755 index 0000000000..03d90e960b --- /dev/null +++ b/micronaut/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.0/maven-wrapper-0.4.0.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/micronaut/pom.xml b/micronaut/pom.xml new file mode 100644 index 0000000000..7b722306b6 --- /dev/null +++ b/micronaut/pom.xml @@ -0,0 +1,141 @@ + + 4.0.0 + com.baeldung.micronaut + micronaut + 0.1 + micronaut + + + com.baeldung.micronaut.helloworld.server.ServerApplication + 1.0.0.M2 + 9 + + + + jcenter.bintray.com + http://jcenter.bintray.com + + + + + + io.micronaut + bom + ${micronaut.version} + pom + import + + + + + + io.micronaut + http-client + compile + + + io.micronaut + http-server-netty + compile + + + io.micronaut + inject + compile + + + io.micronaut + runtime + compile + + + javax.annotation + javax.annotation-api + 1.3.2 + compile + + + io.micronaut + inject-java + provided + + + ch.qos.logback + logback-classic + 1.2.3 + runtime + + + junit + junit + 4.12 + test + + + io.projectreactor + reactor-core + 3.1.6.RELEASE + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + + + ${exec.mainClass} + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + java + + -classpath + + ${exec.mainClass} + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + ${jdk.version} + ${jdk.version} + + -parameters + + + + io.micronaut + inject-java + ${micronaut.version} + + + + + + + + diff --git a/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java new file mode 100644 index 0000000000..d4051cef52 --- /dev/null +++ b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClient.java @@ -0,0 +1,28 @@ +package com.baeldung.micronaut.helloworld.client; + +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.Client; +import io.micronaut.http.client.RxHttpClient; +import io.reactivex.Single; + +import javax.inject.Singleton; + +@Singleton +public class ConcreteGreetingClient +{ + private RxHttpClient httpClient; + + public ConcreteGreetingClient(@Client("/") RxHttpClient httpClient) { + this.httpClient = httpClient; + } + + public String greet(String name) { + HttpRequest req = HttpRequest.GET("/greet/" + name); + return httpClient.retrieve(req).blockingFirst(); + } + + public Single greetAsync(String name) { + HttpRequest req = HttpRequest.GET("/async/greet/" + name); + return httpClient.retrieve(req).first("An error as occurred"); + } +} diff --git a/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/GreetingClient.java b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/GreetingClient.java new file mode 100644 index 0000000000..8a691d5b06 --- /dev/null +++ b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/client/GreetingClient.java @@ -0,0 +1,14 @@ +package com.baeldung.micronaut.helloworld.client; + +import io.micronaut.http.annotation.Get; +import io.micronaut.http.client.Client; +import io.micronaut.http.client.RxHttpClient; + +import javax.inject.Inject; + +@Client("/greet") +public interface GreetingClient { + + @Get("/{name}") + String greet(String name); +} diff --git a/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/ServerApplication.java b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/ServerApplication.java new file mode 100644 index 0000000000..c5936051dd --- /dev/null +++ b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/ServerApplication.java @@ -0,0 +1,10 @@ +package com.baeldung.micronaut.helloworld.server; + +import io.micronaut.runtime.Micronaut; + +public class ServerApplication { + + public static void main(String[] args) { + Micronaut.run(ServerApplication.class); + } +} \ No newline at end of file diff --git a/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java new file mode 100644 index 0000000000..4d86b9dfed --- /dev/null +++ b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/AsyncGreetController.java @@ -0,0 +1,20 @@ +package com.baeldung.micronaut.helloworld.server.controller; + +import com.baeldung.micronaut.helloworld.server.service.GreetingService; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.reactivex.Single; + +import javax.inject.Inject; + +@Controller("/async/greet") +public class AsyncGreetController { + + @Inject + private GreetingService greetingService; + + @Get("/{name}") + public Single greet(String name) { + return Single.just(greetingService.getGreeting() + name); + } +} diff --git a/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java new file mode 100644 index 0000000000..c890c037e4 --- /dev/null +++ b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/controller/GreetController.java @@ -0,0 +1,28 @@ +package com.baeldung.micronaut.helloworld.server.controller; + +import com.baeldung.micronaut.helloworld.server.service.GreetingService; +import io.micronaut.http.MediaType; +import io.micronaut.http.annotation.Body; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Post; + +import javax.inject.Inject; + +@Controller("/greet") +public class GreetController { + + @Inject + private GreetingService greetingService; + + @Get("/{name}") + public String greet(String name) { + return greetingService.getGreeting() + name; + } + + @Post(value = "/{name}", consumes = MediaType.TEXT_PLAIN) + public String setGreeting(@Body String name) + { + return greetingService.getGreeting() + name; + } +} diff --git a/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java new file mode 100644 index 0000000000..8ea5172cf6 --- /dev/null +++ b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/EnglishGreetingService.java @@ -0,0 +1,14 @@ +package com.baeldung.micronaut.helloworld.server.service; + +import io.micronaut.context.annotation.Primary; + +import javax.inject.Singleton; + +@Primary +@Singleton +public class EnglishGreetingService implements GreetingService { + @Override + public String getGreeting() { + return "Hello "; + } +} diff --git a/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/GreetingService.java b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/GreetingService.java new file mode 100644 index 0000000000..6e28baaebe --- /dev/null +++ b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/GreetingService.java @@ -0,0 +1,6 @@ +package com.baeldung.micronaut.helloworld.server.service; + +public interface GreetingService { + + String getGreeting(); +} diff --git a/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java new file mode 100644 index 0000000000..1ec53d8b2d --- /dev/null +++ b/micronaut/src/main/java/com/baeldung/micronaut/helloworld/server/service/SpanishGreetingService.java @@ -0,0 +1,11 @@ +package com.baeldung.micronaut.helloworld.server.service; + +import javax.inject.Singleton; + +@Singleton +public class SpanishGreetingService implements GreetingService { + @Override + public String getGreeting() { + return "Hola "; + } +} diff --git a/micronaut/src/main/resources/application.yml b/micronaut/src/main/resources/application.yml new file mode 100644 index 0000000000..4119026dd6 --- /dev/null +++ b/micronaut/src/main/resources/application.yml @@ -0,0 +1,5 @@ +micronaut: + application: + name: hello-world-server + server: + port: 9080 \ No newline at end of file diff --git a/micronaut/src/main/resources/logback.xml b/micronaut/src/main/resources/logback.xml new file mode 100644 index 0000000000..afaebf8e17 --- /dev/null +++ b/micronaut/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientTest.java b/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientTest.java new file mode 100644 index 0000000000..c8c1d6b12a --- /dev/null +++ b/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/ConcreteGreetingClientTest.java @@ -0,0 +1,38 @@ +package com.baeldung.micronaut.helloworld.client; + +import io.micronaut.context.ApplicationContext; +import io.micronaut.runtime.server.EmbeddedServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; + +public class ConcreteGreetingClientTest +{ + private EmbeddedServer server; + private ConcreteGreetingClient client; + + @Before + public void setup() + { + server = ApplicationContext.run(EmbeddedServer.class); + client = server.getApplicationContext().getBean(ConcreteGreetingClient.class); + } + + @After + public void cleanup() + { + server.stop(); + } + + @Test + public void testGreeting() { + assertEquals(client.greet("Mike"), "Hello Mike"); + } + + @Test + public void testGreetingAsync() { + assertEquals(client.greetAsync("Mike").blockingGet(), "Hello Mike"); + } +} diff --git a/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientTest.java b/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientTest.java new file mode 100644 index 0000000000..0f2ca460ac --- /dev/null +++ b/micronaut/src/test/java/com/baeldung/micronaut/helloworld/client/GreetingClientTest.java @@ -0,0 +1,32 @@ +package com.baeldung.micronaut.helloworld.client; + +import io.micronaut.context.ApplicationContext; +import io.micronaut.runtime.server.EmbeddedServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; + +public class GreetingClientTest { + private EmbeddedServer server; + private GreetingClient client; + + @Before + public void setup() + { + server = ApplicationContext.run(EmbeddedServer.class); + client = server.getApplicationContext().getBean(GreetingClient.class); + } + + @After + public void cleanup() + { + server.stop(); + } + + @Test + public void testGreeting() { + assertEquals(client.greet("Mike"), "Hello Mike"); + } +} diff --git a/microprofile/pom.xml b/microprofile/pom.xml index 27d234b73a..d75b6443ed 100644 --- a/microprofile/pom.xml +++ b/microprofile/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung microprofile @@ -80,8 +79,6 @@ - UTF-8 - UTF-8 library ${project.build.directory}/${app.name}-service.jar runnable diff --git a/microprofile/src/main/resources/logback.xml b/microprofile/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/microprofile/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/msf4j/pom.xml b/msf4j/pom.xml index f691d746b7..9a6483772b 100644 --- a/msf4j/pom.xml +++ b/msf4j/pom.xml @@ -1,32 +1,43 @@ - + + 4.0.0 + com.baeldung.msf4j + msf4j + 0.0.1-SNAPSHOT - org.wso2.msf4j - msf4j-service - 2.6.0 + parent-modules + com.baeldung + 1.0.0-SNAPSHOT - 4.0.0 - com.baeldung.msf4j - msf4j - 0.0.1-SNAPSHOT - WSO2 MSF4J Microservice + + + + org.wso2.msf4j + msf4j-service + ${msf4j.version} + pom + + + + + + org.wso2.msf4j + msf4j-spring + ${msf4j.version} + + + org.wso2.msf4j + msf4j-mustache-template + ${msf4j.version} + + - - com.baeldung.msf4j.msf4jintro.Application - - - - org.wso2.msf4j - msf4j-spring - 2.6.1 - - - org.wso2.msf4j - msf4j-mustache-template - 2.6.1 - - + + com.baeldung.msf4j.msf4jintro.Application + 2.6.3 + \ No newline at end of file diff --git a/msf4j/src/main/resources/logback.xml b/msf4j/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/msf4j/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/muleesb/pom.xml b/muleesb/pom.xml index a3b9869eb4..b34123567a 100644 --- a/muleesb/pom.xml +++ b/muleesb/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 com.mycompany @@ -14,94 +15,6 @@ 1.0.0-SNAPSHOT - - - - org.mule.tools.maven - mule-app-maven-plugin - ${mule.tools.version} - true - - true - - - - org.mule.tools - muleesb-maven-plugin - 1.0 - - 3.7.0 - /home/abir/AnypointStudio/workspace/variablescopetest - - - - deploy - - start - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - add-resource - generate-resources - - add-resource - - - - - src/main/app/ - - - mappings/ - - - src/main/api/ - - - - - - - - com.mulesoft.munit.tools - munit-maven-plugin - ${munit.version} - - - test - test - - test - - - - - - true - - html - - - - - - - - src/test/munit - - - src/test/resources - - - - @@ -182,6 +95,94 @@ + + + + org.mule.tools.maven + mule-app-maven-plugin + ${mule.tools.version} + true + + true + + + + org.mule.tools + muleesb-maven-plugin + ${muleesb-maven-plugin.version} + + ${mule.version} + /home/abir/AnypointStudio/workspace/variablescopetest + + + + deploy + + start + + + + + + org.codehaus.mojo + build-helper-maven-plugin + ${build-helper-maven-plugin.version} + + + add-resource + generate-resources + + add-resource + + + + + src/main/app/ + + + mappings/ + + + src/main/api/ + + + + + + + + com.mulesoft.munit.tools + munit-maven-plugin + ${munit.version} + + + test + test + + test + + + + + + true + + html + + + + + + + + src/test/munit + + + src/test/resources + + + + Central @@ -210,12 +211,12 @@ - UTF-8 - UTF-8 3.8.1 1.2 1.3.6 3.9.0 + 1.0 + 1.7 diff --git a/mustache/pom.xml b/mustache/pom.xml index 40fcecc4f8..a276dfbf43 100644 --- a/mustache/pom.xml +++ b/mustache/pom.xml @@ -1,18 +1,16 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 mustache - 0.0.1-SNAPSHOT jar mustache - org.springframework.boot - spring-boot-starter-parent - 1.5.4.RELEASE - - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 @@ -25,10 +23,8 @@ org.assertj assertj-core - ${assertj.version} - log4j log4j @@ -56,13 +52,6 @@ ${datafactory.version} - - junit - junit - ${junit.version} - test - - @@ -74,90 +63,13 @@ - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*LiveTest.java - **/AutoconfigurationTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - - - json - - - - - - - - autoconfiguration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*LiveTest.java - **/*IntegrationTest.java - **/*IntTest.java - - - **/AutoconfigurationTest.java - - - - - - - json - - - - - - - - 0.9.2 - 3.7.0 1.2.16 - 4.12 - UTF-8 - 3.7.0 - 2.19.1 0.8 3.3.7 - 1.8 \ No newline at end of file diff --git a/mustache/src/main/resources/logback.xml b/mustache/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/mustache/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/mvn-wrapper/pom.xml b/mvn-wrapper/pom.xml index e26df81139..7f45fe218d 100644 --- a/mvn-wrapper/pom.xml +++ b/mvn-wrapper/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 mvn-wrapper 0.0.1-SNAPSHOT @@ -35,9 +35,4 @@ - - UTF-8 - UTF-8 - - diff --git a/mvn-wrapper/src/main/resources/logback.xml b/mvn-wrapper/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/mvn-wrapper/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/mybatis/pom.xml b/mybatis/pom.xml index b167d94ed8..aa9ff9e288 100644 --- a/mybatis/pom.xml +++ b/mybatis/pom.xml @@ -1,6 +1,6 @@ + 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 mybatis diff --git a/mybatis/src/main/resources/logback.xml b/mybatis/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/mybatis/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/noexception/pom.xml b/noexception/pom.xml index c825449452..f632f1e3a9 100644 --- a/noexception/pom.xml +++ b/noexception/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung noexception diff --git a/noexception/src/main/resources/logback.xml b/noexception/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/noexception/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/optaplanner/README.md b/optaplanner/README.md new file mode 100644 index 0000000000..1568a615c0 --- /dev/null +++ b/optaplanner/README.md @@ -0,0 +1,3 @@ +### Relevant articles + +- [A Guide to OptaPlanner](https://www.baeldung.com/opta-planner) diff --git a/optaplanner/pom.xml b/optaplanner/pom.xml new file mode 100644 index 0000000000..22abbedc8c --- /dev/null +++ b/optaplanner/pom.xml @@ -0,0 +1,27 @@ + + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + 4.0.0 + + optaplanner + + + + org.optaplanner + optaplanner-core + 7.9.0.Final + + + + + + + + + \ No newline at end of file diff --git a/optaplanner/src/main/java/com/baeldung/optaplanner/CourseSchedule.java b/optaplanner/src/main/java/com/baeldung/optaplanner/CourseSchedule.java new file mode 100644 index 0000000000..8a820ab56e --- /dev/null +++ b/optaplanner/src/main/java/com/baeldung/optaplanner/CourseSchedule.java @@ -0,0 +1,63 @@ +package com.baeldung.optaplanner; + +import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty; +import org.optaplanner.core.api.domain.solution.PlanningScore; +import org.optaplanner.core.api.domain.solution.PlanningSolution; +import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty; +import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider; +import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +@PlanningSolution +public class CourseSchedule { + + Logger logger = LoggerFactory.getLogger("CourseSchedule"); + + private List roomList; + private List periodList; + private List lectureList; + private HardSoftScore score; + + public CourseSchedule(){ + roomList = new ArrayList<>(); + periodList = new ArrayList<>(); + lectureList = new ArrayList<>(); + } + + @ValueRangeProvider(id = "availableRooms") + @ProblemFactCollectionProperty + public List getRoomList() { + return roomList; + } + + @ValueRangeProvider(id = "availablePeriods") + @ProblemFactCollectionProperty + public List getPeriodList() { + return periodList; + } + + @PlanningEntityCollectionProperty + public List getLectureList() { + return lectureList; + } + + @PlanningScore + public HardSoftScore getScore() { + return score; + } + + public void setScore(HardSoftScore score) { + this.score = score; + } + + public void printCourseSchedule() { + lectureList.stream() + .map(c -> "Lecture in Room " + c.getRoomNumber().toString() + " during Period " + c.getPeriod().toString()) + .forEach(k -> logger.info(k)); + } + +} diff --git a/optaplanner/src/main/java/com/baeldung/optaplanner/Lecture.java b/optaplanner/src/main/java/com/baeldung/optaplanner/Lecture.java new file mode 100644 index 0000000000..48af4e89d1 --- /dev/null +++ b/optaplanner/src/main/java/com/baeldung/optaplanner/Lecture.java @@ -0,0 +1,30 @@ +package com.baeldung.optaplanner; + +import org.optaplanner.core.api.domain.entity.PlanningEntity; +import org.optaplanner.core.api.domain.variable.PlanningVariable; + +@PlanningEntity +public class Lecture { + + private Integer roomNumber; + private Integer period; + + @PlanningVariable(valueRangeProviderRefs = {"availablePeriods"}) + public Integer getPeriod() { + return period; + } + + @PlanningVariable(valueRangeProviderRefs = {"availableRooms"}) + public Integer getRoomNumber() { + return roomNumber; + } + + public void setPeriod(Integer period) { + this.period = period; + } + + public void setRoomNumber(Integer roomNumber) { + this.roomNumber = roomNumber; + } + +} diff --git a/optaplanner/src/main/java/com/baeldung/optaplanner/ScoreCalculator.java b/optaplanner/src/main/java/com/baeldung/optaplanner/ScoreCalculator.java new file mode 100644 index 0000000000..11e5e4a5be --- /dev/null +++ b/optaplanner/src/main/java/com/baeldung/optaplanner/ScoreCalculator.java @@ -0,0 +1,32 @@ +package com.baeldung.optaplanner; + +import org.optaplanner.core.api.score.Score; +import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; +import org.optaplanner.core.impl.score.director.easy.EasyScoreCalculator; + +import java.util.HashSet; + +public class ScoreCalculator implements EasyScoreCalculator { + + @Override + public Score calculateScore(CourseSchedule courseSchedule) { + int hardScore = 0; + int softScore = 0; + + HashSet occupiedRooms = new HashSet<>(); + for (Lecture lecture : courseSchedule.getLectureList()) { + if(lecture.getPeriod() != null && lecture.getRoomNumber() != null) { + String roomInUse = lecture.getPeriod().toString() + ":" + lecture.getRoomNumber().toString(); + if (occupiedRooms.contains(roomInUse)) { + hardScore += -1; + } else { + occupiedRooms.add(roomInUse); + } + } else { + hardScore += -1; + } + } + + return HardSoftScore.valueOf(hardScore, softScore); + } +} diff --git a/optaplanner/src/main/resources/courseSchedule.drl b/optaplanner/src/main/resources/courseSchedule.drl new file mode 100644 index 0000000000..9372a24976 --- /dev/null +++ b/optaplanner/src/main/resources/courseSchedule.drl @@ -0,0 +1,14 @@ +package com.baeldung.optaplanner + +import com.baeldung.optaplanner.Lecture; +import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder; + +global HardSoftScoreHolder scoreHolder; + +rule "noNullRoomPeriod" + when + Lecture( roomNumber == null ); + Lecture( period == null ); + then + scoreHolder.addHardConstraintMatch(kcontext, -1); +end \ No newline at end of file diff --git a/optaplanner/src/main/resources/courseScheduleSolverConfigDrools.xml b/optaplanner/src/main/resources/courseScheduleSolverConfigDrools.xml new file mode 100644 index 0000000000..7cf95fdcd3 --- /dev/null +++ b/optaplanner/src/main/resources/courseScheduleSolverConfigDrools.xml @@ -0,0 +1,12 @@ + + + + + + courseSchedule.drl + + + + 10 + + \ No newline at end of file diff --git a/optaplanner/src/main/resources/courseScheduleSolverConfiguration.xml b/optaplanner/src/main/resources/courseScheduleSolverConfiguration.xml new file mode 100644 index 0000000000..0ad2264dcd --- /dev/null +++ b/optaplanner/src/main/resources/courseScheduleSolverConfiguration.xml @@ -0,0 +1,12 @@ + + + + + + com.baeldung.optaplanner.ScoreCalculator + + + + 10 + + \ No newline at end of file diff --git a/optaplanner/src/main/resources/logback.xml b/optaplanner/src/main/resources/logback.xml new file mode 100644 index 0000000000..c109aa19e2 --- /dev/null +++ b/optaplanner/src/main/resources/logback.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/optaplanner/src/test/java/com/baeldung/optaplanner/test/OptaPlannerUnitTest.java b/optaplanner/src/test/java/com/baeldung/optaplanner/test/OptaPlannerUnitTest.java new file mode 100644 index 0000000000..2847a233a5 --- /dev/null +++ b/optaplanner/src/test/java/com/baeldung/optaplanner/test/OptaPlannerUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.optaplanner.test; + +import com.baeldung.optaplanner.CourseSchedule; +import com.baeldung.optaplanner.Lecture; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.optaplanner.core.api.solver.Solver; +import org.optaplanner.core.api.solver.SolverFactory; +import java.util.Arrays; + +public class OptaPlannerUnitTest { + + static CourseSchedule unsolvedCourseSchedule; + + @BeforeAll + public static void setUp() { + + unsolvedCourseSchedule = new CourseSchedule(); + + for(int i = 0; i < 10; i++){ + unsolvedCourseSchedule.getLectureList().add(new Lecture()); + } + + unsolvedCourseSchedule.getPeriodList().addAll(Arrays.asList(new Integer[] { 1, 2, 3 })); + unsolvedCourseSchedule.getRoomList().addAll(Arrays.asList(new Integer[] { 1, 2 })); + } + + @Test + public void test_whenCustomJavaSolver() { + + SolverFactory solverFactory = SolverFactory.createFromXmlResource("courseScheduleSolverConfiguration.xml"); + Solver solver = solverFactory.buildSolver(); + CourseSchedule solvedCourseSchedule = solver.solve(unsolvedCourseSchedule); + + Assert.assertNotNull(solvedCourseSchedule.getScore()); + Assert.assertEquals(-4, solvedCourseSchedule.getScore().getHardScore()); + } + + @Test + public void test_whenDroolsSolver() { + + SolverFactory solverFactory = SolverFactory.createFromXmlResource("courseScheduleSolverConfigDrools.xml"); + Solver solver = solverFactory.buildSolver(); + CourseSchedule solvedCourseSchedule = solver.solve(unsolvedCourseSchedule); + + Assert.assertNotNull(solvedCourseSchedule.getScore()); + Assert.assertEquals(0, solvedCourseSchedule.getScore().getHardScore()); + } +} diff --git a/orientdb/pom.xml b/orientdb/pom.xml index 317c469005..e1c7ac42bb 100644 --- a/orientdb/pom.xml +++ b/orientdb/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 orientdb 0.0.1-SNAPSHOT @@ -36,22 +36,11 @@ ${blueprints.version} - - junit - junit - ${junit.version} - test - - - + - UTF-8 - UTF-8 - 1.8 2.2.31 2.6.0 - 4.12 diff --git a/orientdb/src/main/resources/logback.xml b/orientdb/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/orientdb/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/orika/pom.xml b/orika/pom.xml index 1a54440ffe..e4da5955bf 100644 --- a/orika/pom.xml +++ b/orika/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung orika diff --git a/orika/src/main/resources/logback.xml b/orika/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/orika/src/main/resources/logback.xml +++ b/orika/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/osgi/osgi-intro-sample-activator/pom.xml b/osgi/osgi-intro-sample-activator/pom.xml index 1584913627..77d7198698 100644 --- a/osgi/osgi-intro-sample-activator/pom.xml +++ b/osgi/osgi-intro-sample-activator/pom.xml @@ -1,20 +1,17 @@ - + + 4.0.0 + + bundle + osgi-intro-sample-activator - osgi-intro + osgi com.baeldung 1.0-SNAPSHOT - 4.0.0 - - - bundle - - osgi-intro-sample-activator @@ -38,11 +35,8 @@ com.baeldung.osgi.sample.activator.HelloWorld - + com.baeldung.osgi.sample.activator diff --git a/osgi/osgi-intro-sample-activator/src/main/resources/logback.xml b/osgi/osgi-intro-sample-activator/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/osgi/osgi-intro-sample-activator/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/osgi/osgi-intro-sample-client/pom.xml b/osgi/osgi-intro-sample-client/pom.xml index 4096674d7d..7f5faedb30 100644 --- a/osgi/osgi-intro-sample-client/pom.xml +++ b/osgi/osgi-intro-sample-client/pom.xml @@ -2,23 +2,22 @@ + 4.0.0 + + osgi-intro-sample-client + bundle + - osgi-intro + osgi com.baeldung 1.0-SNAPSHOT - 4.0.0 - - - osgi-intro-sample-client - - bundle com.baeldung osgi-intro-sample-service - 1.0-SNAPSHOT + ${osgi-intro-sample-service.version} org.osgi @@ -46,4 +45,7 @@ + + 1.0-SNAPSHOT + \ No newline at end of file diff --git a/osgi/osgi-intro-sample-client/src/main/resources/logback.xml b/osgi/osgi-intro-sample-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/osgi/osgi-intro-sample-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/osgi/osgi-intro-sample-service/pom.xml b/osgi/osgi-intro-sample-service/pom.xml index cbc660bb74..8f81645ad4 100644 --- a/osgi/osgi-intro-sample-service/pom.xml +++ b/osgi/osgi-intro-sample-service/pom.xml @@ -1,20 +1,17 @@ - + + 4.0.0 + osgi-intro-sample-service + + bundle - osgi-intro + osgi com.baeldung 1.0-SNAPSHOT - 4.0.0 - - osgi-intro-sample-service - - - bundle diff --git a/osgi/osgi-intro-sample-service/src/main/resources/logback.xml b/osgi/osgi-intro-sample-service/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/osgi/osgi-intro-sample-service/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/osgi/pom.xml b/osgi/pom.xml index 704a738d24..9ebcb09091 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -1,11 +1,11 @@ - + 4.0.0 - osgi-intro + osgi pom 1.0-SNAPSHOT + osgi com.baeldung @@ -45,22 +45,22 @@ com.squareup.okhttp3 okhttp - 3.9.0 + ${okhttp.version} javax.json javax.json-api - 1.1 + ${javax.json.version} org.glassfish javax.json - 1.1 + ${javax.json.version} org.osgi org.osgi.core - 6.0.0 + ${osgi.version} provided @@ -72,11 +72,18 @@ org.apache.felix maven-bundle-plugin - 3.3.0 + ${maven-bundle-plugin.version} true + + 3.9.0 + 1.1 + 6.0.0 + 3.3.0 + + \ No newline at end of file diff --git a/out/production/generated-sources8/src.main.resources.reladomo.ReladomoClassList.xml.log b/out/production/generated-sources8/src.main.resources.reladomo.ReladomoClassList.xml.log deleted file mode 100644 index 0bd4e29a45..0000000000 --- a/out/production/generated-sources8/src.main.resources.reladomo.ReladomoClassList.xml.log +++ /dev/null @@ -1,2 +0,0 @@ -f5a6ba3b942a82fcbfb72e61502d5c30 -9201deea diff --git a/out/production/introduction/views/index.scala.html b/out/production/introduction/views/index.scala.html deleted file mode 100644 index 4539f5a10b..0000000000 --- a/out/production/introduction/views/index.scala.html +++ /dev/null @@ -1,20 +0,0 @@ -@* - * This template takes a single argument, a String containing a - * message to display. - *@ -@(message: String) - -@* - * Call the `main` template with two arguments. The first - * argument is a `String` with the title of the page, the second - * argument is an `Html` object containing the body of the page. - *@ -@main("Welcome to Play") { - - @* - * Get an `Html` object by calling the built-in Play welcome - * template and passing a `String` message. - *@ - @play20.welcome(message, style = "Java") - -} diff --git a/out/production/introduction/views/main.scala.html b/out/production/introduction/views/main.scala.html deleted file mode 100644 index 9414f4be6e..0000000000 --- a/out/production/introduction/views/main.scala.html +++ /dev/null @@ -1,23 +0,0 @@ -@* - * This template is called from the `index` template. This template - * handles the rendering of the page header and body tags. It takes - * two arguments, a `String` for the title of the page and an `Html` - * object to insert into the body of the page. - *@ -@(title: String)(content: Html) - - - - - @* Here's where we render the page title `String`. *@ - @title - - - - - - @* And here's where we render the `Html` object containing - * the page content. *@ - @content - - diff --git a/out/production/main/com/baeldung/.gitignore b/out/production/main/com/baeldung/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/out/production/main/com/baeldung/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/out/production/main151/com/baeldung/README.md b/out/production/main/com/baeldung/README.md similarity index 100% rename from out/production/main151/com/baeldung/README.md rename to out/production/main/com/baeldung/README.md diff --git a/out/production/main330/com/baeldung/enums/README.md b/out/production/main/com/baeldung/enums/README.md similarity index 100% rename from out/production/main330/com/baeldung/enums/README.md rename to out/production/main/com/baeldung/enums/README.md diff --git a/out/production/main330/com/baeldung/networking/README.md b/out/production/main/com/baeldung/networking/README.md similarity index 100% rename from out/production/main330/com/baeldung/networking/README.md rename to out/production/main/com/baeldung/networking/README.md diff --git a/out/production/main/com/baeldung/objectsize/MANIFEST.MF b/out/production/main/com/baeldung/objectsize/MANIFEST.MF new file mode 100644 index 0000000000..b814f624d0 --- /dev/null +++ b/out/production/main/com/baeldung/objectsize/MANIFEST.MF @@ -0,0 +1 @@ +Premain-class: com.baeldung.objectsize.InstrumentationAgent diff --git a/out/production/main330/com/baeldung/printscreen/README.md b/out/production/main/com/baeldung/printscreen/README.md similarity index 100% rename from out/production/main330/com/baeldung/printscreen/README.md rename to out/production/main/com/baeldung/printscreen/README.md diff --git a/out/production/main/javac-args/arguments b/out/production/main/javac-args/arguments new file mode 100644 index 0000000000..51639800a7 --- /dev/null +++ b/out/production/main/javac-args/arguments @@ -0,0 +1,2 @@ +-d javac-target -verbose +com/baeldung/javac/Data.java \ No newline at end of file diff --git a/out/production/main/javac-args/options b/out/production/main/javac-args/options new file mode 100644 index 0000000000..f02f2344ff --- /dev/null +++ b/out/production/main/javac-args/options @@ -0,0 +1,2 @@ +-d javac-target +-verbose \ No newline at end of file diff --git a/out/production/main/javac-args/types b/out/production/main/javac-args/types new file mode 100644 index 0000000000..ef2d861f84 --- /dev/null +++ b/out/production/main/javac-args/types @@ -0,0 +1 @@ +com/baeldung/javac/Data.java \ No newline at end of file diff --git a/out/production/main/javac-args/xlint-ops b/out/production/main/javac-args/xlint-ops new file mode 100644 index 0000000000..cdccbc0cce --- /dev/null +++ b/out/production/main/javac-args/xlint-ops @@ -0,0 +1,3 @@ +-d javac-target +-Xlint:rawtypes,unchecked,static,cast,serial,fallthrough +com/baeldung/javac/Data.java \ No newline at end of file diff --git a/out/production/main173/log4j.properties b/out/production/main/log4j.properties similarity index 100% rename from out/production/main173/log4j.properties rename to out/production/main/log4j.properties diff --git a/out/production/main237/com/baeldung/datetime/README.md b/out/production/main1/com/baeldung/datetime/README.md similarity index 100% rename from out/production/main237/com/baeldung/datetime/README.md rename to out/production/main1/com/baeldung/datetime/README.md diff --git a/out/production/main155/com/baeldung/git/README.md b/out/production/main155/com/baeldung/git/README.md deleted file mode 100644 index 7e6a597c28..0000000000 --- a/out/production/main155/com/baeldung/git/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [Injecting Git Information Into Spring](http://www.baeldung.com/spring-git-information) diff --git a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt b/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt deleted file mode 100644 index bffe24e485..0000000000 --- a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt +++ /dev/null @@ -1,76 +0,0 @@ -About the application ---------------------- -This application demonstrates the usage of JavaEE Web Annotations. - - -Contents of the application ---------------------------- -1. AccountServlet.java - Demonstrates the @WebServlet and @ServletSecurity annotation. - -NOTES: @WebServlet annotation designates the AccountServlet class as a Servlet component. - The usage of its parameters 'urlPatterns' & 'initParams' can be observed. - An initialization parameter 'type' is being set to denote the type of the bank account. - - @ServletSecurity annotation imposes security constraints on the AccountServlet based on - the tomcat-users.xml. -   - This code assumes that your tomcat-users.xml looks as follows: - - - - - - - -   -N.B : To see @ServletSecurity annotation in action, please uncomment the annotation code - for @ServletSecurity. - - -2. BankAppServletContextListener.java - Demonstrates the @WebListener annotation for denoting a class as a ServletContextListener. - -NOTES: Sets a Servlet context attribute ATTR_DEFAULT_LANGUAGE to 'english' on web application start up, - which can then be used throughout the application. - - -3. LogInFilter.java - Demonstrates the @WebFilter annotation. - -NOTES: @WebFilter annotation designates the LogInFilter class as a Filter component. - It filters all requests to the bank account servlet and redirects them to - the login page. - -N.B : To see @WebFilter annotation in action, please uncomment the annotation code for @WebFilter. - - -4. UploadCustomerDocumentsServlet.java - Demonstrates the @MultipartConfig annotation. - -NOTES: @MultipartConfig anotation designates the UploadCustomerDocumentsServlet Servlet component, - to handle multipart/form-data requests. - To see it in action, deploy the web application an access the url: http://:/JavaEEAnnotationsSample/upload.jsp - Once you upload a file from here, it will get uploaded to D:/custDocs (assuming such a folder exists). - - -5. index.jsp - This is the welcome page. - -NOTES: You can enter a deposit amount here and click on the 'Deposit' button to see the AccountServlet in action. - -6. login.jsp - All requests to the AccountServlet are redirected to this page, if the LogInFilter is imposed. - -7. upload.jsp - Demonstrates the usage of handling multipart/form-data requests by the UploadCustomerDocumentsServlet. - - -Building and Running the application ------------------------------------- -To build the application: - -1. Open the project in eclipse -2. Right click on it in eclispe and choose Run As > Maven build -3. Give 'clean install' under Goals -4. This should build the WAR file of the application - -To run the application: - -1. Right click on the project -2. Run as > Run on Server -3. This will start you Tomcat server and deploy the application (Provided that you have configured Tomcat in your eclipse) -4. You should now be able to access the url : http://:/JavaEEAnnotationsSample diff --git a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml b/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml deleted file mode 100644 index 2835f6f416..0000000000 --- a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml +++ /dev/null @@ -1,48 +0,0 @@ - - 4.0.0 - com.baeldung.javaeeannotations - JavaEEAnnotationsSample - 0.0.1-SNAPSHOT - war - JavaEEAnnotationsSample - JavaEEAnnotationsSample - - - - - javax.annotation - javax.annotation-api - 1.3 - - - - javax.servlet - javax.servlet-api - 3.1.0 - - - - javax.servlet.jsp - jsp-api - 2.1 - - - - - - - - org.apache.maven.plugins - maven-war-plugin - 2.4 - - src/main/webapp - SpringFieldConstructorInjection - false - - - - - JavaEEAnnotationsSample - - \ No newline at end of file diff --git a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml b/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index a92885ec11..0000000000 --- a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - BASIC - default - - diff --git a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/index.jsp b/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/index.jsp deleted file mode 100644 index c49dec859e..0000000000 --- a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/index.jsp +++ /dev/null @@ -1,16 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> - - - - -My Account - - -
    - Amount: -    - -
    - - \ No newline at end of file diff --git a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp b/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp deleted file mode 100644 index 6892cb0420..0000000000 --- a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp +++ /dev/null @@ -1,12 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" - pageEncoding="ISO-8859-1"%> - - - - -Login - - -Login Here... - - \ No newline at end of file diff --git a/out/production/main180/com/baeldung/jaxws/wsdl/employeeservicetopdown.wsdl b/out/production/main180/com/baeldung/jaxws/wsdl/employeeservicetopdown.wsdl deleted file mode 100644 index 426717f90e..0000000000 --- a/out/production/main180/com/baeldung/jaxws/wsdl/employeeservicetopdown.wsdl +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/out/production/main195/com/baeldung/java/nio/selector/README.md b/out/production/main195/com/baeldung/java/nio/selector/README.md deleted file mode 100644 index b28aae1397..0000000000 --- a/out/production/main195/com/baeldung/java/nio/selector/README.md +++ /dev/null @@ -1,2 +0,0 @@ -###Relevant Articles: -- [Introduction to the Java NIO Selector](http://www.baeldung.com/java-nio-selector) diff --git a/out/production/main216/com/baeldung/googlehttpclientguide/logging.properties b/out/production/main216/com/baeldung/googlehttpclientguide/logging.properties deleted file mode 100644 index 02489378df..0000000000 --- a/out/production/main216/com/baeldung/googlehttpclientguide/logging.properties +++ /dev/null @@ -1,10 +0,0 @@ -# Properties file which configures the operation of the JDK logging facility. -# The system will look for this config file to be specified as a system property: -# -Djava.util.logging.config.file=${project_loc:dailymotion-simple-cmdline-sample}/logging.properties - -# Set up the console handler (uncomment "level" to show more fine-grained messages) -handlers = java.util.logging.ConsoleHandler -java.util.logging.ConsoleHandler.level = ALL - -# Set up logging of HTTP requests and responses (uncomment "level" to show) -com.google.api.client.http.level = ALL diff --git a/out/production/main231/com/baeldung/wicket/examples/HelloWorld.html b/out/production/main231/com/baeldung/wicket/examples/HelloWorld.html deleted file mode 100644 index 497e98e01a..0000000000 --- a/out/production/main231/com/baeldung/wicket/examples/HelloWorld.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - -Wicket Intro Examples - - - -
    -
    -
    -

    Wicket Introduction Examples:

    - - Hello World! -
    -
    - Cafes -
    -
    -
    -
    - - diff --git a/out/production/main231/com/baeldung/wicket/examples/cafeaddress/CafeAddress.html b/out/production/main231/com/baeldung/wicket/examples/cafeaddress/CafeAddress.html deleted file mode 100644 index c5ada2323d..0000000000 --- a/out/production/main231/com/baeldung/wicket/examples/cafeaddress/CafeAddress.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - -Cafes - - -
    - -

    - Address: address -

    -
    - - diff --git a/out/production/main231/com/baeldung/wicket/examples/helloworld/HelloWorld.html b/out/production/main231/com/baeldung/wicket/examples/helloworld/HelloWorld.html deleted file mode 100644 index c56d07fc10..0000000000 --- a/out/production/main231/com/baeldung/wicket/examples/helloworld/HelloWorld.html +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/out/production/main234/com/baeldung/activiti/security.rar b/out/production/main234/com/baeldung/activiti/security.rar deleted file mode 100644 index 38c4946168..0000000000 Binary files a/out/production/main234/com/baeldung/activiti/security.rar and /dev/null differ diff --git a/out/production/main291/xml-bean-config.xml b/out/production/main291/xml-bean-config.xml deleted file mode 100644 index 3b880bbd70..0000000000 --- a/out/production/main291/xml-bean-config.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/out/production/main30/com/baeldung/factorybean/README.md b/out/production/main30/com/baeldung/factorybean/README.md deleted file mode 100644 index 13f9f379e0..0000000000 --- a/out/production/main30/com/baeldung/factorybean/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [How to use the Spring FactoryBean?](http://www.baeldung.com/spring-factorybean) diff --git a/out/production/main330/com/baeldung/README.md b/out/production/main330/com/baeldung/README.md deleted file mode 100644 index 51809b2882..0000000000 --- a/out/production/main330/com/baeldung/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [SHA-256 Hashing in Java](http://www.baeldung.com/sha-256-hashing-java) diff --git a/out/production/main351/com/baeldung/produceimage/README.md b/out/production/main351/com/baeldung/produceimage/README.md deleted file mode 100644 index acd546598d..0000000000 --- a/out/production/main351/com/baeldung/produceimage/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant articles - -- [Returning an Image or a File with Spring](http://www.baeldung.com/spring-controller-return-image-file) diff --git a/out/production/main96/com/baeldung/git/README.md b/out/production/main96/com/baeldung/git/README.md deleted file mode 100644 index 7e6a597c28..0000000000 --- a/out/production/main96/com/baeldung/git/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [Injecting Git Information Into Spring](http://www.baeldung.com/spring-git-information) diff --git a/out/production/routing-in-play/views/index.scala.html b/out/production/routing-in-play/views/index.scala.html deleted file mode 100644 index 4539f5a10b..0000000000 --- a/out/production/routing-in-play/views/index.scala.html +++ /dev/null @@ -1,20 +0,0 @@ -@* - * This template takes a single argument, a String containing a - * message to display. - *@ -@(message: String) - -@* - * Call the `main` template with two arguments. The first - * argument is a `String` with the title of the page, the second - * argument is an `Html` object containing the body of the page. - *@ -@main("Welcome to Play") { - - @* - * Get an `Html` object by calling the built-in Play welcome - * template and passing a `String` message. - *@ - @play20.welcome(message, style = "Java") - -} diff --git a/out/production/routing-in-play/views/main.scala.html b/out/production/routing-in-play/views/main.scala.html deleted file mode 100644 index 9414f4be6e..0000000000 --- a/out/production/routing-in-play/views/main.scala.html +++ /dev/null @@ -1,23 +0,0 @@ -@* - * This template is called from the `index` template. This template - * handles the rendering of the page header and body tags. It takes - * two arguments, a `String` for the title of the page and an `Html` - * object to insert into the body of the page. - *@ -@(title: String)(content: Html) - - - - - @* Here's where we render the page title `String`. *@ - @title - - - - - - @* And here's where we render the `Html` object containing - * the page content. *@ - @content - - diff --git a/out/test/test95/com/baeldung/hexToAscii/README.md b/out/test/test/com/baeldung/hexToAscii/README.md similarity index 100% rename from out/test/test95/com/baeldung/hexToAscii/README.md rename to out/test/test/com/baeldung/hexToAscii/README.md diff --git a/out/test/test95/com/baeldung/java/conversion/README.md b/out/test/test/com/baeldung/java/conversion/README.md similarity index 100% rename from out/test/test95/com/baeldung/java/conversion/README.md rename to out/test/test/com/baeldung/java/conversion/README.md diff --git a/out/test/test/com/baeldung/stringisnumeric.zip b/out/test/test/com/baeldung/stringisnumeric.zip new file mode 100644 index 0000000000..b8a7b9b35a Binary files /dev/null and b/out/test/test/com/baeldung/stringisnumeric.zip differ diff --git a/out/test/test105/com/baeldung/cglib/proxy/README.md b/out/test/test105/com/baeldung/cglib/proxy/README.md deleted file mode 100644 index abeabc6162..0000000000 --- a/out/test/test105/com/baeldung/cglib/proxy/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant articles - -- [Introduction to cglib](http://www.baeldung.com/cglib) diff --git a/out/test/test143/com/baeldung/java9/README.MD b/out/test/test143/com/baeldung/java9/README.MD deleted file mode 100644 index 2f44a2336b..0000000000 --- a/out/test/test143/com/baeldung/java9/README.MD +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Artiles: -- [Filtering a Stream of Optionals in Java](http://www.baeldung.com/java-filter-stream-of-optional) diff --git a/out/test/test174/org/baeldung/hamcrest/README.md b/out/test/test174/org/baeldung/hamcrest/README.md deleted file mode 100644 index 7266ecda3a..0000000000 --- a/out/test/test174/org/baeldung/hamcrest/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [Testing with Hamcrest](http://www.baeldung.com/java-junit-hamcrest-guide) diff --git a/out/test/test191/com/baeldung/web/controller/README.md b/out/test/test191/com/baeldung/web/controller/README.md deleted file mode 100644 index 9923962dde..0000000000 --- a/out/test/test191/com/baeldung/web/controller/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [WebAppConfiguration in Spring Tests](http://www.baeldung.com/spring-webappconfiguration) diff --git a/out/test/test197/com/baeldung/java/nio2/README.md b/out/test/test197/com/baeldung/java/nio2/README.md deleted file mode 100644 index 569be82d27..0000000000 --- a/out/test/test197/com/baeldung/java/nio2/README.md +++ /dev/null @@ -1,11 +0,0 @@ -### Relevant Articles: -- [Introduction to the Java NIO2 File API](http://www.baeldung.com/java-nio-2-file-api) -- [Java NIO2 Path API](http://www.baeldung.com/java-nio-2-path) -- [A Guide To NIO2 Asynchronous File Channel](http://www.baeldung.com/java-nio2-async-file-channel) -- [Guide to Selenium with JUnit / TestNG](http://www.baeldung.com/java-selenium-with-junit-and-testng) -- [A Guide to NIO2 Asynchronous Socket Channel](http://www.baeldung.com/java-nio2-async-socket-channel) -- [A Guide To NIO2 FileVisitor](http://www.baeldung.com/java-nio2-file-visitor) -- [A Guide To NIO2 File Attribute APIs](http://www.baeldung.com/java-nio2-file-attribute) -- [How to use the Spring FactoryBean?](http://www.baeldung.com/spring-factorybean) -- [A Guide to WatchService in Java NIO2](http://www.baeldung.com/java-nio2-watchservice) -- [Guide to Java NIO2 Asynchronous Channel APIs](http://www.baeldung.com/java-nio-2-async-channels) diff --git a/out/test/test237/META-INF/persistence.xml b/out/test/test237/META-INF/persistence.xml deleted file mode 100644 index 922aedbc39..0000000000 --- a/out/test/test237/META-INF/persistence.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - org.baeldung.persistence.model.Foo - org.baeldung.persistence.model.Bar - - - - - - - - - - - - - diff --git a/out/test/test95/org/baeldung/java/collections/README.md b/out/test/test95/org/baeldung/java/collections/README.md deleted file mode 100644 index 317d81fae7..0000000000 --- a/out/test/test95/org/baeldung/java/collections/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: -- [Join and Split Arrays and Collections in Java](http://www.baeldung.com/java-join-and-split) -- [Introduction to Java Servlets](http://www.baeldung.com/intro-to-servlets) diff --git a/out/test/test95/org/baeldung/java/lists/README.md b/out/test/test95/org/baeldung/java/lists/README.md deleted file mode 100644 index 2a1e8aeeaa..0000000000 --- a/out/test/test95/org/baeldung/java/lists/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [Check If Two Lists are Equal in Java](http://www.baeldung.com/java-test-a-list-for-ordinality-and-equality) diff --git a/out/test/test98/com/baeldung/applicationcontext/README.md b/out/test/test98/com/baeldung/applicationcontext/README.md deleted file mode 100644 index 211007e0cf..0000000000 --- a/out/test/test98/com/baeldung/applicationcontext/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles: -- [Introduction to Java Servlets](http://www.baeldung.com/intro-to-servlets) -- [Intro to the Spring ClassPathXmlApplicationContext](http://www.baeldung.com/spring-classpathxmlapplicationcontext) diff --git a/out/test/test98/com/baeldung/beanfactory/README.md b/out/test/test98/com/baeldung/beanfactory/README.md deleted file mode 100644 index cff20a184b..0000000000 --- a/out/test/test98/com/baeldung/beanfactory/README.md +++ /dev/null @@ -1,2 +0,0 @@ -### Relevant Articles: -- [Guide to the Spring BeanFactory](http://www.baeldung.com/spring-beanfactory) diff --git a/parent-boot-1/pom.xml b/parent-boot-1/pom.xml index bd28f7c5e2..d220b4a6b7 100644 --- a/parent-boot-1/pom.xml +++ b/parent-boot-1/pom.xml @@ -1,122 +1,55 @@ - 4.0.0 - com.baeldung - parent-boot-1 - 0.0.1-SNAPSHOT - pom - Parent for all Spring Boot 1.x modules + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + parent-boot-1 + 0.0.1-SNAPSHOT + pom + Parent for all Spring Boot 1.x modules - - org.springframework.boot - spring-boot-starter-parent - 1.5.13.RELEASE - - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + - - - junit - junit - test - - - io.rest-assured - rest-assured - ${rest-assured.version} - - - org.springframework.boot - spring-boot-starter-test - test - - + + + + org.springframework.boot + spring-boot-dependencies + 1.5.16.RELEASE + pom + import + + + + + + io.rest-assured + rest-assured + ${rest-assured.version} + + + org.springframework.boot + spring-boot-starter-test + test + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/*LiveTest.java - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - - - + + + + + org.springframework.boot + spring-boot-maven-plugin + 1.5.15.RELEASE + + + + - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - **/*LiveTest.java - **/AutoconfigurationTest.java - **/*UnitTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - */EthControllerTestOne.java - **/*EntryPointsTest.java - - - - - - - json - - - - - - - - - - UTF-8 - UTF-8 - 1.8 - 3.0.6 - - 2.20.1 - 3.7.0 - 1.8 - 1.8 - + + 3.1.0 + \ No newline at end of file diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index b62d37b3f0..de6cb5d068 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -1,31 +1,33 @@ + 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-2 0.0.1-SNAPSHOT pom - Parent Boot 2 - Parent for all spring boot 2 modules + Parent for all Spring Boot 2 modules - org.springframework.boot - spring-boot-starter-parent - 2.0.1.RELEASE - + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-dependencies + 2.0.4.RELEASE + pom + import + + + - - junit - junit - test - io.rest-assured rest-assured - ${rest-assured.version} - +
    org.springframework.boot spring-boot-starter-test @@ -33,79 +35,19 @@
    - - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/*LiveTest.java - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.0.4.RELEASE + + + + + - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - **/*LiveTest.java - **/AutoconfigurationTest.java - **/*UnitTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - */EthControllerTestOne.java - **/*EntryPointsTest.java - - - - - - - json - - - - - - thin-jar @@ -128,13 +70,8 @@ - UTF-8 - UTF-8 - 1.8 3.1.0 - 1.8 - 1.8 1.0.11.RELEASE diff --git a/parent-java/pom.xml b/parent-java/pom.xml index 40df31d1c7..86be34d508 100644 --- a/parent-java/pom.xml +++ b/parent-java/pom.xml @@ -1,5 +1,5 @@ + 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-java diff --git a/parent-kotlin/pom.xml b/parent-kotlin/pom.xml new file mode 100644 index 0000000000..7fd18e4fa4 --- /dev/null +++ b/parent-kotlin/pom.xml @@ -0,0 +1,194 @@ + + + 4.0.0 + parent-kotlin + pom + parent-kotlin + Parent for all kotlin modules + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + jcenter + http://jcenter.bintray.com + + + kotlin-ktor + https://dl.bintray.com/kotlin/ktor/ + + + + + + + org.springframework.boot + spring-boot-dependencies + 2.0.1.RELEASE + pom + import + + + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin.version} + + + + org.jetbrains.kotlinx + kotlinx-coroutines-core + ${kotlinx.version} + + + + io.ktor + ktor-server-netty + ${ktor.io.version} + + + io.ktor + ktor-gson + ${ktor.io.version} + + + + org.jetbrains.kotlin + kotlin-test-junit + ${kotlin.version} + test + + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + + compile + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/main/java + + ${java.version} + + + + test-compile + + test-compile + + + + ${project.basedir}/src/test/kotlin + ${project.basedir}/src/test/java + + ${java.version} + + + + + + spring + + + + + org.jetbrains.kotlin + kotlin-maven-allopen + ${kotlin.version} + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + + compile + + + + java-test-compile + test-compile + + testCompile + + + + + + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + junit5 + + integration-test + verify + + + + **/*Test5.java + + + + + + + + + + 1.2.61 + 0.25.0 + 0.9.3 + 3.11.0 + 1.2.0 + + diff --git a/parent-spring-4/pom.xml b/parent-spring-4/pom.xml index b2b8295f01..d1b1298013 100644 --- a/parent-spring-4/pom.xml +++ b/parent-spring-4/pom.xml @@ -1,5 +1,5 @@ + 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-spring-4 diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index 84e1a29a0d..6a15f38884 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -1,5 +1,5 @@ + 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-spring-5 @@ -31,7 +31,9 @@ 5.0.6.RELEASE 5.0.2 - 2.9.6 + 2.9.6 + 2.9.6 + 5.0.6.RELEASE \ No newline at end of file diff --git a/patterns/README.md b/patterns/README.md index df39b39224..221cba6456 100644 --- a/patterns/README.md +++ b/patterns/README.md @@ -1,7 +1,8 @@ -###Relevant Articles: +### Relevant Articles: - [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern) - [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java) - [Implementing the Template Method Pattern in Java](http://www.baeldung.com/java-template-method-pattern) - [Chain of Responsibility Design Pattern in Java](http://www.baeldung.com/chain-of-responsibility-pattern) - [The Command Pattern in Java](http://www.baeldung.com/java-command-pattern) +- [The DAO Pattern in Java](http://www.baeldung.com/java-dao-pattern) diff --git a/patterns/design-patterns/README.md b/patterns/design-patterns/README.md index 8b9d7a8193..75f7cec73a 100644 --- a/patterns/design-patterns/README.md +++ b/patterns/design-patterns/README.md @@ -10,3 +10,5 @@ - [Composite Design Pattern in Java](http://www.baeldung.com/java-composite-pattern) - [Visitor Design Pattern in Java](http://www.baeldung.com/java-visitor-pattern) - [The DAO Pattern in Java](http://www.baeldung.com/java-dao-pattern) +- [Interpreter Design Pattern in Java](http://www.baeldung.com/java-interpreter-pattern) +- [State Design Pattern in Java](https://www.baeldung.com/java-state-design-pattern) diff --git a/patterns/design-patterns/pom.xml b/patterns/design-patterns/pom.xml index dd1c5abced..dc2631b36e 100644 --- a/patterns/design-patterns/pom.xml +++ b/patterns/design-patterns/pom.xml @@ -1,74 +1,59 @@ - + 4.0.0 - com.baeldung design-patterns 1.0 jar com.baeldung - patterns-parent + patterns 1.0.0-SNAPSHOT .. - - - junit - junit - 4.12 - test - - - org.hamcrest - hamcrest-core - 1.3 - test - + org.assertj assertj-core - 3.9.1 - test - - - org.mockito - mockito-core - 2.18.3 + ${assertj-core.version} test javax javaee-api - 8.0 + ${javaee.version} org.hibernate hibernate-core - 5.2.16.Final + ${hibernate-core.version} mysql mysql-connector-java - 6.0.6 + ${mysql-connector.version} jar - log4j - log4j - ${log4j.version} + log4j + log4j + ${log4j.version} com.googlecode.grep4j - grep4j - ${grep4j.version} - + grep4j + ${grep4j.version} + UTF-8 1.8 1.8 - 1.2.17 1.8.7 + 3.9.1 + 8.0 + 5.2.16.Final + 6.0.6 diff --git a/patterns/design-patterns/src/main/java/com/baeldung/state/DeliveredState.java b/patterns/design-patterns/src/main/java/com/baeldung/state/DeliveredState.java new file mode 100644 index 0000000000..9f5e4d8fc4 --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/state/DeliveredState.java @@ -0,0 +1,25 @@ +package com.baeldung.state; + +public class DeliveredState implements PackageState { + + @Override + public void next(Package pkg) { + pkg.setState(new ReceivedState()); + } + + @Override + public void prev(Package pkg) { + pkg.setState(new OrderedState()); + } + + @Override + public void printStatus() { + System.out.println("Package delivered to post office, not received yet."); + } + + @Override + public String toString() { + return "DeliveredState{}"; + } + +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/state/OrderedState.java b/patterns/design-patterns/src/main/java/com/baeldung/state/OrderedState.java new file mode 100644 index 0000000000..0642c4c73c --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/state/OrderedState.java @@ -0,0 +1,24 @@ +package com.baeldung.state; + +public class OrderedState implements PackageState { + + @Override + public void next(Package pkg) { + pkg.setState(new DeliveredState()); + } + + @Override + public void prev(Package pkg) { + System.out.println("The package is in it's root state."); + } + + @Override + public void printStatus() { + System.out.println("Package ordered, not delivered to the office yet."); + } + + @Override + public String toString() { + return "OrderedState{}"; + } +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/state/Package.java b/patterns/design-patterns/src/main/java/com/baeldung/state/Package.java new file mode 100644 index 0000000000..f3dfbb3fa7 --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/state/Package.java @@ -0,0 +1,26 @@ +package com.baeldung.state; + +public class Package { + + private PackageState state = new OrderedState(); + + public PackageState getState() { + return state; + } + + public void setState(PackageState state) { + this.state = state; + } + + public void previousState() { + state.prev(this); + } + + public void nextState() { + state.next(this); + } + + public void printStatus() { + state.printStatus(); + } +} diff --git a/patterns/design-patterns/src/main/java/com/baeldung/state/PackageState.java b/patterns/design-patterns/src/main/java/com/baeldung/state/PackageState.java new file mode 100644 index 0000000000..d6656c78ac --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/state/PackageState.java @@ -0,0 +1,10 @@ +package com.baeldung.state; + +public interface PackageState { + + void next(Package pkg); + + void prev(Package pkg); + + void printStatus(); +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/state/ReceivedState.java b/patterns/design-patterns/src/main/java/com/baeldung/state/ReceivedState.java new file mode 100644 index 0000000000..84136fa48e --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/state/ReceivedState.java @@ -0,0 +1,24 @@ +package com.baeldung.state; + +public class ReceivedState implements PackageState { + + @Override + public void next(Package pkg) { + System.out.println("This package is already received by a client."); + } + + @Override + public void prev(Package pkg) { + pkg.setState(new DeliveredState()); + } + + @Override + public void printStatus() { + System.out.println("Package was received by client."); + } + + @Override + public String toString() { + return "ReceivedState{}"; + } +} \ No newline at end of file diff --git a/patterns/design-patterns/src/main/java/com/baeldung/state/StateDemo.java b/patterns/design-patterns/src/main/java/com/baeldung/state/StateDemo.java new file mode 100644 index 0000000000..1a63ea3ddf --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/state/StateDemo.java @@ -0,0 +1,19 @@ +package com.baeldung.state; + +public class StateDemo { + + public static void main(String[] args) { + + Package pkg = new Package(); + pkg.printStatus(); + + pkg.nextState(); + pkg.printStatus(); + + pkg.nextState(); + pkg.printStatus(); + + pkg.nextState(); + pkg.printStatus(); + } +} diff --git a/patterns/design-patterns/src/test/java/com/baeldung/state/StatePatternUnitTest.java b/patterns/design-patterns/src/test/java/com/baeldung/state/StatePatternUnitTest.java new file mode 100644 index 0000000000..731974f92b --- /dev/null +++ b/patterns/design-patterns/src/test/java/com/baeldung/state/StatePatternUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.state; + +import com.baeldung.state.Package; + +import static org.junit.Assert.assertThat; +import static org.hamcrest.CoreMatchers.instanceOf; + +import org.junit.Test; + +public class StatePatternUnitTest { + + @Test + public void givenNewPackage_whenPackageReceived_thenStateReceived() { + Package pkg = new Package(); + + assertThat(pkg.getState(), instanceOf(OrderedState.class)); + pkg.nextState(); + + assertThat(pkg.getState(), instanceOf(DeliveredState.class)); + pkg.nextState(); + + assertThat(pkg.getState(), instanceOf(ReceivedState.class)); + } + + @Test + public void givenDeliveredPackage_whenPrevState_thenStateOrdered() { + Package pkg = new Package(); + pkg.setState(new DeliveredState()); + pkg.previousState(); + + assertThat(pkg.getState(), instanceOf(OrderedState.class)); + } +} diff --git a/patterns/front-controller/pom.xml b/patterns/front-controller/pom.xml index a12d606165..435b0dd9cd 100644 --- a/patterns/front-controller/pom.xml +++ b/patterns/front-controller/pom.xml @@ -1,12 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 front-controller war - patterns-parent + patterns com.baeldung 1.0.0-SNAPSHOT .. diff --git a/patterns/front-controller/src/main/resources/logback.xml b/patterns/front-controller/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/patterns/front-controller/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/patterns/intercepting-filter/pom.xml b/patterns/intercepting-filter/pom.xml index 8c68302315..fa94d5d1fd 100644 --- a/patterns/intercepting-filter/pom.xml +++ b/patterns/intercepting-filter/pom.xml @@ -8,7 +8,7 @@ com.baeldung - patterns-parent + patterns 1.0.0-SNAPSHOT .. @@ -21,7 +21,7 @@ org.slf4j slf4j-api - ${slf4j.version} + ${org.slf4j.version} @@ -30,10 +30,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + ${maven-compiler-plugin.version} - 1.8 - 1.8 + ${java.version} + ${java.version} @@ -55,7 +55,4 @@ - - 1.7.21 - diff --git a/patterns/intercepting-filter/src/main/resources/logback.xml b/patterns/intercepting-filter/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/patterns/intercepting-filter/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/patterns/pom.xml b/patterns/pom.xml index a811664b86..df09f1836a 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -1,9 +1,8 @@ + 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 - patterns-parent + patterns pom diff --git a/pdf/pom.xml b/pdf/pom.xml index 01b2e15652..bf5d475163 100644 --- a/pdf/pom.xml +++ b/pdf/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 pdf pdf @@ -74,7 +73,6 @@ - UTF-8 2.0.3 1.6 5.5.10 diff --git a/pdf/src/main/resources/logback.xml b/pdf/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/pdf/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml index 3f25796516..8c9d027724 100644 --- a/performance-tests/pom.xml +++ b/performance-tests/pom.xml @@ -2,72 +2,73 @@ + 4.0.0 + performance-tests + parent-modules com.baeldung 1.0.0-SNAPSHOT - 4.0.0 - - performancetests ma.glasnost.orika orika-core - 1.5.2 + ${orika.version} net.sf.dozer dozer - 5.5.1 + ${dozer.version} io.craftsman dozer-jdk8-support - 1.0.2 + ${dozer-jdk8-support.version} org.mapstruct mapstruct-jdk8 - 1.2.0.Final + ${mapstruct-jdk8.version} org.modelmapper modelmapper - 1.1.0 + ${modelmapper.version} com.googlecode.jmapper-framework jmapper-core - 1.6.0.1 + ${jmapper.version} org.openjdk.jmh jmh-core - 1.20 + ${jmh.version} org.openjdk.jmh jmh-generator-annprocess - 1.20 + ${jmh.version} + org.apache.maven.plugins maven-compiler-plugin - 3.5.1 + ${maven-compiler-plugin.version} - 1.8 - 1.8 + ${java.version} + ${java.version} org.mapstruct mapstruct-processor - 1.2.0.Final + ${mapstruct-processor.version} @@ -75,5 +76,16 @@ + + + 1.5.2 + 5.5.1 + 1.0.2 + 1.2.0.Final + 1.1.0 + 1.6.0.1 + 1.20 + 1.2.0.Final + \ No newline at end of file diff --git a/performance-tests/src/main/resources/logback.xml b/performance-tests/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/performance-tests/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/README.md b/persistence-modules/README.md index 8f8c3eb13d..f12163bd6a 100644 --- a/persistence-modules/README.md +++ b/persistence-modules/README.md @@ -7,6 +7,5 @@ - [Introduction to Hibernate Search](http://www.baeldung.com/hibernate-search) - [Bootstrapping Hibernate 5 with Spring](http://www.baeldung.com/hibernate-5-spring) - [Introduction to Lettuce – the Java Redis Client](http://www.baeldung.com/java-redis-lettuce) -- [A Simple Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging) - [A Guide to Jdbi](http://www.baeldung.com/jdbi) - [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking) diff --git a/persistence-modules/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml index 610d6b8f09..36ec6b5ac8 100644 --- a/persistence-modules/java-cassandra/pom.xml +++ b/persistence-modules/java-cassandra/pom.xml @@ -1,16 +1,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 - cassandra-java-client + java-cassandra 1.0.0-SNAPSHOT - cassandra-java-client com.baeldung parent-java - 0.0.1-SNAPSHOT - ../../parent-java + 0.0.1-SNAPSHOT + ../../parent-java @@ -36,8 +35,6 @@ - UTF-8 - 19.0 3.1.2 3.1.1.0 diff --git a/persistence-modules/java-cassandra/src/main/resources/logback.xml b/persistence-modules/java-cassandra/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/java-cassandra/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/java-cockroachdb/pom.xml b/persistence-modules/java-cockroachdb/pom.xml index a1924b674a..870707c750 100644 --- a/persistence-modules/java-cockroachdb/pom.xml +++ b/persistence-modules/java-cockroachdb/pom.xml @@ -1,6 +1,6 @@ + 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 java-cockroachdb diff --git a/persistence-modules/java-cockroachdb/src/main/resources/logback.xml b/persistence-modules/java-cockroachdb/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/java-cockroachdb/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java similarity index 99% rename from persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java rename to persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java index 9eb00b3651..eda9ca15e4 100644 --- a/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java +++ b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryLiveTest.java @@ -16,7 +16,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -public class ArticleRepositoryIntegrationTest { +public class ArticleRepositoryLiveTest { private static final String TABLE_NAME = "articles"; diff --git a/persistence-modules/java-jdbi/pom.xml b/persistence-modules/java-jdbi/pom.xml index a823141bc5..885906fcd0 100644 --- a/persistence-modules/java-jdbi/pom.xml +++ b/persistence-modules/java-jdbi/pom.xml @@ -1,7 +1,6 @@ - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 java-jdbi 1.0-SNAPSHOT diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md new file mode 100644 index 0000000000..418e0a67e2 --- /dev/null +++ b/persistence-modules/java-jpa/README.md @@ -0,0 +1,4 @@ +# Relevant Articles + +- [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping) +- [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) \ No newline at end of file diff --git a/persistence-modules/java-jpa/pom.xml b/persistence-modules/java-jpa/pom.xml new file mode 100644 index 0000000000..78764f7148 --- /dev/null +++ b/persistence-modules/java-jpa/pom.xml @@ -0,0 +1,32 @@ + + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + ../../pom.xml + + 4.0.0 + + java-jpa + + + + org.hibernate + hibernate-core + ${hibernate.version} + + + com.h2database + h2 + ${h2.version} + + + + + 5.3.1.Final + 1.4.197 + + \ No newline at end of file diff --git a/jpa-storedprocedure/src/main/java/com/baeldung/jpa/model/Car.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/model/Car.java similarity index 100% rename from jpa-storedprocedure/src/main/java/com/baeldung/jpa/model/Car.java rename to persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/model/Car.java diff --git a/jpa-storedprocedure/src/main/java/com/baeldung/jpa/model/QueryParameter.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/model/QueryParameter.java similarity index 100% rename from jpa-storedprocedure/src/main/java/com/baeldung/jpa/model/QueryParameter.java rename to persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/model/QueryParameter.java diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/Employee.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/Employee.java new file mode 100644 index 0000000000..bec1b8845a --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/Employee.java @@ -0,0 +1,43 @@ +package com.baeldung.sqlresultsetmapping; + +import javax.persistence.*; + + +@SqlResultSetMapping( + name="EmployeeResult", + entities={ + @EntityResult( + entityClass = com.baeldung.sqlresultsetmapping.Employee.class, + fields={@FieldResult(name="id",column="employeeNumber"), + @FieldResult(name="name", column="name")} + ) + } +) +@NamedNativeQuery( + name="Employees", + query="SELECT id as employeeNumber, name FROM EMPLOYEE", + resultSetMapping = "EmployeeResult" +) +@Entity +public class Employee { + + @Id + private Long id; + private String 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; + } +} diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/ScheduledDay.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/ScheduledDay.java new file mode 100644 index 0000000000..7e332bc67a --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/sqlresultsetmapping/ScheduledDay.java @@ -0,0 +1,58 @@ +package com.baeldung.sqlresultsetmapping; + +import javax.persistence.*; + +@SqlResultSetMappings(value = { + @SqlResultSetMapping(name = "ScheduleResult", + classes = { @ConstructorResult(targetClass = com.baeldung.sqlresultsetmapping.ScheduledDay.class, + columns = { @ColumnResult(name = "id", type = Long.class), + @ColumnResult(name = "employeeId", type = Long.class), + @ColumnResult(name = "dayOfWeek") }) }), + @SqlResultSetMapping(name = "FridayEmployeeResult", + columns = { @ColumnResult(name = "employeeId") }), + @SqlResultSetMapping(name = "EmployeeScheduleResults", + entities = { @EntityResult(entityClass = com.baeldung.sqlresultsetmapping.Employee.class), + @EntityResult(entityClass = com.baeldung.sqlresultsetmapping.ScheduledDay.class) + }) }) +@NamedNativeQuery(name = "FridayEmployees", + query = "SELECT employeeId FROM schedule_days WHERE dayOfWeek = 'FRIDAY'", + resultSetMapping = "FridayEmployeeResult") + +@NamedNativeQuery(name = "Schedules", + query = "SELECT * FROM schedule_days WHERE employeeId = 3", + resultSetMapping = "ScheduleResult") +@Entity +@Table(name = "SCHEDULE_DAYS") +public class ScheduledDay { + + @Id + @GeneratedValue + private Long id; + private Long employeeId; + private String dayOfWeek; + + public ScheduledDay() { + } + + public ScheduledDay(Long id, Long employeeId, String dayofWeek) { + this.id = id; + this.employeeId = employeeId; + this.dayOfWeek = dayofWeek; + } + + public Long getEmployeeId() { + return employeeId; + } + + public void setEmployeeId(Long employeeId) { + this.employeeId = employeeId; + } + + public String getDayOfWeek() { + return dayOfWeek; + } + + public void setDayOfWeek(String dayOfWeek) { + this.dayOfWeek = dayOfWeek; + } +} diff --git a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..3d881673b2 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,37 @@ + + + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.sqlresultsetmapping.ScheduledDay + + + + + + + + + + + + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.model.Car + + + + + + + + + + + \ No newline at end of file diff --git a/jpa-storedprocedure/src/main/resources/config/database/FindCarByYearProcedureMySQL.sql b/persistence-modules/java-jpa/src/main/resources/config/database/FindCarByYearProcedureMySQL.sql similarity index 100% rename from jpa-storedprocedure/src/main/resources/config/database/FindCarByYearProcedureMySQL.sql rename to persistence-modules/java-jpa/src/main/resources/config/database/FindCarByYearProcedureMySQL.sql diff --git a/jpa-storedprocedure/src/main/resources/config/database/create_table_mysql.sql b/persistence-modules/java-jpa/src/main/resources/config/database/create_table_mysql.sql similarity index 100% rename from jpa-storedprocedure/src/main/resources/config/database/create_table_mysql.sql rename to persistence-modules/java-jpa/src/main/resources/config/database/create_table_mysql.sql diff --git a/jpa-storedprocedure/src/main/resources/config/database/insert_cars.sql b/persistence-modules/java-jpa/src/main/resources/config/database/insert_cars.sql similarity index 100% rename from jpa-storedprocedure/src/main/resources/config/database/insert_cars.sql rename to persistence-modules/java-jpa/src/main/resources/config/database/insert_cars.sql diff --git a/persistence-modules/java-jpa/src/main/resources/database.sql b/persistence-modules/java-jpa/src/main/resources/database.sql new file mode 100644 index 0000000000..bd2bb68599 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/resources/database.sql @@ -0,0 +1,17 @@ +CREATE TABLE EMPLOYEE +(id BIGINT, + name VARCHAR(10)); + +INSERT INTO EMPLOYEE VALUES (1, 'JOHN'); +INSERT INTO EMPLOYEE VALUES (2, 'MARY'); +INSERT INTO EMPLOYEE VALUES (3, 'FRANK'); + +CREATE TABLE SCHEDULE_DAYS +(id IDENTITY, + employeeId BIGINT, + dayOfWeek VARCHAR(10)); + +INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (1, 'FRIDAY'); +INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (2, 'SATURDAY'); +INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (3, 'MONDAY'); +INSERT INTO SCHEDULE_DAYS (employeeId, dayOfWeek) VALUES (3, 'FRIDAY'); diff --git a/persistence-modules/java-jpa/src/main/resources/logback.xml b/persistence-modules/java-jpa/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java similarity index 100% rename from jpa-storedprocedure/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java rename to persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/storedprocedure/StoredProcedureLiveTest.java diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/sqlresultsetmapping/SqlResultSetMappingUnitTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/sqlresultsetmapping/SqlResultSetMappingUnitTest.java new file mode 100644 index 0000000000..4e01095278 --- /dev/null +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/sqlresultsetmapping/SqlResultSetMappingUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.sqlresultsetmapping; + +import static org.junit.Assert.*; + +import org.junit.jupiter.api.*; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import java.util.Collections; +import java.util.List; + +public class SqlResultSetMappingUnitTest { + + private static EntityManager em; + private static EntityManagerFactory emFactory; + + @BeforeAll + public static void setup() { + emFactory = Persistence.createEntityManagerFactory("java-jpa-scheduled-day"); + em = emFactory.createEntityManager(); + } + + @Test + public void whenNamedQuery_thenColumnResult() { + List employeeIds = em.createNamedQuery("FridayEmployees").getResultList(); + assertEquals(2, employeeIds.size()); + } + + @Test + public void whenNamedQuery_thenConstructorResult() { + List scheduleDays = Collections.checkedList(em.createNamedQuery("Schedules", ScheduledDay.class).getResultList(), ScheduledDay.class); + assertEquals(2, scheduleDays.size()); + assertTrue(scheduleDays.stream().allMatch(c -> c.getEmployeeId().longValue() == 3)); + } + + @Test + public void whenNamedQuery_thenSingleEntityResult() { + List employees = Collections.checkedList(em.createNamedQuery("Employees").getResultList(), Employee.class); + assertEquals(3, employees.size()); + assertTrue(employees.stream().allMatch(c -> c.getClass() == Employee.class)); + } + + @Test + public void whenNamedQuery_thenMultipleEntityResult() { + final Query query = em.createNativeQuery("SELECT e.id, e.name, d.id, d.employeeId, d.dayOfWeek " + + " FROM employee e, schedule_days d " + + " WHERE e.id = d.employeeId", "EmployeeScheduleResults"); + List results = query.getResultList(); + assertEquals(4, results.size()); + assertTrue(results.get(0).length == 2); + + Employee emp = (Employee) results.get(1)[0]; + ScheduledDay day = (ScheduledDay) results.get(1)[1]; + + assertTrue(day.getEmployeeId() == emp.getId()); + } + + @AfterAll + public static void destroy() { + + if (em != null) { + em.close(); + } + if (emFactory != null) { + emFactory.close(); + } + } +} diff --git a/persistence-modules/java-jpa/src/test/resources/employees.sql b/persistence-modules/java-jpa/src/test/resources/employees.sql new file mode 100644 index 0000000000..feace36e2c --- /dev/null +++ b/persistence-modules/java-jpa/src/test/resources/employees.sql @@ -0,0 +1,3 @@ +INSERT INTO employee (1, "JOHN"); +INSERT INTO employee (2, "MARY"); +INSERT INTO employee (3, "FRANK"); \ No newline at end of file diff --git a/jpa-storedprocedure/src/test/resources/persistence.xml b/persistence-modules/java-jpa/src/test/resources/persistence.xml similarity index 100% rename from jpa-storedprocedure/src/test/resources/persistence.xml rename to persistence-modules/java-jpa/src/test/resources/persistence.xml diff --git a/persistence-modules/java-jpa/src/test/resources/scheduledDays.sql b/persistence-modules/java-jpa/src/test/resources/scheduledDays.sql new file mode 100644 index 0000000000..df1d4ed09e --- /dev/null +++ b/persistence-modules/java-jpa/src/test/resources/scheduledDays.sql @@ -0,0 +1,10 @@ +INSERT INTO SCHEDULE_DAYS (1, 13, 21, 'FRIDAY'); +INSERT INTO SCHEDULE_DAYS (2, 8, 4, 'SATURDAY'); +INSERT INTO SCHEDULE_DAYS (3, 8, 4, 'FRIDAY'); + + +-- private Long id; +-- private Long employeeId; +-- private Time in; +-- private Time out; +-- private DayOfWeek dayOfWeek; \ No newline at end of file diff --git a/persistence-modules/java-mongodb/pom.xml b/persistence-modules/java-mongodb/pom.xml index ba8fabb9a5..bbc48f54c2 100644 --- a/persistence-modules/java-mongodb/pom.xml +++ b/persistence-modules/java-mongodb/pom.xml @@ -1,8 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - com.baeldung java-mongodb 1.0-SNAPSHOT diff --git a/persistence-modules/java-mongodb/src/main/resources/logback.xml b/persistence-modules/java-mongodb/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/java-mongodb/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/liquibase/pom.xml b/persistence-modules/liquibase/pom.xml index a18ced0d71..cb2bee8d48 100644 --- a/persistence-modules/liquibase/pom.xml +++ b/persistence-modules/liquibase/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 liquibase @@ -20,7 +20,7 @@ - baeldung-liquibase-demo + liquibase org.liquibase diff --git a/persistence-modules/liquibase/src/main/resources/logback.xml b/persistence-modules/liquibase/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/liquibase/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/querydsl/pom.xml b/persistence-modules/querydsl/pom.xml index 4c20d673a3..d3bf1b1fb7 100644 --- a/persistence-modules/querydsl/pom.xml +++ b/persistence-modules/querydsl/pom.xml @@ -1,6 +1,6 @@ + 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 querydsl @@ -147,8 +147,6 @@ - UTF-8 - 1.8 4.3.4.RELEASE 5.2.5.Final 1.0.0.Final diff --git a/persistence-modules/redis/pom.xml b/persistence-modules/redis/pom.xml index 7f7aeda4ad..e5a39d6eac 100644 --- a/persistence-modules/redis/pom.xml +++ b/persistence-modules/redis/pom.xml @@ -1,13 +1,10 @@ - - + 4.0.0 com.baeldung redis 0.1-SNAPSHOT - redis http://maven.apache.org @@ -24,31 +21,27 @@ jedis ${jedis.version} - com.github.kstyrc embedded-redis ${embedded-redis.version} - org.redisson redisson - 3.3.0 + ${redisson.version} - io.lettuce lettuce-core - 5.0.1.RELEASE + ${lettuce-core.version} - - UTF-8 - 2.9.0 0.6 + 3.3.0 + 5.0.1.RELEASE diff --git a/persistence-modules/redis/src/main/resources/logback.xml b/persistence-modules/redis/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/redis/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/solr/pom.xml b/persistence-modules/solr/pom.xml index 34a9722af3..49f2f85856 100644 --- a/persistence-modules/solr/pom.xml +++ b/persistence-modules/solr/pom.xml @@ -1,6 +1,5 @@ - + 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 solr @@ -15,16 +14,16 @@ ../../ - - UTF-8 - - org.apache.solr solr-solrj - 6.4.1 + ${solr.version} + + 6.4.1 + + \ No newline at end of file diff --git a/persistence-modules/solr/src/main/resources/logback.xml b/persistence-modules/solr/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/solr/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-cassandra/pom.xml b/persistence-modules/spring-data-cassandra/pom.xml index b11a1fd07b..11953a734b 100644 --- a/persistence-modules/spring-data-cassandra/pom.xml +++ b/persistence-modules/spring-data-cassandra/pom.xml @@ -1,5 +1,5 @@ + 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 spring-data-cassandra @@ -10,8 +10,8 @@ com.baeldung parent-spring-4 - 0.0.1-SNAPSHOT - ../../parent-spring-4 + 0.0.1-SNAPSHOT + ../../parent-spring-4 @@ -75,7 +75,6 @@ - UTF-8 1.3.2.RELEASE 2.1.5 2.1.9.2 diff --git a/persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..46ee3cd368 --- /dev/null +++ b/persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,67 @@ +package org.baeldung; + +import java.io.IOException; +import java.util.HashMap; + +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.thrift.transport.TTransportException; +import org.baeldung.spring.data.cassandra.config.CassandraConfig; +import org.baeldung.spring.data.cassandra.model.Book; +import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cassandra.core.cql.CqlIdentifier; +import org.springframework.data.cassandra.core.CassandraAdminOperations; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Session; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = CassandraConfig.class) +public class SpringContextIntegrationTest { + + public static final String KEYSPACE_CREATION_QUERY = "CREATE KEYSPACE IF NOT EXISTS testKeySpace " + "WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '3' };"; + + public static final String KEYSPACE_ACTIVATE_QUERY = "USE testKeySpace;"; + + public static final String DATA_TABLE_NAME = "book"; + + @Autowired + private CassandraAdminOperations adminTemplate; + + @BeforeClass + public static void startCassandraEmbedded() throws InterruptedException, TTransportException, ConfigurationException, IOException { + EmbeddedCassandraServerHelper.startEmbeddedCassandra(); + final Cluster cluster = Cluster.builder().addContactPoints("127.0.0.1").withPort(9142).build(); + final Session session = cluster.connect(); + session.execute(KEYSPACE_CREATION_QUERY); + session.execute(KEYSPACE_ACTIVATE_QUERY); + Thread.sleep(5000); + } + + @Before + public void createTable() throws InterruptedException, TTransportException, ConfigurationException, IOException { + adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap()); + } + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } + + @After + public void dropTable() { + adminTemplate.dropTable(CqlIdentifier.cqlId(DATA_TABLE_NAME)); + } + + @AfterClass + public static void stopCassandraEmbedded() { + EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); + } +} diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index b1b7c8237b..4cb805131a 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -1,12 +1,12 @@ + 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 - spring-boot-dynamodb + spring-data-dynamodb 0.0.1-SNAPSHOT jar - Spring Boot Actuator - This is simple boot application for Spring boot actuator test + spring-data-dynamodb + This is simple boot application for Spring boot dynamodb test parent-boot-1 @@ -154,70 +154,16 @@ org.apache.maven.plugins maven-war-plugin
    - - org.apache.maven.plugins - maven-dependency-plugin - 2.10 - - - copy-dependencies - test-compile - - copy-dependencies - - - test - so,dll,dylib - ${project.basedir}/native-libs - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - dynamodb-local DynamoDB Local Release Repository ${dynamodblocal.repository.url} - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - diff --git a/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java index 271c1e29ab..9278c0a12e 100644 --- a/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java +++ b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java @@ -1,14 +1,18 @@ package com.baeldung.spring.data.dynamodb.config; +import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; +import org.springframework.web.servlet.handler.HandlerMappingIntrospector; + import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; -import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; @Configuration @EnableDynamoDBRepositories(basePackages = "com.baeldung.spring.data.dynamodb.repositories") @@ -22,6 +26,9 @@ public class DynamoDBConfig { @Value("${amazon.aws.secretkey}") private String amazonAWSSecretKey; + + @Autowired + private ApplicationContext context; @Bean public AmazonDynamoDB amazonDynamoDB() { @@ -37,4 +44,8 @@ public class DynamoDBConfig { return new BasicAWSCredentials(amazonAWSAccessKey, amazonAWSSecretKey); } + @Bean(name = "mvcHandlerMappingIntrospector") + public HandlerMappingIntrospector mvcHandlerMappingIntrospector() { + return new HandlerMappingIntrospector(context); + } } diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-data-dynamodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7f906bdbcd --- /dev/null +++ b/persistence-modules/spring-data-dynamodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-data-eclipselink/pom.xml b/persistence-modules/spring-data-eclipselink/pom.xml index 524175fcd4..618fa83ee5 100644 --- a/persistence-modules/spring-data-eclipselink/pom.xml +++ b/persistence-modules/spring-data-eclipselink/pom.xml @@ -1,10 +1,8 @@ + 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 spring-data-eclipselink - 1.0.0-SNAPSHOT spring-data-eclipselink @@ -20,7 +18,6 @@ spring-boot-dependencies ${spring.version} pom - import org.springframework.boot @@ -68,9 +65,6 @@ - UTF-8 - UTF-8 - 1.8 1.5.9.RELEASE 2.7.0 1.4.196 diff --git a/persistence-modules/spring-data-eclipselink/src/main/resources/logback.xml b/persistence-modules/spring-data-eclipselink/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-eclipselink/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-data-eclipselink/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..4be5891e3e --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.eclipselink.springdata.EclipselinkSpringDataApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = EclipselinkSpringDataApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-data-gemfire/pom.xml b/persistence-modules/spring-data-gemfire/pom.xml index 479eb0c55f..34346c502f 100644 --- a/persistence-modules/spring-data-gemfire/pom.xml +++ b/persistence-modules/spring-data-gemfire/pom.xml @@ -1,6 +1,6 @@ + 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 spring-data-gemfire diff --git a/persistence-modules/spring-data-gemfire/src/main/resources/logback.xml b/persistence-modules/spring-data-gemfire/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/spring-data-gemfire/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-gemfire/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-data-gemfire/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2f0557ccc1 --- /dev/null +++ b/persistence-modules/spring-data-gemfire/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.spring.data.gemfire.function.GemfireConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes=GemfireConfiguration.class, loader=AnnotationConfigContextLoader.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-data-neo4j/pom.xml b/persistence-modules/spring-data-neo4j/pom.xml index 3405e98edb..2be4df71be 100644 --- a/persistence-modules/spring-data-neo4j/pom.xml +++ b/persistence-modules/spring-data-neo4j/pom.xml @@ -1,8 +1,6 @@ - + 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 spring-data-neo4j 1.0 @@ -19,65 +17,44 @@ neo4j ${neo4j.version} - org.neo4j neo4j-ogm-core ${neo4j-ogm.version} - org.neo4j neo4j-ogm-embedded-driver ${neo4j-ogm.version} - org.neo4j.driver neo4j-java-driver ${neo4j-java-driver.version} - org.springframework.data spring-data-neo4j ${spring-data-neo4j.version} - - - commons-logging - commons-logging - - - - - org.springframework.data - spring-data-neo4j - ${spring-data-neo4j.version} - test-jar - - com.voodoodyne.jackson.jsog jackson-jsog ${jackson-jsog.version} compile - org.springframework.boot spring-boot-starter-test ${spring-boot.version} test - org.neo4j neo4j-kernel ${neo4j.version} test-jar - org.neo4j.app neo4j-server @@ -90,14 +67,12 @@ - org.neo4j neo4j-ogm-test ${neo4j-ogm.version} test - org.neo4j.test neo4j-harness @@ -108,25 +83,17 @@ org.springframework spring-test ${spring-test.version} - - - commons-logging - commons-logging - - - UTF-8 - UTF-8 - 1.1.1 - 3.1.0 - 4.1.6.RELEASE + 1.6.2 + 3.4.6 + 5.0.1.RELEASE 1.1 - 1.4.3.RELEASE - 4.3.5.RELEASE - 2.1.1 + 2.0.1.RELEASE + 5.0.1.RELEASE + 3.1.2 diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java index 344282d665..9bbc571aee 100644 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java @@ -1,5 +1,6 @@ package com.baeldung.spring.data.neo4j.config; +import org.neo4j.ogm.config.Configuration.Builder; import org.neo4j.ogm.session.SessionFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -8,15 +9,14 @@ import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; @ComponentScan(basePackages = { "com.baeldung.spring.data.neo4j.services" }) @Configuration -@EnableNeo4jRepositories(basePackages = "com.baeldung.spring.data.neo4j.repostory") +@EnableNeo4jRepositories(basePackages = "com.baeldung.spring.data.neo4j.repository") public class MovieDatabaseNeo4jConfiguration { public static final String URL = System.getenv("NEO4J_URL") != null ? System.getenv("NEO4J_URL") : "http://neo4j:movies@localhost:7474"; @Bean public org.neo4j.ogm.config.Configuration getConfiguration() { - org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration(); - config.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver").setURI(URL); + org.neo4j.ogm.config.Configuration config = new Builder().uri(URL).build(); return config; } diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java index fda478e5be..a4cbe4b809 100644 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java @@ -1,26 +1,25 @@ package com.baeldung.spring.data.neo4j.config; +import org.neo4j.ogm.config.Configuration.Builder; import org.neo4j.ogm.session.SessionFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; -import org.springframework.data.neo4j.config.Neo4jConfiguration; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; +import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement @ComponentScan(basePackages = { "com.baeldung.spring.data.neo4j.services" }) -@EnableNeo4jRepositories(basePackages = "com.baeldung.spring.data.neo4j.repostory") +@EnableNeo4jRepositories(basePackages = "com.baeldung.spring.data.neo4j.repository") @Profile({ "embedded", "test" }) -public class MovieDatabaseNeo4jTestConfiguration extends Neo4jConfiguration { +public class MovieDatabaseNeo4jTestConfiguration { @Bean public org.neo4j.ogm.config.Configuration getConfiguration() { - final org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration(); - config.driverConfiguration() - .setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver"); + org.neo4j.ogm.config.Configuration config = new Builder().build(); return config; } @@ -28,5 +27,10 @@ public class MovieDatabaseNeo4jTestConfiguration extends Neo4jConfiguration { public SessionFactory getSessionFactory() { return new SessionFactory(getConfiguration(), "com.baeldung.spring.data.neo4j.domain"); } + + @Bean + public Neo4jTransactionManager transactionManager() { + return new Neo4jTransactionManager(getSessionFactory()); + } } diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java index f2325a334f..455407a92b 100644 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java @@ -1,12 +1,13 @@ package com.baeldung.spring.data.neo4j.domain; -import org.neo4j.ogm.annotation.GraphId; +import org.neo4j.ogm.annotation.GeneratedValue; +import org.neo4j.ogm.annotation.Id; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; @NodeEntity public class Car { - @GraphId + @Id @GeneratedValue private Long id; private String make; diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Movie.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Movie.java index 029754c0fc..996a661b07 100644 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Movie.java +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Movie.java @@ -2,7 +2,9 @@ package com.baeldung.spring.data.neo4j.domain; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.voodoodyne.jackson.jsog.JSOGGenerator; -import org.neo4j.ogm.annotation.GraphId; + +import org.neo4j.ogm.annotation.GeneratedValue; +import org.neo4j.ogm.annotation.Id; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; @@ -13,7 +15,7 @@ import java.util.List; @NodeEntity public class Movie { - @GraphId + @Id @GeneratedValue Long id; private String title; diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Person.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Person.java index dc5a850f29..453ca1c3f3 100644 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Person.java +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Person.java @@ -2,7 +2,9 @@ package com.baeldung.spring.data.neo4j.domain; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.voodoodyne.jackson.jsog.JSOGGenerator; -import org.neo4j.ogm.annotation.GraphId; + +import org.neo4j.ogm.annotation.GeneratedValue; +import org.neo4j.ogm.annotation.Id; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; @@ -11,7 +13,7 @@ import java.util.List; @JsonIdentityInfo(generator = JSOGGenerator.class) @NodeEntity public class Person { - @GraphId + @Id @GeneratedValue Long id; private String name; diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Role.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Role.java index 40dabb054b..5a18837dae 100644 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Role.java +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Role.java @@ -3,7 +3,8 @@ package com.baeldung.spring.data.neo4j.domain; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.voodoodyne.jackson.jsog.JSOGGenerator; import org.neo4j.ogm.annotation.EndNode; -import org.neo4j.ogm.annotation.GraphId; +import org.neo4j.ogm.annotation.GeneratedValue; +import org.neo4j.ogm.annotation.Id; import org.neo4j.ogm.annotation.RelationshipEntity; import org.neo4j.ogm.annotation.StartNode; @@ -12,8 +13,8 @@ import java.util.Collection; @JsonIdentityInfo(generator = JSOGGenerator.class) @RelationshipEntity(type = "ACTED_IN") public class Role { - @GraphId - Long id; + @Id @GeneratedValue + Long id; private Collection roles; @StartNode private Person person; diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repository/MovieRepository.java similarity index 78% rename from persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repository/MovieRepository.java index afb82551e7..dde946ea73 100644 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repository/MovieRepository.java @@ -1,8 +1,8 @@ -package com.baeldung.spring.data.neo4j.repostory; +package com.baeldung.spring.data.neo4j.repository; import com.baeldung.spring.data.neo4j.domain.Movie; import org.springframework.data.neo4j.annotation.Query; -import org.springframework.data.neo4j.repository.GraphRepository; +import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @@ -11,7 +11,7 @@ import java.util.List; import java.util.Map; @Repository -public interface MovieRepository extends GraphRepository { +public interface MovieRepository extends Neo4jRepository { Movie findByTitle(@Param("title") String title); diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repository/PersonRepository.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repository/PersonRepository.java new file mode 100644 index 0000000000..22094d26b6 --- /dev/null +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repository/PersonRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.data.neo4j.repository; + +import com.baeldung.spring.data.neo4j.domain.Person; +import org.springframework.data.neo4j.repository.Neo4jRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PersonRepository extends Neo4jRepository { +} diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java deleted file mode 100644 index 4ac40ef75b..0000000000 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.baeldung.spring.data.neo4j.repostory; - -import com.baeldung.spring.data.neo4j.domain.Person; -import org.springframework.data.neo4j.repository.GraphRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface PersonRepository extends GraphRepository { -} diff --git a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java index ae1f6eb8e5..086bf48bfa 100644 --- a/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java +++ b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java @@ -1,10 +1,11 @@ package com.baeldung.spring.data.neo4j.services; -import com.baeldung.spring.data.neo4j.repostory.MovieRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.baeldung.spring.data.neo4j.repository.MovieRepository; + import java.util.*; @Service diff --git a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java index 06b31667dd..96e5e76402 100644 --- a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java +++ b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java @@ -12,14 +12,12 @@ import org.neo4j.ogm.session.SessionFactory; import com.baeldung.spring.data.neo4j.domain.Car; import com.baeldung.spring.data.neo4j.domain.Company; -import org.neo4j.ogm.transaction.Transaction; public class Neo4jOgmLiveTest { @Test public void testOgm() { - Configuration conf = new Configuration(); - conf.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver"); + Configuration conf = new Configuration.Builder().build(); SessionFactory factory = new SessionFactory(conf, "com.baeldung.spring.data.neo4j.domain"); Session session = factory.openSession(); diff --git a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/spring/data/neo4j/MovieRepositoryIntegrationTest.java b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/spring/data/neo4j/MovieRepositoryIntegrationTest.java index 95bc38aafc..3d9215f32f 100644 --- a/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/spring/data/neo4j/MovieRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/spring/data/neo4j/MovieRepositoryIntegrationTest.java @@ -4,8 +4,9 @@ import com.baeldung.spring.data.neo4j.config.MovieDatabaseNeo4jTestConfiguration import com.baeldung.spring.data.neo4j.domain.Movie; import com.baeldung.spring.data.neo4j.domain.Person; import com.baeldung.spring.data.neo4j.domain.Role; -import com.baeldung.spring.data.neo4j.repostory.MovieRepository; -import com.baeldung.spring.data.neo4j.repostory.PersonRepository; +import com.baeldung.spring.data.neo4j.repository.MovieRepository; +import com.baeldung.spring.data.neo4j.repository.PersonRepository; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,10 +51,10 @@ public class MovieRepositoryIntegrationTest { Role charlie = new Role(); charlie.setMovie(italianJob); charlie.setPerson(mark); - Collection roleNames = new HashSet(); + Collection roleNames = new HashSet<>(); roleNames.add("Charlie Croker"); charlie.setRoles(roleNames); - List roles = new ArrayList(); + List roles = new ArrayList<>(); roles.add(charlie); italianJob.setRoles(roles); movieRepository.save(italianJob); diff --git a/persistence-modules/spring-data-neo4j/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-data-neo4j/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ea32ed324b --- /dev/null +++ b/persistence-modules/spring-data-neo4j/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.neo4j.config.MovieDatabaseNeo4jTestConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MovieDatabaseNeo4jTestConfiguration.class) +@ActiveProfiles(profiles = "test") +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index c5e0049e83..bee3d683b8 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -1,6 +1,5 @@ - + 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 spring-data-redis @@ -8,17 +7,61 @@ jar + parent-boot-2 com.baeldung - parent-spring-5 - 0.0.1-SNAPSHOT - ../../parent-spring-5 + 0.0.1-SNAPSHOT + ../../parent-boot-2 - org.springframework.data - spring-data-redis - ${spring-data-redis} + org.springframework.boot + spring-boot-starter-data-redis-reactive + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + + + io.projectreactor + reactor-test + test + + + + org.springframework + spring-test + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.junit.jupiter + junit-jupiter-api + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test @@ -34,31 +77,6 @@ jar - - org.springframework - spring-core - ${spring.version} - - - commons-logging - commons-logging - - - - - - org.springframework - spring-context - ${spring.version} - - - - org.springframework - spring-test - ${spring.version} - test - - com.lordofthejars nosqlunit-redis @@ -66,19 +84,20 @@ - org.springframework.data - spring-data-commons - ${spring-data-commons.version} + com.github.kstyrc + embedded-redis + ${embedded-redis.version} - UTF-8 - 2.0.3.RELEASE 3.2.4 2.9.0 0.10.0 2.0.3.RELEASE + 0.6 + 1.0.0 + 5.0.2 diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/SpringRedisReactiveApplication.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/SpringRedisReactiveApplication.java new file mode 100644 index 0000000000..8b1f892f67 --- /dev/null +++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/SpringRedisReactiveApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.data.reactive.redis; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringRedisReactiveApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringRedisReactiveApplication.class, args); + } + +} diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/config/RedisConfig.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/config/RedisConfig.java new file mode 100644 index 0000000000..d23d0092eb --- /dev/null +++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/config/RedisConfig.java @@ -0,0 +1,56 @@ +package com.baeldung.spring.data.reactive.redis.config; + + +import com.baeldung.spring.data.reactive.redis.model.Employee; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.ReactiveKeyCommands; +import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; +import org.springframework.data.redis.connection.ReactiveStringCommands; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.ReactiveRedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import javax.annotation.PreDestroy; + +@Configuration +public class RedisConfig { + + @Autowired + RedisConnectionFactory factory; + + @Bean + public ReactiveRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) { + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Employee.class); + RedisSerializationContext.RedisSerializationContextBuilder builder = RedisSerializationContext.newSerializationContext(new StringRedisSerializer()); + RedisSerializationContext context = builder.value(serializer) + .build(); + return new ReactiveRedisTemplate<>(factory, context); + } + + @Bean + public ReactiveRedisTemplate reactiveRedisTemplateString(ReactiveRedisConnectionFactory connectionFactory) { + return new ReactiveRedisTemplate<>(connectionFactory, RedisSerializationContext.string()); + } + + @Bean + public ReactiveKeyCommands keyCommands(final ReactiveRedisConnectionFactory reactiveRedisConnectionFactory) { + return reactiveRedisConnectionFactory.getReactiveConnection() + .keyCommands(); + } + + @Bean + public ReactiveStringCommands stringCommands(final ReactiveRedisConnectionFactory reactiveRedisConnectionFactory) { + return reactiveRedisConnectionFactory.getReactiveConnection() + .stringCommands(); + } + + @PreDestroy + public void cleanRedis() { + factory.getConnection() + .flushDb(); + } +} diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/model/Employee.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/model/Employee.java new file mode 100644 index 0000000000..9178f6e112 --- /dev/null +++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/reactive/redis/model/Employee.java @@ -0,0 +1,21 @@ +package com.baeldung.spring.data.reactive.redis.model; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@ToString +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode +public class Employee implements Serializable { + private static final long serialVersionUID = 1603714798906422731L; + private String id; + private String name; + private String department; +} diff --git a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java index 4ea8bb4bc0..6fdb3c5bef 100644 --- a/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java +++ b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java @@ -1,8 +1,12 @@ package com.baeldung.spring.data.redis.config; +import com.baeldung.spring.data.redis.queue.MessagePublisher; +import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; +import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.listener.ChannelTopic; @@ -11,13 +15,10 @@ import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.data.redis.serializer.GenericToStringSerializer; -import com.baeldung.spring.data.redis.queue.MessagePublisher; -import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; -import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; - @Configuration @ComponentScan("com.baeldung.spring.data.redis") @EnableRedisRepositories(basePackages = "com.baeldung.spring.data.redis.repo") +@PropertySource("classpath:application.properties") public class RedisConfig { @Bean diff --git a/spring-session/src/main/resources/application.properties b/persistence-modules/spring-data-redis/src/main/resources/application.properties similarity index 100% rename from spring-session/src/main/resources/application.properties rename to persistence-modules/spring-data-redis/src/main/resources/application.properties diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisKeyCommandsIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisKeyCommandsIntegrationTest.java new file mode 100644 index 0000000000..e48aa1e06a --- /dev/null +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisKeyCommandsIntegrationTest.java @@ -0,0 +1,51 @@ +package com.baeldung.spring.data.reactive.redis.template; + + +import com.baeldung.spring.data.reactive.redis.SpringRedisReactiveApplication; +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.data.redis.connection.ReactiveKeyCommands; +import org.springframework.data.redis.connection.ReactiveStringCommands; +import org.springframework.data.redis.connection.ReactiveStringCommands.SetCommand; +import org.springframework.test.context.junit4.SpringRunner; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.nio.ByteBuffer; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringRedisReactiveApplication.class) +public class RedisKeyCommandsIntegrationTest { + + @Autowired + private ReactiveKeyCommands keyCommands; + + @Autowired + private ReactiveStringCommands stringCommands; + + @Test + public void givenFluxOfKeys_whenPerformOperations_thenPerformOperations() { + Flux keys = Flux.just("key1", "key2", "key3", "key4"); + + Flux generator = keys.map(String::getBytes) + .map(ByteBuffer::wrap) + .map(key -> SetCommand.set(key) + .value(key)); + + StepVerifier.create(stringCommands.set(generator)) + .expectNextCount(4L) + .verifyComplete(); + + Mono keyCount = keyCommands.keys(ByteBuffer.wrap("key*".getBytes())) + .flatMapMany(Flux::fromIterable) + .count(); + + StepVerifier.create(keyCount) + .expectNext(4L) + .verifyComplete(); + + } +} diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateListOpsIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateListOpsIntegrationTest.java new file mode 100644 index 0000000000..3ebeff87b1 --- /dev/null +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateListOpsIntegrationTest.java @@ -0,0 +1,49 @@ +package com.baeldung.spring.data.reactive.redis.template; + + +import com.baeldung.spring.data.reactive.redis.SpringRedisReactiveApplication; +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.data.redis.core.ReactiveListOperations; +import org.springframework.data.redis.core.ReactiveRedisTemplate; +import org.springframework.test.context.junit4.SpringRunner; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringRedisReactiveApplication.class) +public class RedisTemplateListOpsIntegrationTest { + + private static final String LIST_NAME = "demo_list"; + + @Autowired + private ReactiveRedisTemplate redisTemplate; + + private ReactiveListOperations reactiveListOps; + + @Before + public void setup() { + reactiveListOps = redisTemplate.opsForList(); + } + + @Test + public void givenListAndValues_whenLeftPushAndLeftPop_thenLeftPushAndLeftPop() { + Mono lPush = reactiveListOps.leftPushAll(LIST_NAME, "first", "second") + .log("Pushed"); + + StepVerifier.create(lPush) + .expectNext(2L) + .verifyComplete(); + + Mono lPop = reactiveListOps.leftPop(LIST_NAME) + .log("Popped"); + + StepVerifier.create(lPop) + .expectNext("second") + .verifyComplete(); + } + +} diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateValueOpsIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateValueOpsIntegrationTest.java new file mode 100644 index 0000000000..9490568089 --- /dev/null +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateValueOpsIntegrationTest.java @@ -0,0 +1,71 @@ +package com.baeldung.spring.data.reactive.redis.template; + + +import com.baeldung.spring.data.reactive.redis.SpringRedisReactiveApplication; +import com.baeldung.spring.data.reactive.redis.model.Employee; +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.data.redis.core.ReactiveRedisTemplate; +import org.springframework.data.redis.core.ReactiveValueOperations; +import org.springframework.test.context.junit4.SpringRunner; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.time.Duration; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringRedisReactiveApplication.class) +public class RedisTemplateValueOpsIntegrationTest { + + @Autowired + private ReactiveRedisTemplate redisTemplate; + + private ReactiveValueOperations reactiveValueOps; + + @Before + public void setup() { + reactiveValueOps = redisTemplate.opsForValue(); + } + + @Test + public void givenEmployee_whenSet_thenSet() { + + Mono result = reactiveValueOps.set("123", new Employee("123", "Bill", "Accounts")); + + StepVerifier.create(result) + .expectNext(true) + .verifyComplete(); + } + + @Test + public void givenEmployeeId_whenGet_thenReturnsEmployee() { + + Mono fetchedEmployee = reactiveValueOps.get("123"); + + StepVerifier.create(fetchedEmployee) + .expectNext(new Employee("123", "Bill", "Accounts")) + .verifyComplete(); + } + + @Test + public void givenEmployee_whenSetWithExpiry_thenSetsWithExpiryTime() throws InterruptedException { + + Mono result = reactiveValueOps.set("129", new Employee("129", "John", "Programming"), Duration.ofSeconds(1)); + + Mono fetchedEmployee = reactiveValueOps.get("129"); + + StepVerifier.create(result) + .expectNext(true) + .verifyComplete(); + + Thread.sleep(2000L); + + StepVerifier.create(fetchedEmployee) + .expectNextCount(0L) + .verifyComplete(); + } + +} diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java index 01dbfcff4d..99febb6430 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java @@ -1,24 +1,44 @@ package com.baeldung.spring.data.redis; -import com.baeldung.spring.data.redis.config.RedisConfig; -import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; -import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; -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 java.util.UUID; - import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.UUID; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.redis.config.RedisConfig; +import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; +import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class RedisMessageListenerIntegrationTest { + private static redis.embedded.RedisServer redisServer; + @Autowired private RedisMessagePublisher redisMessagePublisher; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new redis.embedded.RedisServer(6380); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Test public void testOnMessage() throws Exception { diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java index 66ef3c21b2..43aadefc01 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java @@ -3,13 +3,17 @@ package com.baeldung.spring.data.redis.repo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -18,10 +22,24 @@ import com.baeldung.spring.data.redis.model.Student; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class StudentRepositoryIntegrationTest { @Autowired private StudentRepository studentRepository; + + private static redis.embedded.RedisServer redisServer; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new redis.embedded.RedisServer(6380); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Test public void whenSavingStudent_thenAvailableOnRetrieval() throws Exception { diff --git a/persistence-modules/spring-data-redis/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..e093892365 --- /dev/null +++ b/persistence-modules/spring-data-redis/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.redis.config.RedisConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = RedisConfig.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-data-solr/pom.xml b/persistence-modules/spring-data-solr/pom.xml index 036b40a7ed..dcba80b49a 100644 --- a/persistence-modules/spring-data-solr/pom.xml +++ b/persistence-modules/spring-data-solr/pom.xml @@ -1,6 +1,5 @@ - + 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 spring-data-solr @@ -11,8 +10,8 @@ com.baeldung parent-spring-4 - 0.0.1-SNAPSHOT - ../../parent-spring-4 + 0.0.1-SNAPSHOT + ../../parent-spring-4 @@ -46,7 +45,6 @@ - UTF-8 2.0.5.RELEASE diff --git a/persistence-modules/spring-data-solr/src/main/resources/logback.xml b/persistence-modules/spring-data-solr/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/persistence-modules/spring-data-solr/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java b/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryLiveTest.java similarity index 98% rename from persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java rename to persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryLiveTest.java index a3765a74ec..f86adcdc8a 100644 --- a/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryLiveTest.java @@ -20,7 +20,7 @@ import com.baeldung.spring.data.solr.repository.ProductRepository; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SolrConfig.class) -public class ProductRepositoryIntegrationTest { +public class ProductRepositoryLiveTest { @Autowired private ProductRepository productRepository; diff --git a/persistence-modules/spring-data-solr/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-data-solr/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..e76967ae8a --- /dev/null +++ b/persistence-modules/spring-data-solr/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.solr.config.SolrConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = SolrConfig.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-hibernate-3/pom.xml b/persistence-modules/spring-hibernate-3/pom.xml index 3233dd11fe..6c1bdace30 100644 --- a/persistence-modules/spring-hibernate-3/pom.xml +++ b/persistence-modules/spring-hibernate-3/pom.xml @@ -1,5 +1,5 @@ + 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 spring-hibernate-3 @@ -86,24 +86,15 @@ 4.3.4.RELEASE - 4.2.0.RELEASE 3.21.0-GA 3.6.10.Final 5.1.40 8.5.8 1.4.193 - - 5.3.3.Final 19.0 3.5 - 4.4.5 - 4.5.2 - 2.9.0 - - 2.7 - 1.6.1 diff --git a/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml index 09314c67b1..263e902e7c 100644 --- a/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml +++ b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml @@ -17,7 +17,7 @@ - + diff --git a/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml b/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml index e7ef9ad765..f39817383b 100644 --- a/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml +++ b/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml @@ -5,7 +5,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd" > - + diff --git a/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..a81a4eedb1 --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.baeldung.spring.PersistenceConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/spring-hibernate-5/README.md b/persistence-modules/spring-hibernate-5/README.md index d48723ac31..b4d73708c3 100644 --- a/persistence-modules/spring-hibernate-5/README.md +++ b/persistence-modules/spring-hibernate-5/README.md @@ -3,3 +3,4 @@ - [Guide to @Immutable Annotation in Hibernate](http://www.baeldung.com/hibernate-immutable) - [Hibernate Many to Many Annotation Tutorial](http://www.baeldung.com/hibernate-many-to-many) - [Programmatic Transactions in the Spring TestContext Framework](http://www.baeldung.com/spring-test-programmatic-transactions) +- [Hibernate Criteria Queries](http://www.baeldung.com/hibernate-criteria-queries) diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index de66d9e6f7..832cf8dca7 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -93,12 +93,6 @@ ${org.springframework.version} test - - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - org.springframework.security spring-security-test @@ -106,20 +100,6 @@ test - - junit - junit-dep - 4.11 - test - - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - org.hsqldb hsqldb @@ -155,7 +135,6 @@ 5.0.2.RELEASE 1.10.6.RELEASE 4.2.1.RELEASE - 1.10.6.RELEASE 5.2.10.Final @@ -166,31 +145,10 @@ 2.3.4 1.4.195 - - 1.7.21 - 1.1.7 - - - 5.4.0.Final - 2.2.5 - 21.0 3.5 - - 1.3 - 4.12 - 4.4.1 - 4.5 - 2.9.0 - - - 3.7.0 - 2.19.1 - 2.7 - 1.6.1 -
    diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/model/Item.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/model/Item.java new file mode 100644 index 0000000000..957207b7e6 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/model/Item.java @@ -0,0 +1,81 @@ +package com.baeldung.hibernate.criteria.model; + +import java.io.Serializable; + +public class Item implements Serializable { + + private static final long serialVersionUID = 1L; + private Integer itemId; + private String itemName; + private String itemDescription; + private Integer itemPrice; + + // constructors + public Item() { + + } + + public Item(final Integer itemId, final String itemName, final String itemDescription) { + super(); + this.itemId = itemId; + this.itemName = itemName; + this.itemDescription = itemDescription; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((itemId == null) ? 0 : itemId.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final Item other = (Item) obj; + if (itemId == null) { + if (other.itemId != null) + return false; + } else if (!itemId.equals(other.itemId)) + return false; + return true; + } + + public Integer getItemId() { + return itemId; + } + + public void setItemId(final Integer itemId) { + this.itemId = itemId; + } + + public String getItemName() { + return itemName; + } + + public void setItemName(final String itemName) { + this.itemName = itemName; + } + + public String getItemDescription() { + return itemDescription; + } + + public Integer getItemPrice() { + return itemPrice; + } + + public void setItemPrice(final Integer itemPrice) { + this.itemPrice = itemPrice; + } + + public void setItemDescription(final String itemDescription) { + this.itemDescription = itemDescription; + } +} diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java similarity index 100% rename from spring-hibernate4/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/util/HibernateUtil.java diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java new file mode 100644 index 0000000000..72d4dea377 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java @@ -0,0 +1,335 @@ +/** + * ApplicationViewer is the class that starts the application + * First it creates the session object and then creates the + * criteria query. + * + * @author Pritam Banerjee + * @version 1.0 + * @since 07/20/2016 + */ + +package com.baeldung.hibernate.criteria.view; + +import java.util.List; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.hibernate.Session; +import org.hibernate.query.Query; + +import com.baeldung.hibernate.criteria.model.Item; +import com.baeldung.hibernate.criteria.util.HibernateUtil; + +public class ApplicationView { + + // default Constructor + public ApplicationView() { + + } + + public boolean checkIfCriteriaTimeLower() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + + // calculate the time taken by criteria + final long startTimeCriteria = System.nanoTime(); + cr.select(root) + .where(cb.like(root.get("itemName"), "%item One%")); + // .add(Restrictions.like("itemName", "%item One%")); + Query query = session.createQuery(cr); + + final List results = query.getResultList(); + final long endTimeCriteria = System.nanoTime(); + final long durationCriteria = (endTimeCriteria - startTimeCriteria) / 1000; + + // calculate the time taken by HQL + final long startTimeHQL = System.nanoTime(); + session.beginTransaction(); + final List items = session.createQuery("FROM Item where itemName like '%item One%'") + .list(); + final long endTimeHQL = System.nanoTime(); + final long durationHQL = (endTimeHQL - startTimeHQL) / 1000; + + if (durationCriteria > durationHQL) { + return false; + } else { + return true; + } + } + + // To get items having price more than 1000 + public String[] greaterThanCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root) + .where(cb.gt(root.get("itemPrice"), 1000)); + // cr.add(Restrictions.gt("itemPrice", 1000)); + Query query = session.createQuery(cr); + final List greaterThanItemsList = query.getResultList(); + final String greaterThanItems[] = new String[greaterThanItemsList.size()]; + for (int i = 0; i < greaterThanItemsList.size(); i++) { + greaterThanItems[i] = greaterThanItemsList.get(i) + .getItemName(); + } + session.close(); + return greaterThanItems; + } + + // To get items having price less than 1000 + public String[] lessThanCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root) + .where(cb.lt(root.get("itemPrice"), 1000)); + // cr.add(Restrictions.lt("itemPrice", 1000)); + Query query = session.createQuery(cr); + final List lessThanItemsList = query.getResultList(); + final String lessThanItems[] = new String[lessThanItemsList.size()]; + for (int i = 0; i < lessThanItemsList.size(); i++) { + lessThanItems[i] = lessThanItemsList.get(i) + .getItemName(); + } + session.close(); + return lessThanItems; + } + + // To get items whose Name start with Chair + public String[] likeCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root) + .where(cb.like(root.get("itemName"), "%chair%")); + // cr.add(Restrictions.like("itemName", "%chair%")); + Query query = session.createQuery(cr); + final List likeItemsList = query.getResultList(); + final String likeItems[] = new String[likeItemsList.size()]; + for (int i = 0; i < likeItemsList.size(); i++) { + likeItems[i] = likeItemsList.get(i) + .getItemName(); + } + session.close(); + return likeItems; + } + + // Case sensitive search + public String[] likeCaseCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root) + .where(cb.like(cb.lower(root.get("itemName")), "%chair%")); + // cr.add(Restrictions.ilike("itemName", "%Chair%")); + Query query = session.createQuery(cr); + final List ilikeItemsList = query.getResultList(); + final String ilikeItems[] = new String[ilikeItemsList.size()]; + for (int i = 0; i < ilikeItemsList.size(); i++) { + ilikeItems[i] = ilikeItemsList.get(i) + .getItemName(); + } + session.close(); + return ilikeItems; + } + + // To get records having itemPrice in between 100 and 200 + public String[] betweenCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root) + .where(cb.between(root.get("itemPrice"), 100, 200)); + // cr.add(Restrictions.between("itemPrice", 100, 200)); + Query query = session.createQuery(cr); + final List betweenItemsList = query.getResultList(); + final String betweenItems[] = new String[betweenItemsList.size()]; + for (int i = 0; i < betweenItemsList.size(); i++) { + betweenItems[i] = betweenItemsList.get(i) + .getItemName(); + } + session.close(); + return betweenItems; + } + + // To check if the given property is null + public String[] nullCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root) + .where(cb.isNull(root.get("itemDescription"))); + // cr.add(Restrictions.isNull("itemDescription")); + Query query = session.createQuery(cr); + final List nullItemsList = query.getResultList(); + final String nullDescItems[] = new String[nullItemsList.size()]; + for (int i = 0; i < nullItemsList.size(); i++) { + nullDescItems[i] = nullItemsList.get(i) + .getItemName(); + } + session.close(); + return nullDescItems; + } + + // To check if the given property is not null + public String[] notNullCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root) + .where(cb.isNotNull(root.get("itemDescription"))); + // cr.add(Restrictions.isNotNull("itemDescription")); + Query query = session.createQuery(cr); + final List notNullItemsList = query.getResultList(); + final String notNullDescItems[] = new String[notNullItemsList.size()]; + for (int i = 0; i < notNullItemsList.size(); i++) { + notNullDescItems[i] = notNullItemsList.get(i) + .getItemName(); + } + session.close(); + return notNullDescItems; + } + + // Adding more than one expression in one cr + public String[] twoCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + Predicate[] predicates = new Predicate[2]; + predicates[0] = cb.isNull(root.get("itemDescription")); + predicates[1] = cb.like(root.get("itemName"), "chair%"); + cr.select(root) + .where(predicates); + // cr.add(Restrictions.isNull("itemDescription")); + // cr.add(Restrictions.like("itemName", "chair%")); + Query query = session.createQuery(cr); + final List notNullItemsList = query.getResultList(); + final String notNullDescItems[] = new String[notNullItemsList.size()]; + for (int i = 0; i < notNullItemsList.size(); i++) { + notNullDescItems[i] = notNullItemsList.get(i) + .getItemName(); + } + session.close(); + return notNullDescItems; + } + + // To get items matching with the above defined conditions joined + // with Logical AND + public String[] andLogicalCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + Predicate greaterThanPrice = cb.gt(root.get("itemPrice"), 1000); + Predicate chairItems = cb.like(root.get("itemName"), "Chair%"); + cr.select(root) + .where(cb.and(greaterThanPrice, chairItems)); + // final Criterion greaterThanPrice = Restrictions.gt("itemPrice", 1000); + // final Criterion chairItems = Restrictions.like("itemName", "Chair%"); + // final LogicalExpression andExample = Restrictions.and(greaterThanPrice, chairItems); + // cr.add(andExample); + Query query = session.createQuery(cr); + final List andItemsList = query.getResultList(); + final String andItems[] = new String[andItemsList.size()]; + for (int i = 0; i < andItemsList.size(); i++) { + andItems[i] = andItemsList.get(i) + .getItemName(); + } + session.close(); + return andItems; + } + + // To get items matching with the above defined conditions joined + // with Logical OR + public String[] orLogicalCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + Predicate greaterThanPrice = cb.gt(root.get("itemPrice"), 1000); + Predicate chairItems = cb.like(root.get("itemName"), "Chair%"); + cr.select(root) + .where(cb.or(greaterThanPrice, chairItems)); + Query query = session.createQuery(cr); + final List orItemsList = query.getResultList(); + final String orItems[] = new String[orItemsList.size()]; + for (int i = 0; i < orItemsList.size(); i++) { + orItems[i] = orItemsList.get(i) + .getItemName(); + } + session.close(); + return orItems; + } + + // Sorting example + public String[] sortingCriteria() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Item.class); + final Root root = cr.from(Item.class); + cr.select(root); + cr.orderBy(cb.asc(root.get("itemName")), cb.desc(root.get("itemPrice"))); + // cr.addOrder(Order.asc("itemName")); + // cr.addOrder(Order.desc("itemPrice")).list(); + Query query = session.createQuery(cr); + final List sortedItemsList = query.getResultList(); + final String sortedItems[] = new String[sortedItemsList.size()]; + for (int i = 0; i < sortedItemsList.size(); i++) { + sortedItems[i] = sortedItemsList.get(i) + .getItemName(); + } + session.close(); + return sortedItems; + } + + // Set projections Row Count + public Long[] projectionRowCount() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Long.class); + final Root root = cr.from(Item.class); + cr.select(cb.count(root)); + Query query = session.createQuery(cr); + final List itemProjected = query.getResultList(); + // session.createCriteria(Item.class).setProjection(Projections.rowCount()).list(); + final Long projectedRowCount[] = new Long[itemProjected.size()]; + for (int i = 0; i < itemProjected.size(); i++) { + projectedRowCount[i] = itemProjected.get(i); + } + session.close(); + return projectedRowCount; + } + + // Set projections average of itemPrice + public Double[] projectionAverage() { + final Session session = HibernateUtil.getHibernateSession(); + final CriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery(Double.class); + final Root root = cr.from(Item.class); + cr.select(cb.avg(root.get("itemPrice"))); + Query query = session.createQuery(cr); + final List avgItemPriceList = query.getResultList(); + // session.createCriteria(Item.class).setProjection(Projections.projectionList().add(Projections.avg("itemPrice"))).list(); + + final Double avgItemPrice[] = new Double[avgItemPriceList.size()]; + for (int i = 0; i < avgItemPriceList.size(); i++) { + avgItemPrice[i] = (Double) avgItemPriceList.get(i); + } + session.close(); + return avgItemPrice; + } + +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java index f1ad30b090..8157945e2c 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java @@ -3,13 +3,15 @@ package com.baeldung.hibernate.manytomany.model; import java.io.Serializable; import java.util.HashSet; import java.util.Set; + import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.JoinTable; import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; @@ -18,7 +20,7 @@ import javax.persistence.Table; public class Employee implements Serializable { @Id @Column(name = "employee_id") - @GeneratedValue + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long employeeId; @Column(name = "first_name") diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java index 6bbd2625fc..d6445c3cb0 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java @@ -50,6 +50,8 @@ public class HibernateSearchConfig { final BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(env.getProperty("jdbc.user")); + dataSource.setPassword(env.getProperty("jdbc.pass")); return dataSource; } diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java index 5dace1f742..44cbfadb25 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java @@ -19,7 +19,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement -@PropertySource({ "classpath:persistence-mysql.properties" }) +@PropertySource({ "classpath:persistence-h2.properties" }) @ComponentScan({ "com.baeldung.hibernate.manytomany" }) public class PersistenceConfig { @@ -61,7 +61,7 @@ public class PersistenceConfig { private final Properties hibernateProperties() { final Properties hibernateProperties = new Properties(); - //hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); hibernateProperties.setProperty("hibernate.show_sql", "true"); diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java index e64f0a4efe..74ac0a269e 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java @@ -21,7 +21,7 @@ import java.util.Properties; @Configuration @EnableTransactionManagement -@PropertySource({ "classpath:persistence-mysql.properties" }) +@PropertySource({ "classpath:persistence-h2.properties" }) @ComponentScan({ "com.baeldung.persistence" }) public class PersistenceConfig { diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/import.sql b/persistence-modules/spring-hibernate-5/src/main/resources/import.sql new file mode 100644 index 0000000000..ae008f29bc --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/resources/import.sql @@ -0,0 +1,31 @@ +insert into item (item_id, item_name, item_desc, item_price) +values(1,'item One', 'test 1', 35.12); + +insert into item (item_id, item_name, item_desc, item_price) +values(2,'Pogo stick', 'Pogo stick', 466.12); +insert into item (item_id, item_name, item_desc, item_price) +values(3,'Raft', 'Raft', 345.12); + +insert into item (item_id, item_name, item_desc, item_price) +values(4,'Skate Board', 'Skating', 135.71); + +insert into item (item_id, item_name, item_desc, item_price) +values(5,'Umbrella', 'Umbrella for Rain', 619.25); + +insert into item (item_id, item_name, item_desc, item_price) +values(6,'Glue', 'Glue for home', 432.73); + +insert into item (item_id, item_name, item_desc, item_price) +values(7,'Paint', 'Paint for Room', 1311.40); + +insert into item (item_id, item_name, item_desc, item_price) +values(8,'Red paint', 'Red paint for room', 1135.71); + +insert into item (item_id, item_name, item_desc, item_price) +values(9,'Household Chairs', 'Chairs for house', 25.71); + +insert into item (item_id, item_name, item_desc, item_price) +values(10,'Office Chairs', 'Chairs for office', 395.98); + +insert into item (item_id, item_name, item_desc, item_price) +values(11,'Outdoor Chairs', 'Chairs for outdoor activities', 1234.36); diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties index 0325174b67..5a137e2310 100644 --- a/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties +++ b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties @@ -3,7 +3,7 @@ jdbc.driverClassName=org.h2.Driver jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 jdbc.eventGeneratedId=sa jdbc.user=sa -jdbc.pass=sa +jdbc.pass= # hibernate.X hibernate.dialect=org.hibernate.dialect.H2Dialect diff --git a/spring-hibernate4/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java similarity index 99% rename from spring-hibernate4/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java rename to persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java index 2275bf14f2..723b097305 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java @@ -43,7 +43,6 @@ public class HibernateCriteriaIntegrationTest { } session.close(); assertArrayEquals(expectedChairCaseItems, av.likeCaseCriteria()); - } @Test diff --git a/spring-hibernate4/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java similarity index 100% rename from spring-hibernate4/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java rename to persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestRunner.java diff --git a/spring-hibernate4/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java similarity index 100% rename from spring-hibernate4/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java rename to persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaTestSuite.java diff --git a/persistence-modules/spring-hibernate-5/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..af4618d0f3 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.spring.PersistenceConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-hibernate4/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml b/persistence-modules/spring-hibernate-5/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml similarity index 100% rename from spring-hibernate4/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml rename to persistence-modules/spring-hibernate-5/src/test/resources/com/baeldung/hibernate/criteria/model/Item.hbm.xml diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml b/persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml new file mode 100644 index 0000000000..bc4fed9680 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/resources/criteria.cfg.xml @@ -0,0 +1,17 @@ + + + + + + org.h2.Driver + jdbc:h2:mem:testdb + sa + + org.hibernate.dialect.H2Dialect + create-drop + false + + + \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/import.sql b/persistence-modules/spring-hibernate-5/src/test/resources/import.sql new file mode 100644 index 0000000000..087d62d331 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/resources/import.sql @@ -0,0 +1,21 @@ +insert into item (item_id, item_name, item_desc, item_price) values(1,'item One', 'test 1', 35.12); + +insert into item (item_id, item_name, item_desc, item_price) values(2,'Pogo stick', 'Pogo stick', 466.12); + +insert into item (item_id, item_name, item_desc, item_price) values(3,'Raft', 'Raft', 345.12); + +insert into item (item_id, item_name, item_desc, item_price) values(4,'Skate Board', 'Skating', 135.71); + +insert into item (item_id, item_name, item_desc, item_price) values(5,'Umbrella', 'Umbrella for Rain', 619.25); + +insert into item (item_id, item_name, item_desc, item_price) values(6,'Glue', 'Glue for home', 432.73); + +insert into item (item_id, item_name, item_desc, item_price) values(7,'Paint', 'Paint for Room', 1311.40); + +insert into item (item_id, item_name, item_desc, item_price) values(8,'Red paint', 'Red paint for room', 1135.71); + +insert into item (item_id, item_name, item_desc, item_price) values(9,'Household Chairs', 'Chairs for house', 25.71); + +insert into item (item_id, item_name, item_desc, item_price) values(10,'Office Chairs', 'Chairs for office', 395.98); + +insert into item (item_id, item_name, item_desc, item_price) values(11,'Outdoor Chairs', 'Chairs for outdoor activities', 1234.36); diff --git a/persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml b/persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml new file mode 100644 index 0000000000..a7a23ec70d --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/resources/manytomany.cfg.xml @@ -0,0 +1,16 @@ + + + + + org.h2.Driver + + jdbc:h2:mem:spring_hibernate_many_to_many + sa + org.hibernate.dialect.H2Dialect + thread + true + create-drop + + diff --git a/persistence-modules/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md index 02d4306ecb..299a5a1e51 100644 --- a/persistence-modules/spring-jpa/README.md +++ b/persistence-modules/spring-jpa/README.md @@ -9,20 +9,16 @@ - [The DAO with JPA and Spring](http://www.baeldung.com/spring-dao-jpa) - [JPA Pagination](http://www.baeldung.com/jpa-pagination) - [Sorting with JPA](http://www.baeldung.com/jpa-sort) -- [Spring JPA – Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases) - [Hibernate Second-Level Cache](http://www.baeldung.com/hibernate-second-level-cache) - [Spring, Hibernate and a JNDI Datasource](http://www.baeldung.com/spring-persistence-jpa-jndi-datasource) - [Deleting Objects with Hibernate](http://www.baeldung.com/delete-with-hibernate) - [Self-Contained Testing Using an In-Memory Database](http://www.baeldung.com/spring-jpa-test-in-memory-database) -- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories) - [A Guide to Spring AbstractRoutingDatasource](http://www.baeldung.com/spring-abstract-routing-data-source) -- [Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced) - [A Guide to Hibernate with Spring 4](http://www.baeldung.com/the-persistence-layer-with-spring-and-jpa) - [Testing REST with multiple MIME types](http://www.baeldung.com/testing-rest-api-with-multiple-media-types) - [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) +- [Use Criteria Queries in a Spring Data Application](https://www.baeldung.com/spring-data-criteria-queries) ### Eclipse Config After importing the project into Eclipse, you may see the following error: diff --git a/persistence-modules/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml index c6762df54b..400811b582 100644 --- a/persistence-modules/spring-jpa/pom.xml +++ b/persistence-modules/spring-jpa/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-jpa 0.1-SNAPSHOT @@ -178,13 +178,8 @@ 21.0 3.5 3.8.0 - 4.4.5 - 4.5.2 - 2.9.0 - 2.7 - 1.6.1 2.6 diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java index 010eb5b8a1..ec0d4bca3c 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java @@ -24,7 +24,7 @@ import com.google.common.base.Preconditions; @Configuration @EnableTransactionManagement -@PropertySource({ "classpath:persistence-mysql.properties" }) +@PropertySource({ "classpath:persistence-h2.properties" }) @ComponentScan({ "org.baeldung.persistence" }) @EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao") public class PersistenceJPAConfig { @@ -78,9 +78,9 @@ public class PersistenceJPAConfig { final Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); - hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache")); - hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache")); - // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", "false"); + + return hibernateProperties; } diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java index 1c8ce5400f..cf6e69eb39 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java @@ -5,7 +5,7 @@ import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatche public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class[] getRootConfigClasses() { - return new Class[] { PersistenceJNDIConfig.class }; + return new Class[] { PersistenceJPAConfig.class }; } @Override diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java deleted file mode 100644 index 7e2efc72bc..0000000000 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.baeldung.extended.persistence.dao; - -import org.baeldung.inmemory.persistence.model.Student; - -public interface ExtendedStudentRepository extends ExtendedRepository { -} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java new file mode 100644 index 0000000000..114cf48c7c --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java @@ -0,0 +1,9 @@ +package org.baeldung.persistence.dao; + +import org.baeldung.persistence.model.Book; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface BookRepository extends JpaRepository, BookRepositoryCustom, JpaSpecificationExecutor { + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java new file mode 100644 index 0000000000..b939907572 --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java @@ -0,0 +1,11 @@ +package org.baeldung.persistence.dao; + +import java.util.List; + +import org.baeldung.persistence.model.Book; + +public interface BookRepositoryCustom { + + List findBooksByAuthorNameAndTitle(String authorName, String title); + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java new file mode 100644 index 0000000000..6e9aa998d7 --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java @@ -0,0 +1,45 @@ +package org.baeldung.persistence.dao; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.baeldung.persistence.model.Book; +import org.springframework.stereotype.Repository; + +@Repository +public class BookRepositoryImpl implements BookRepositoryCustom { + + private EntityManager em; + + public BookRepositoryImpl(EntityManager em) { + this.em = em; + } + + @Override + public List findBooksByAuthorNameAndTitle(String authorName, String title) { + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(Book.class); + + Root book = cq.from(Book.class); + List predicates = new ArrayList<>(); + + if (authorName != null) { + predicates.add(cb.equal(book.get("author"), authorName)); + } + if (title != null) { + predicates.add(cb.like(book.get("title"), "%" + title + "%")); + } + cq.where(predicates.toArray(new Predicate[0])); + + TypedQuery query = em.createQuery(cq); + return query.getResultList(); + } + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java new file mode 100644 index 0000000000..88b769e9bf --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java @@ -0,0 +1,25 @@ +package org.baeldung.persistence.dao; + +import static org.baeldung.persistence.dao.BookSpecifications.hasAuthor; +import static org.baeldung.persistence.dao.BookSpecifications.titleContains; +import static org.springframework.data.jpa.domain.Specifications.where; + +import java.util.List; + +import org.baeldung.persistence.model.Book; +import org.springframework.stereotype.Service; + +@Service +public class BookService { + + private BookRepository bookRepository; + + public BookService(BookRepository bookRepository) { + this.bookRepository = bookRepository; + } + + public List query(String author, String title) { + return bookRepository.findAll(where(hasAuthor(author)).and(titleContains(title))); + } + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java new file mode 100644 index 0000000000..ed9540060d --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java @@ -0,0 +1,16 @@ +package org.baeldung.persistence.dao; + +import org.baeldung.persistence.model.Book; +import org.springframework.data.jpa.domain.Specification; + +public class BookSpecifications { + + public static Specification hasAuthor(String author) { + return (book, cq, cb) -> cb.equal(book.get("author"), author); + } + + public static Specification titleContains(String title) { + return (book, cq, cb) -> cb.like(book.get("title"), "%" + title + "%"); + } + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java new file mode 100644 index 0000000000..754bd179d1 --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java @@ -0,0 +1,36 @@ +package org.baeldung.persistence.model; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Book { + + @Id + private Long id; + + private String title; + + private String author; + + public Long getId() { + return 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; + } + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java index 97b5803d73..7aff5f51d0 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java @@ -1,17 +1,13 @@ package org.baeldung.persistence.multiple.model.user; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; +import javax.persistence.*; @Entity @Table(schema = "spring_jpa_user") public class Possession { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private String name; diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java index 1c6399dc44..6fb9de4a47 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java @@ -1,21 +1,14 @@ package org.baeldung.persistence.multiple.model.user; +import javax.persistence.*; import java.util.List; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; - @Entity @Table(schema = "spring_jpa_user") public class User { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties index 2c3e18b58d..716a96fde3 100644 --- a/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties +++ b/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties @@ -2,7 +2,7 @@ jdbc.driverClassName=org.h2.Driver jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 jdbc.user=sa -# jdbc.pass= +jdbc.pass= # hibernate.X hibernate.dialect=org.hibernate.dialect.H2Dialect diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-multiple-db.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-multiple-db.properties deleted file mode 100644 index 539535528c..0000000000 --- a/persistence-modules/spring-jpa/src/main/resources/persistence-multiple-db.properties +++ /dev/null @@ -1,13 +0,0 @@ -# jdbc.X -jdbc.driverClassName=com.mysql.cj.jdbc.Driver -user.jdbc.url=jdbc:mysql://localhost:3306/spring_jpa_user?createDatabaseIfNotExist=true -product.jdbc.url=jdbc:mysql://localhost:3306/spring_jpa_product?createDatabaseIfNotExist=true -jdbc.user=tutorialuser -jdbc.pass=tutorialmy5ql - -# hibernate.X -hibernate.dialect=org.hibernate.dialect.MySQL5Dialect -hibernate.show_sql=false -hibernate.hbm2ddl.auto=create-drop -hibernate.cache.use_second_level_cache=false -hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties index e1d6bfa45a..405e6ff109 100644 --- a/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties +++ b/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties @@ -2,7 +2,7 @@ jdbc.driverClassName=org.h2.Driver jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 jdbc.user=sa -# jdbc.pass= +jdbc.pass= # hibernate.X hibernate.dialect=org.hibernate.dialect.H2Dialect diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence.xml b/persistence-modules/spring-jpa/src/main/resources/persistence.xml index 5afc0af94d..6304fa0a65 100644 --- a/persistence-modules/spring-jpa/src/main/resources/persistence.xml +++ b/persistence-modules/spring-jpa/src/main/resources/persistence.xml @@ -7,7 +7,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd" > - + @@ -21,8 +21,6 @@ ${hibernate.hbm2ddl.auto} ${hibernate.dialect} - ${hibernate.cache.use_second_level_cache} - ${hibernate.cache.use_query_cache} diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java index f81247e3cd..47355471b9 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java @@ -9,11 +9,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @ContextConfiguration(classes = DataSourceRoutingTestConfiguration.class) +@DirtiesContext public class DataSourceRoutingIntegrationTest { @Autowired diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java index 09d118fedc..e5fb728a0a 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java @@ -10,6 +10,6 @@ public class PersistenceJPAConfigDeletion extends PersistenceJPAConfigL2Cache { @Override protected String[] getPackagesToScan() { - return new String[] { "org.baeldung.persistence.deletion.model" }; + return new String[] { "org.baeldung.persistence.deletion.model", "org.baeldung.persistence.model" }; } } \ No newline at end of file diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/AdvancedTaggingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/AdvancedTaggingIntegrationTest.java index 9432420878..9a90b857e5 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/AdvancedTaggingIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/AdvancedTaggingIntegrationTest.java @@ -11,6 +11,7 @@ import org.baeldung.inmemory.persistence.model.SkillTag; import org.baeldung.inmemory.persistence.model.Student; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @@ -26,6 +27,7 @@ import static org.junit.Assert.assertEquals; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { StudentJpaConfig.class }, loader = AnnotationConfigContextLoader.class) @Transactional +@DirtiesContext public class AdvancedTaggingIntegrationTest { @Resource private StudentRepository studentRepository; diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java index 3d9e376e81..9ddc48460a 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java @@ -5,6 +5,7 @@ import org.baeldung.inmemory.persistence.dao.StudentRepository; import org.baeldung.inmemory.persistence.model.Student; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @@ -20,6 +21,7 @@ import static org.junit.Assert.assertEquals; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { StudentJpaConfig.class }, loader = AnnotationConfigContextLoader.class) @Transactional +@DirtiesContext public class InMemoryDBIntegrationTest { @Resource diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java index f42a4e9be1..0dbb7dbfe8 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java @@ -8,6 +8,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @@ -23,6 +24,7 @@ import static org.junit.Assert.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { PersistenceJPAConfigDeletion.class }, loader = AnnotationConfigContextLoader.class) +@DirtiesContext public class DeletionIntegrationTest { @PersistenceContext diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java index 091bec0ba0..bf49a431e1 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java @@ -16,17 +16,20 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import org.baeldung.config.PersistenceJPAConfig; +import org.baeldung.config.PersistenceJPAConfigL2Cache; import org.baeldung.persistence.model.Foo; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceJPAConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceJPAConfigL2Cache.class }, loader = AnnotationConfigContextLoader.class) +@DirtiesContext public class FooPaginationPersistenceIntegrationTest { @PersistenceContext diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java index 4c57865f74..45316cf06c 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java @@ -3,6 +3,7 @@ package org.baeldung.persistence.service; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import org.baeldung.config.PersistenceJPAConfig; +import org.baeldung.config.PersistenceJPAConfigL2Cache; import org.baeldung.persistence.model.Foo; import org.junit.Assert; import org.junit.Test; @@ -11,12 +12,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceJPAConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceJPAConfigL2Cache.class }, loader = AnnotationConfigContextLoader.class) +@DirtiesContext public class FooServicePersistenceIntegrationTest { @Autowired diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java index 3c9f509da5..61a3bfd565 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java @@ -10,17 +10,19 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; -import org.baeldung.config.PersistenceJPAConfig; +import org.baeldung.config.PersistenceJPAConfigL2Cache; import org.baeldung.persistence.model.Bar; import org.baeldung.persistence.model.Foo; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceJPAConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceJPAConfigL2Cache.class }, loader = AnnotationConfigContextLoader.class) +@DirtiesContext @SuppressWarnings("unchecked") public class FooServiceSortingIntegrationTest { diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java index 040eee1c73..50fdf5f0f3 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java @@ -10,16 +10,19 @@ import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.baeldung.config.PersistenceJPAConfig; +import org.baeldung.config.PersistenceJPAConfigL2Cache; import org.baeldung.persistence.model.Foo; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceJPAConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceJPAConfigL2Cache.class }, loader = AnnotationConfigContextLoader.class) +@DirtiesContext public class FooServiceSortingWitNullsManualIntegrationTest { @PersistenceContext diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java index aa2dfb5293..beaa51f5f9 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java @@ -8,7 +8,6 @@ import org.junit.runners.Suite; FooPaginationPersistenceIntegrationTest.class ,FooServicePersistenceIntegrationTest.class ,FooServiceSortingIntegrationTest.class - ,JpaMultipleDBIntegrationTest.class ,FooServiceSortingWitNullsManualIntegrationTest.class }) // @formatter:on public class PersistenceTestSuite { diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java index 907043b8ce..4de8d321d5 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java @@ -8,6 +8,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; @@ -24,6 +25,7 @@ import static org.junit.Assert.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { PersistenceJPAConfigL2Cache.class }, loader = AnnotationConfigContextLoader.class) +@DirtiesContext public class SecondLevelCacheIntegrationTest { @PersistenceContext diff --git a/pom.xml b/pom.xml index 661258ef1d..beb10b3287 100644 --- a/pom.xml +++ b/pom.xml @@ -1,467 +1,1554 @@ - - 4.0.0 - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - parent-modules - pom + + 4.0.0 - - parent-boot-1 - parent-boot-2 - parent-spring-4 - parent-spring-5 - parent-java - asm - atomix - apache-cayenne - aws - aws-lambda - akka-streams - algorithms - annotations - apache-cxf - apache-fop - apache-poi - apache-tika - apache-thrift - apache-curator - apache-zookeeper - apache-opennlp - autovalue - axon - azure - bootique - cdi - - core-java - core-java-collections - core-java-io - core-java-8 - - core-groovy - core-java-concurrency - couchbase - deltaspike - dozer - ethereumj - - feign - flips - - geotools - testing-modules/groovy-spock - google-cloud - gson - guava - guava-modules/guava-18 - guava-modules/guava-19 - guava-modules/guava-21 - guice - disruptor - spring-static-resources - hazelcast - hbase - - httpclient - hystrix - - immutables - influxdb - jackson - - vavr - java-lite - java-rmi - java-vavr-stream - javax-servlets - javaxval - jaxb - javafx - jgroups - jee-7 - - jjwt - jpa-storedprocedure - jsf - json-path - json - jsoup - testing-modules/junit-5 - jws - - libraries-data - linkrest - logging-modules/log-mdc - logging-modules/log4j - logging-modules/log4j2 - logging-modules/logback - lombok - mapstruct - metrics - maven - mesos-marathon - msf4j - testing-modules/mockito - testing-modules/mockito-2 - testing-modules/mocks - mustache - mvn-wrapper - noexception - orientdb - osgi - orika - patterns - pdf - protobuffer - persistence-modules/querydsl - reactor-core - persistence-modules/redis - testing-modules/rest-assured - testing-modules/rest-testing - resteasy - rxjava - spring-swagger-codegen - testing-modules/selenium-junit-testng - persistence-modules/solr - spark-java - spring-4 - spring-5 - spring-5-reactive - spring-5-mvc - spring-5-security - spring-activiti - spring-akka - spring-amqp - spring-all - spring-amqp-simple - spring-apache-camel - spring-batch - spring-bom - spring-boot - spring-boot-keycloak - spring-boot-bootstrap - spring-boot-admin - spring-boot-ops - spring-boot-persistence - spring-boot-security - spring-boot-mvc - spring-boot-logging-log4j2 - spring-cloud-data-flow - spring-cloud - spring-core - spring-cucumber - spring-ejb - spring-aop - persistence-modules/spring-data-cassandra - spring-data-couchbase-2 - persistence-modules/spring-data-dynamodb - spring-data-elasticsearch - spring-data-keyvalue - spring-data-mongodb - persistence-modules/spring-data-neo4j - persistence-modules/spring-data-redis - spring-data-rest - persistence-modules/spring-data-solr - spring-dispatcher-servlet - spring-exceptions - spring-freemarker - persistence-modules/spring-hibernate-3 - spring-hibernate4 - persistence-modules/spring-hibernate-5 - persistence-modules/spring-data-eclipselink - spring-integration - spring-jenkins-pipeline - spring-jersey - - spring-jms - spring-jooq - persistence-modules/spring-jpa - spring-kafka - spring-katharsis - spring-ldap - spring-mockito - spring-mvc-email - spring-mvc-forms-jsp - spring-mvc-forms-thymeleaf - spring-mvc-java - spring-mvc-velocity - spring-mvc-webflow - spring-mvc-xml - spring-mvc-simple - spring-mvc-kotlin - spring-security-openid - spring-protobuf - spring-quartz - spring-rest-angular - spring-rest-full - spring-rest-query-language - spring-rest - spring-rest-simple - spring-security-acl - spring-security-cache-control - spring-security-client/spring-security-jsp-authentication - spring-security-client/spring-security-jsp-authorize - spring-security-client/spring-security-jsp-config - spring-security-client/spring-security-mvc - spring-security-client/spring-security-thymeleaf-authentication - spring-security-client/spring-security-thymeleaf-authorize - spring-security-client/spring-security-thymeleaf-config - spring-security-core - spring-security-mvc-boot - spring-security-mvc-custom - spring-security-mvc-digest-auth - spring-security-mvc-ldap - spring-security-mvc-login - spring-security-mvc-persisted-remember-me - spring-security-mvc-session - spring-security-mvc-socket - spring-security-rest-basic-auth - spring-security-rest-custom - spring-security-rest - spring-security-sso - spring-security-x509 - spring-session - spring-sleuth - spring-social-login - spring-spel - spring-state-machine - spring-thymeleaf - spring-userservice - spring-zuul - spring-reactor - spring-vertx - spring-jinq - spring-rest-embedded-tomcat - testing-modules/testing - testing-modules/testng - video-tutorials - xml - xmlunit-2 - struts-2 - apache-velocity - apache-solrj - rabbitmq - vertx - persistence-modules/spring-data-gemfire - mybatis - spring-drools - drools - persistence-modules/liquibase - spring-boot-property-exp - testing-modules/mockserver - testing-modules/test-containers - undertow - vertx-and-rxjava - saas - deeplearning4j - lucene - vraptor - persistence-modules/java-cockroachdb - spring-security-thymeleaf - persistence-modules/java-jdbi - jersey - java-spi - performance-tests - twilio - spring-boot-ctx-fluent - java-ee-8-security-api - spring-webflux-amqp - antlr - maven-archetype - + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + parent-modules + pom - - - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - ch.qos.logback - logback-core - ${logback.version} - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - + + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + ch.qos.logback + logback-core + ${logback.version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + - - - junit - junit - ${junit.version} - test - - + + + junit + junit + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit-jupiter.version} + test + + org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.version} - test + junit-jupiter-api + ${junit-jupiter.version} + test - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-all - ${org.hamcrest.version} - test - - - org.mockito - mockito-core - ${mockito.version} - test - - + + org.hamcrest + hamcrest-core + ${org.hamcrest.version} + test + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + org.hamcrest + hamcrest-all + ${org.hamcrest.version} + test + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.apache.maven.surefire + surefire-logger-api + ${maven-surefire-plugin.version} + + test + true + + - - - - org.codehaus.mojo - exec-maven-plugin - ${exec-maven-plugin.version} - - maven - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/JdbcTest.java - **/*LiveTest.java - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-pmd-plugin - 3.9.0 - - - org.baeldung.pmd - custom-pmd - 0.0.1 - - - - 5 - false - true - true - true - true - UTF-8 - 1.8 - - ${tutorialsproject.basedir}/baeldung-pmd-rules.xml - - - - - compile - - check - - - - - - org.commonjava.maven.plugins - directory-maven-plugin - 0.3.1 - - - directories - - directory-of - - validate - - tutorialsproject.basedir - - com.baeldung - parent-modules - - - - - - - org.apache.maven.plugins - maven-install-plugin - 2.5.1 - - org.baeldung.pmd - custom-pmd - 0.0.1 - jar - ${tutorialsproject.basedir}/custom-pmd-0.0.1.jar - true - - - - install-jar-lib - - install-file - - validate - - - - + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + maven + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + org.junit.platform + junit-platform-surefire-provider + ${junit-platform.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + + + org.junit.vintage + junit-vintage-engine + ${junit-jupiter.version} + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-pmd-plugin + ${maven-pmd-plugin.version} + + + org.baeldung.pmd + custom-pmd + ${custom-pmd.version} + + + + 5 + false + true + true + true + true + UTF-8 + ${java.version} + + ${tutorialsproject.basedir}/baeldung-pmd-rules.xml + + + target/generated-sources + + + + + compile + + check + + + + + + org.commonjava.maven.plugins + directory-maven-plugin + ${directory-maven-plugin.version} + + + directories + + directory-of + + validate + + tutorialsproject.basedir + + com.baeldung + parent-modules + + + + + + + org.apache.maven.plugins + maven-install-plugin + ${maven-install-plugin.version} + + org.baeldung.pmd + custom-pmd + ${custom-pmd.version} + jar + ${tutorialsproject.basedir}/custom-pmd-${custom-pmd.version}.jar + true + + + + install-jar-lib + + install-file + + validate + + + + + maven-war-plugin + ${maven-war-plugin.version} + + + + + com.vackosar.gitflowincrementalbuilder + gitflow-incremental-builder + ${gitflow-incremental-builder.version} + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.commonjava.maven.plugins + + + directory-maven-plugin + + + [0.3.1,) + + + directory-of + + + + + + + + + + org.apache.maven.plugins + + + maven-install-plugin + + + [2.5.1,) + + + install-file + + + + + + + + + + + + + - - - com.vackosar.gitflowincrementalbuilder - gitflow-incremental-builder - 3.4 - - + - + + default-first + + - + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + + + + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin + asm + atomix + apache-cayenne + aws + aws-lambda + akka-streams + algorithms + annotations + apache-cxf + apache-fop + apache-geode + apache-poi + apache-tika + apache-thrift + apache-curator + apache-zookeeper + apache-opennlp + autovalue + axon + azure + bootique + cdi + java-strings + + core-java + core-java-collections + core-java-io + core-java-8 + java-streams + core-java-persistence + core-kotlin + kotlin-libraries + core-groovy + core-java-concurrency + core-java-concurrency-collections + couchbase + deltaspike + dozer + ethereum + ejb + ejb/ejb-client + feign + flips + testing-modules/gatling + geotools + testing-modules/groovy-spock + google-cloud + google-web-toolkit + gson + guava + guava-collections + guava-modules/guava-18 + guava-modules/guava-19 + guava-modules/guava-21 + guice + disruptor + spring-static-resources + hazelcast + hbase + hibernate5 + httpclient + hystrix + image-processing + immutables + influxdb + jackson + persistence-modules/java-cassandra + vavr + java-lite + java-numbers + java-rmi + java-vavr-stream + javax-servlets + javaxval + jaxb + javafx + jgroups + jee-7 + jee-7-security + jhipster + jjwt + jsf + json-path + json + jsoup + testing-modules/junit-5 + + libraries + libraries-data + libraries-security + libraries-server + linkrest + logging-modules/log-mdc + logging-modules/log4j + logging-modules/log4j2 + logging-modules/logback + lombok + mapstruct + metrics + maven + mesos-marathon + msf4j + testing-modules/mockito + testing-modules/mockito-2 + testing-modules/mocks + mustache + mvn-wrapper + noexception + orientdb + osgi + orika + patterns + pdf + protobuffer + persistence-modules/querydsl + reactor-core + persistence-modules/redis + testing-modules/rest-assured + testing-modules/rest-testing + resteasy + rxjava + rxjava-2 + spring-swagger-codegen + testing-modules/selenium-junit-testng + persistence-modules/solr + spark-java + spring-4 + spring-5 + spring-5-data-reactive + spring-5-reactive + spring-data-5-reactive/spring-5-data-reactive-redis + spring-5-reactive-security + spring-5-reactive-client + spring-5-mvc + spring-5-security + spring-activiti + spring-akka + spring-amqp + spring-all + spring-amqp-simple + spring-apache-camel + spring-batch + spring-bom + spring-boot + spring-boot-client + spring-boot-keycloak + spring-boot-bootstrap + spring-boot-admin + spring-boot-camel + spring-boot-ops + spring-boot-persistence + spring-boot-security + spring-boot-mvc + spring-boot-vue + spring-boot-logging-log4j2 + spring-cloud-data-flow + spring-cloud + spring-cloud-bus + spring-core + spring-cucumber + spring-ejb + spring-ejb/spring-ejb-client + spring-aop + persistence-modules/spring-data-cassandra + spring-data-couchbase-2 + persistence-modules/spring-data-dynamodb + spring-data-elasticsearch + spring-data-jpa + spring-data-keyvalue + spring-data-mongodb + persistence-modules/spring-data-neo4j + persistence-modules/spring-data-redis + spring-data-rest + persistence-modules/spring-data-solr + spring-dispatcher-servlet + spring-exceptions + spring-freemarker + persistence-modules/spring-hibernate-3 + spring-hibernate4 + persistence-modules/spring-hibernate-5 + persistence-modules/spring-data-eclipselink + spring-integration + spring-jenkins-pipeline + spring-jersey + jmeter + spring-jms + spring-jooq + persistence-modules/spring-jpa + spring-kafka + spring-katharsis + spring-ldap + spring-mockito + spring-mvc-forms-jsp + spring-mvc-forms-thymeleaf + spring-mvc-java + spring-mvc-velocity + spring-mvc-webflow + spring-mvc-xml + spring-mvc-kotlin + spring-protobuf + spring-quartz + spring-rest-angular + spring-rest-full + spring-rest-query-language + + + spring-resttemplate + + + + - integration + default-second + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + + + + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin + + spring-session + spring-sleuth + spring-social-login + spring-spel + spring-state-machine + spring-thymeleaf + spring-userservice + spring-zuul + spring-remoting + spring-reactor + spring-vertx + spring-jinq + spring-rest-embedded-tomcat + testing-modules/testing + testing-modules/testng + video-tutorials + xml + xmlunit-2 + struts-2 + apache-velocity + apache-solrj + rabbitmq + vertx + persistence-modules/spring-data-gemfire + mybatis + spring-drools + drools + persistence-modules/liquibase + spring-boot-property-exp + testing-modules/mockserver + testing-modules/test-containers + undertow + vaadin + vertx-and-rxjava + saas + deeplearning4j + lucene + vraptor + persistence-modules/java-cockroachdb + spring-security-thymeleaf + persistence-modules/java-jdbi + jersey + java-spi + performance-tests + twilio + spring-boot-ctx-fluent + java-ee-8-security-api + spring-webflux-amqp + antlr + maven-archetype + optaplanner + apache-meecrowave + spring-reactive-kotlin + jnosql + spring-boot-angular-ecommerce + cdi-portable-extension + jta + + java-websocket + activejdbc + animal-sniffer-mvn-plugin + apache-avro + apache-bval + apache-shiro + apache-spark + asciidoctor + checker-plugin + + + core-java-sun + custom-pmd + dagger + data-structures + dubbo + flyway + + + jni + jooby + + + + ratpack + rest-with-spark-java + spring-boot-autoconfiguration + spring-boot-custom-starter + spring-boot-jasypt + spring-custom-aop + spring-data-rest-querydsl + spring-groovy + spring-mobile + spring-mustache + spring-mvc-simple + spring-mybatis + spring-rest-hal-browser + spring-rest-shell + spring-rest-template + spring-roo + spring-security-stormpath + sse-jaxrs + static-analysis + stripe + + Twitter4J + wicket + xstream + cas/cas-secured-app + cas/cas-server + + + + + + + + + + + + + + + + + spring-boot-custom-starter/greeter + spring-boot-h2/spring-boot-h2-database + + + + + flyway-cdi-extension + + spring-security-acl + spring-security-cache-control + spring-security-client/spring-security-jsp-authentication + spring-security-client/spring-security-jsp-authorize + spring-security-client/spring-security-jsp-config + spring-security-client/spring-security-mvc + spring-security-client/spring-security-thymeleaf-authentication + spring-security-client/spring-security-thymeleaf-authorize + spring-security-client/spring-security-thymeleaf-config + spring-security-core + spring-security-mvc-boot + spring-security-mvc-custom + spring-security-mvc-digest-auth + spring-security-mvc-ldap + spring-security-mvc-login + spring-security-mvc-persisted-remember-me + spring-security-mvc-session + spring-security-mvc-socket + spring-security-openid + + spring-security-rest-basic-auth + spring-security-rest-custom + spring-security-rest + spring-security-sso + spring-security-x509 + + + + + + spring-context + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*SpringContextIntegrationTest.java + + + + + + + + + spring-5 + spring-5-data-reactive + spring-5-reactive + spring-5-reactive-client + spring-5-reactive-security + spring-5-security + spring-activiti + spring-akka + spring-all + spring-aop + spring-apache-camel + spring-batch + spring-bom + spring-boot-admin/spring-boot-admin-client + spring-boot-admin/spring-boot-admin-server + spring-boot-bootstrap + spring-boot-bootstrap + spring-boot-camel + spring-boot-client + spring-boot-custom-starter + greeter-spring-boot-autoconfigure + greeter-spring-boot-sample-app + spring-boot-h2/spring-boot-h2-database + spring-boot-jasypt + spring-boot-keycloak + spring-boot-mvc + spring-boot-property-exp/property-exp-custom-config + spring-boot-property-exp/property-exp-default-config + spring-boot-vue + spring-cloud + spring-cloud/spring-cloud-archaius/basic-config + spring-cloud/spring-cloud-archaius/extra-configs + spring-cloud/spring-cloud-bootstrap/config + spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer + spring-cloud/spring-cloud-contract/spring-cloud-contract-producer + spring-cloud/spring-cloud-gateway + spring-cloud/spring-cloud-kubernetes/demo-backend + spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server + spring-cloud/spring-cloud-ribbon-client + spring-cloud/spring-cloud-security/auth-client + spring-cloud/spring-cloud-security/auth-resource + spring-cloud/spring-cloud-security/auth-server + spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit + spring-cloud/spring-cloud-task/springcloudtasksink + spring-cloud/spring-cloud-zookeeper + spring-cloud/spring-cloud-bus/spring-cloud-config-server + spring-cloud/spring-cloud-data-flow/log-sink + spring-cloud/spring-cloud-data-flow/time-processor + spring-cloud/spring-cloud-data-flow/time-source + spring-cucumber + spring-data-keyvalue + spring-data-rest + spring-dispatcher-servlet + spring-drools + spring-freemarker + spring-hibernate-3 + spring-hibernate4 + spring-integration + spring-jenkins-pipeline + spring-jersey + spring-jinq + spring-jms + spring-kafka + spring-katharsis + spring-ldap + spring-mobile + spring-mockito + spring-mvc-forms-thymeleaf + spring-mvc-java + spring-mvc-velocity + spring-mvc-webflow + spring-protobuf + spring-quartz + remoting-hessian-burlap/spring-remoting-hessian-burlap-client + remoting-hessian-burlap/remoting-hessian-burlap-server + spring-reactor + spring-remoting/ + spring-remoting/remoting-http/remoting-http-server + spring-remoting/remoting-jms/remoting-jms-client + spring-remoting/remoting-rmi/remoting-rmi-server + spring-rest + spring-rest-angular + spring-rest-embedded-tomcat + spring-rest-full + spring-rest-simple + spring-resttemplate + spring-security-acl + spring-security-angular + spring-security-cache-control + spring-security-client/spring-security-jsp-authentication + spring-security-client/spring-security-jsp-authorize + spring-security-client/spring-security-jsp-config + spring-security-client/spring-security-mvc + spring-security-client/spring-security-thymeleaf-authentication + spring-security-client/spring-security-thymeleaf-authorize + spring-security-client/spring-security-thymeleaf-config + spring-security-core + spring-security-mvc-boot + spring-security-mvc-custom + spring-security-mvc-digest-auth + spring-security-mvc-ldap + spring-security-mvc-persisted-remember-me + spring-security-mvc-session + spring-security-mvc-socket + spring-security-rest + spring-security-sso/spring-security-sso-auth-server + spring-security-sso/spring-security-sso-ui + spring-security-sso/spring-security-sso-ui-2 + spring-security-thymeleaf/spring-security-thymeleaf-authentication + spring-security-thymeleaf/spring-security-thymeleaf-authorize + spring-security-thymeleaf/spring-security-thymeleaf-config + spring-security-x509/spring-security-x509-basic-auth + spring-security-x509/spring-security-x509-client-auth + spring-session/spring-session-jdbc + spring-sleuth + spring-social-login + spring-spel + spring-state-machine + spring-swagger-codegen/spring-swagger-codegen-app + spring-thymeleaf + spring-userservice + spring-vault + spring-vertx + spring-zuul/spring-zuul-foos-resource + persistence-modules/spring-data-dynamodb + persistence-modules/spring-data-eclipselink + persistence-modules/spring-data-solr + persistence-modules/spring-hibernate-5 + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + **/*LiveTest.java + + + **/*IntegrationTest.java + **/*IntTest.java + + + + + + + json + + + + + + + + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin + + + + + + + + + + testing-modules/mockito + testing-modules/mockito-2 + testing-modules/mocks + mustache + mvn-wrapper + noexception + orientdb + osgi + orika + patterns + pdf + protobuffer + persistence-modules/querydsl + reactor-core + persistence-modules/redis + testing-modules/rest-assured + testing-modules/rest-testing + resteasy + rxjava + rxjava-2 + spring-swagger-codegen + testing-modules/selenium-junit-testng + persistence-modules/solr + spark-java + spring-4 + spring-5 + spring-5-data-reactive + spring-5-reactive + spring-5-reactive-security + spring-5-reactive-client + spring-5-mvc + spring-5-security + spring-activiti + spring-akka + spring-amqp + spring-all + spring-amqp-simple + spring-apache-camel + spring-batch + jmh + + + + + + spring-bom + spring-boot + spring-boot-client + spring-boot-keycloak + spring-boot-bootstrap + spring-boot-admin + spring-boot-camel + spring-boot-ops + spring-boot-persistence + spring-boot-security + spring-boot-mvc + spring-boot-logging-log4j2 + spring-cloud-data-flow + spring-cloud + spring-cloud-bus + spring-core + spring-cucumber + spring-ejb + spring-ejb/spring-ejb-client + spring-aop + persistence-modules/spring-data-cassandra + spring-data-couchbase-2 + persistence-modules/spring-data-dynamodb + spring-data-elasticsearch + spring-data-keyvalue + spring-data-mongodb + spring-data-jpa + persistence-modules/spring-data-neo4j + persistence-modules/spring-data-redis + spring-data-rest + + + + + + + persistence-modules/spring-data-solr + spring-dispatcher-servlet + spring-exceptions + spring-freemarker + persistence-modules/spring-hibernate-3 + spring-hibernate4 + persistence-modules/spring-hibernate-5 + persistence-modules/spring-data-eclipselink + spring-integration + spring-jenkins-pipeline + spring-jersey + spring-jms + spring-jooq + persistence-modules/spring-jpa + spring-kafka + spring-katharsis + spring-ldap + spring-mockito + spring-mvc-forms-jsp + spring-mvc-forms-thymeleaf + spring-mvc-java + spring-mvc-velocity + spring-mvc-webflow + spring-mvc-xml + spring-mvc-kotlin + spring-protobuf + spring-quartz + spring-rest-angular + spring-rest-full + spring-rest-query-language + spring-rest + spring-resttemplate + spring-rest-simple + spring-reactive-kotlin + + + + + + + + + + + + + + + + java-websocket + activejdbc + animal-sniffer-mvn-plugin + apache-avro + apache-bval + apache-shiro + apache-spark + asciidoctor + checker-plugin + + + core-java-sun + custom-pmd + dagger + data-structures + dubbo + flyway + + + jni + jooby + + + + ratpack + rest-with-spark-java + spring-boot-autoconfiguration + spring-boot-custom-starter + spring-boot-jasypt + spring-custom-aop + spring-data-rest-querydsl + spring-groovy + spring-mobile + spring-mustache + spring-mvc-simple + spring-mybatis + spring-rest-hal-browser + spring-rest-shell + spring-rest-template + spring-roo + spring-security-stormpath + sse-jaxrs + static-analysis + stripe + + + wicket + xstream + cas/cas-secured-app + + + + + + + + + + + + + + jenkins/hello-world + + + + spring-boot-custom-starter/greeter + spring-boot-h2/spring-boot-h2-database + + + + + + + + + + integration-lite + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + **/*LiveTest.java + + + **/*IntegrationTest.java + **/*IntTest.java + + + + + + + json + + + + + + + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin + asm + atomix + apache-cayenne + aws + aws-lambda + akka-streams + algorithms + annotations + apache-cxf + apache-fop + apache-poi + apache-tika + apache-thrift + apache-curator + apache-zookeeper + apache-opennlp + autovalue + axon + azure + bootique + cdi + java-strings + + core-java-collections + core-java-io + core-java-8 + java-streams + core-groovy + + couchbase + deltaspike + dozer + ethereum + feign + flips + testing-modules/groovy-spock + google-cloud + gson + guava + guava-collections + guava-modules/guava-18 + guava-modules/guava-19 + guava-modules/guava-21 + guice + disruptor + spring-static-resources + hazelcast + hbase + + hystrix + image-processing + immutables + influxdb + jackson + vavr + java-lite + java-numbers + java-rmi + java-vavr-stream + javax-servlets + javaxval + jaxb + javafx + jgroups + jee-7 + jee-7-security + jjwt + jsf + json-path + json + jsoup + jta + testing-modules/junit-5 + testing-modules/junit5-migration + jws + libraries-data + linkrest + logging-modules/log-mdc + logging-modules/log4j + + logging-modules/logback + lombok + mapstruct + + maven + mesos-marathon + msf4j + testing-modules/mockito + testing-modules/mockito-2 + testing-modules/mocks + mustache + mvn-wrapper + noexception + orientdb + osgi + orika + patterns + pdf + protobuffer + persistence-modules/querydsl + reactor-core + persistence-modules/redis + testing-modules/rest-assured + testing-modules/rest-testing + resteasy + rxjava + rxjava-2 + spring-swagger-codegen + testing-modules/selenium-junit-testng + persistence-modules/solr + spark-java + spring-4 + spring-5-data-reactive + spring-5-reactive + spring-5-reactive-security + spring-5-reactive-client + spring-5-mvc + spring-5-security + spring-activiti + spring-akka + spring-amqp + spring-all + spring-amqp-simple + spring-apache-camel + spring-batch + spring-bom + spring-boot-keycloak + spring-boot-bootstrap + spring-boot-admin + spring-boot-camel + spring-boot-persistence + spring-boot-security + spring-boot-mvc + spring-boot-logging-log4j2 + spring-cloud-data-flow + spring-cloud + spring-cloud-bus + spring-core + spring-cucumber + spring-ejb + spring-ejb/spring-ejb-client + spring-aop + + persistence-modules/spring-data-dynamodb + spring-data-keyvalue + spring-data-mongodb + persistence-modules/spring-data-neo4j + + spring-data-rest + persistence-modules/spring-data-solr + spring-dispatcher-servlet + spring-exceptions + spring-freemarker + persistence-modules/spring-hibernate-3 + + persistence-modules/spring-hibernate-5 + persistence-modules/spring-data-eclipselink + spring-integration + spring-jenkins-pipeline + spring-jersey + + spring-jms + spring-jooq + persistence-modules/spring-jpa + spring-kafka + spring-katharsis + spring-ldap + spring-mockito + spring-mvc-forms-jsp + spring-mvc-forms-thymeleaf + spring-mvc-java + spring-mvc-velocity + spring-mvc-webflow + spring-mvc-xml + spring-mvc-kotlin + spring-protobuf + spring-quartz + spring-rest-angular + spring-rest-full + spring-rest-query-language + spring-rest + spring-resttemplate + spring-rest-simple + spring-security-acl + spring-security-cache-control + spring-security-client/spring-security-jsp-authentication + spring-security-client/spring-security-jsp-authorize + spring-security-client/spring-security-jsp-config + spring-security-client/spring-security-mvc + spring-security-client/spring-security-thymeleaf-authentication + spring-security-client/spring-security-thymeleaf-authorize + spring-security-client/spring-security-thymeleaf-config + spring-security-core + spring-security-mvc-boot + spring-security-mvc-digest-auth + spring-security-mvc-ldap + spring-security-mvc-login + spring-security-mvc-persisted-remember-me + spring-security-mvc-session + spring-security-mvc-socket + spring-security-openid + + spring-security-rest-basic-auth + spring-security-rest-custom + spring-security-rest + spring-security-sso + spring-security-x509 + spring-session + spring-sleuth + spring-social-login + spring-spel + spring-state-machine + spring-thymeleaf + spring-userservice + spring-zuul + spring-remoting + spring-reactor + spring-vertx + spring-vault + spring-jinq + spring-rest-embedded-tomcat + testing-modules/testing + testing-modules/testng + video-tutorials + + xmlunit-2 + struts-2 + apache-velocity + apache-solrj + rabbitmq + + persistence-modules/spring-data-gemfire + mybatis + spring-drools + drools + persistence-modules/liquibase + spring-boot-property-exp + testing-modules/mockserver + testing-modules/test-containers + undertow + vaadin + vertx-and-rxjava + saas + deeplearning4j + lucene + vraptor + persistence-modules/java-cockroachdb + spring-security-thymeleaf + persistence-modules/java-jdbi + jersey + java-spi + performance-tests + twilio + spring-boot-ctx-fluent + java-ee-8-security-api + spring-webflux-amqp + antlr + maven-archetype + apache-meecrowave + + spring-hibernate4 + xml + vertx + metrics + httpclient + + + + + + + + + + + + + + integration-heavy + @@ -493,55 +1580,92 @@ + + + parent-boot-1 + parent-boot-2 + parent-spring-4 + parent-spring-5 + parent-java + parent-kotlin + libraries + geotools + jhipster + testing-modules/gatling + spring-boot + spring-boot-ops + spring-5 + core-kotlin + kotlin-libraries + core-java + google-web-toolkit + spring-security-mvc-custom + hibernate5 + spring-data-elasticsearch + core-java-concurrency + core-java-concurrency-collections + + - - - - - org.apache.maven.plugins - maven-jxr-plugin - 2.3 - - - - - UTF-8 - refs/heads/master - true - false - false - - 4.12 - 1.3 - 2.8.9 - - 1.7.21 - 1.1.7 - - 2.21.0 - 3.7.0 - 1.6.0 - 1.8 - 1.2.17 - 1.1 - 2.1.0.1 - 1.19 - 1.19 - 1.3 - 1.6.0 - 2.19.1 - 2.5 - 1.4 - 2.6 - 3.1.0 - 1.2 - 2.3.1 - 1.9.13 - 1.2 - 2.5.0 - 1.3 - 5.0.2 - + + + + + + org.apache.maven.plugins + maven-jxr-plugin + ${maven-jxr-plugin.version} + + + + + + UTF-8 + UTF-8 + refs/heads/master + true + false + false + + 4.12 + 1.3 + 2.21.0 + + 1.7.21 + 1.1.7 + + 2.21.0 + 3.7.0 + 1.6.0 + 1.8 + 1.2.17 + 1.1 + 2.1.0.1 + 1.19 + 1.19 + 1.3 + 1.6.0 + 2.19.1 + 2.5 + 1.4 + 3.0.0 + 3.1.0 + 1.2 + 2.3.1 + 1.9.13 + 1.2 + 2.5.0 + 1.3 + 1.2.0 + 5.2.0 + 0.3.1 + 2.5.1 + 0.0.1 + 3.4 + 2.3 + + 3.8 + diff --git a/protobuffer/pom.xml b/protobuffer/pom.xml index 919a49e67d..ff443a1615 100644 --- a/protobuffer/pom.xml +++ b/protobuffer/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 protobuffer diff --git a/protobuffer/src/main/resources/logback.xml b/protobuffer/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/protobuffer/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/rabbitmq/pom.xml b/rabbitmq/pom.xml index 391d7933ea..b620248cfc 100644 --- a/rabbitmq/pom.xml +++ b/rabbitmq/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung @@ -25,7 +24,6 @@ - UTF-8 3.6.6 diff --git a/rabbitmq/src/main/resources/logback.xml b/rabbitmq/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/rabbitmq/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ratpack/README.md b/ratpack/README.md index 02b91da0bd..dded42fab6 100644 --- a/ratpack/README.md +++ b/ratpack/README.md @@ -4,4 +4,4 @@ - [Ratpack Google Guice Integration](http://www.baeldung.com/ratpack-google-guice) - [Ratpack Integration with Spring Boot](http://www.baeldung.com/ratpack-spring-boot) - [Ratpack with Hystrix](http://www.baeldung.com/ratpack-hystrix) - +- [Ratpack HTTP Client](https://www.baeldung.com/ratpack-http-client) diff --git a/ratpack/build.gradle b/ratpack/build.gradle index aeddd5f9f9..25af3ddb51 100644 --- a/ratpack/build.gradle +++ b/ratpack/build.gradle @@ -1,35 +1,35 @@ -buildscript { - repositories { - jcenter() - } - dependencies { - classpath "io.ratpack:ratpack-gradle:1.4.5" - classpath "com.h2database:h2:1.4.193" - } -} - -if (!JavaVersion.current().java8Compatible) { - throw new IllegalStateException("Must be built with Java 8 or higher") -} - -apply plugin: "io.ratpack.ratpack-java" -apply plugin: 'java' - -repositories { - jcenter() -} - -dependencies { - compile ratpack.dependency('hikari') - compile 'com.h2database:h2:1.4.193' - testCompile 'junit:junit:4.11' - runtime "org.slf4j:slf4j-simple:1.7.21" -} - -test { - testLogging { - events 'started', 'passed' - } -} - -mainClassName = "com.baeldung.Application" +buildscript { + repositories { + jcenter() + } + dependencies { + classpath "io.ratpack:ratpack-gradle:1.5.4" + classpath "com.h2database:h2:1.4.193" + } +} + +if (!JavaVersion.current().java8Compatible) { + throw new IllegalStateException("Must be built with Java 8 or higher") +} + +apply plugin: "io.ratpack.ratpack-java" +apply plugin: 'java' + +repositories { + jcenter() +} + +dependencies { + compile ratpack.dependency('hikari') + compile 'com.h2database:h2:1.4.193' + testCompile 'junit:junit:4.11' + runtime "org.slf4j:slf4j-simple:1.7.21" +} + +test { + testLogging { + events 'started', 'passed' + } +} + +mainClassName = "com.baeldung.Application" diff --git a/ratpack/pom.xml b/ratpack/pom.xml index bf43168b02..7de11e6955 100644 --- a/ratpack/pom.xml +++ b/ratpack/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung ratpack @@ -35,6 +35,17 @@ io.ratpack ratpack-hystrix ${ratpack.version} + + + com.netflix.hystrix + hystrix-core + + + + + com.netflix.hystrix + hystrix-core + ${hystrix.version} io.ratpack @@ -74,13 +85,13 @@ - UTF-8 1.8 1.8 - 1.4.6 + 1.5.4 4.5.3 4.4.6 1.4.193 + 1.5.12 diff --git a/ratpack/src/main/java/com/baeldung/Application.java b/ratpack/src/main/java/com/baeldung/Application.java index 7f46b241ea..4a391d04a1 100644 --- a/ratpack/src/main/java/com/baeldung/Application.java +++ b/ratpack/src/main/java/com/baeldung/Application.java @@ -1,49 +1,81 @@ -package com.baeldung; - -import java.util.ArrayList; -import java.util.List; - -import com.baeldung.filter.RequestValidatorFilter; -import com.baeldung.model.Employee; - -import ratpack.guice.Guice; -import ratpack.hikari.HikariModule; -import ratpack.http.MutableHeaders; -import ratpack.jackson.Jackson; -import ratpack.http.MutableHeaders; -import ratpack.server.RatpackServer; - -public class Application { - - public static void main(String[] args) throws Exception { - - List employees = new ArrayList(); - employees.add(new Employee(1L, "Mr", "John Doe")); - employees.add(new Employee(2L, "Mr", "White Snow")); - - - RatpackServer.start( - server -> server.registry(Guice.registry(bindings -> bindings.module(HikariModule.class, config -> { - config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource"); - config.addDataSourceProperty("URL", - "jdbc:h2:mem:baeldung;INIT=RUNSCRIPT FROM 'classpath:/DDL.sql'"); - }))).handlers(chain -> chain - .all( - // ctx -> { - // MutableHeaders headers = - // ctx.getResponse().getHeaders(); - // headers.set("Access-Control-Allow-Origin","*"); - // headers.set("Accept-Language", "en-us"); - // headers.set("Accept-Charset", "UTF-8"); - // ctx.next(); - // } - new RequestValidatorFilter()) - .get(ctx -> ctx.render("Welcome to baeldung ratpack!!!")) - .get("data/employees", ctx -> ctx.render(Jackson.json(employees))) - .get(":name", ctx -> ctx.render("Hello " + ctx.getPathTokens().get("name") + "!!!")) - .post(":amount", ctx -> ctx - .render(" Amount $" + ctx.getPathTokens().get("amount") + " added successfully !!!")))); - } - -} - +package com.baeldung; + +import com.baeldung.filter.RequestValidatorFilter; +import com.baeldung.handler.EmployeeHandler; +import com.baeldung.handler.RedirectHandler; +import com.baeldung.model.Employee; +import com.baeldung.repository.EmployeeRepository; +import com.baeldung.repository.EmployeeRepositoryImpl; +import com.zaxxer.hikari.HikariConfig; +import io.netty.buffer.PooledByteBufAllocator; +import ratpack.func.Action; +import ratpack.func.Function; +import ratpack.guice.BindingsSpec; +import ratpack.guice.Guice; +import ratpack.handling.Chain; +import ratpack.hikari.HikariModule; +import ratpack.http.client.HttpClient; +import ratpack.jackson.Jackson; +import ratpack.registry.Registry; +import ratpack.server.RatpackServer; +import ratpack.server.RatpackServerSpec; +import ratpack.server.ServerConfig; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; + +public class Application { + + public static void main(String[] args) throws Exception { + + final Action hikariConfigAction = hikariConfig -> { + hikariConfig.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource"); + hikariConfig.addDataSourceProperty("URL", "jdbc:h2:mem:baeldung;INIT=RUNSCRIPT FROM 'classpath:/DDL.sql'"); + }; + + final Action bindingsSpecAction = bindings -> bindings.module(HikariModule.class, hikariConfigAction); + final HttpClient httpClient = HttpClient.of(httpClientSpec -> { + httpClientSpec.poolSize(10) + .connectTimeout(Duration.of(60, ChronoUnit.SECONDS)) + .maxContentLength(ServerConfig.DEFAULT_MAX_CONTENT_LENGTH) + .responseMaxChunkSize(16384) + .readTimeout(Duration.of(60, ChronoUnit.SECONDS)) + .byteBufAllocator(PooledByteBufAllocator.DEFAULT); + }); + final Function registryFunction = Guice.registry(bindingsSpecAction); + + final Action chainAction = chain -> chain.all(new RequestValidatorFilter()) + .get(ctx -> ctx.render("Welcome to baeldung ratpack!!!")) + .get("data/employees", ctx -> ctx.render(Jackson.json(createEmpList()))) + .get(":name", ctx -> ctx.render("Hello " + ctx.getPathTokens() + .get("name") + "!!!")) + .post(":amount", ctx -> ctx.render(" Amount $" + ctx.getPathTokens() + .get("amount") + " added successfully !!!")); + + final Action routerChainAction = routerChain -> { + routerChain.path("redirect", new RedirectHandler()) + .prefix("employee", empChain -> { + empChain.get(":id", new EmployeeHandler()); + }); + }; + final Action ratpackServerSpecAction = serverSpec -> serverSpec.registry(registryFunction) + .registryOf(registrySpec -> { + registrySpec.add(EmployeeRepository.class, new EmployeeRepositoryImpl()); + registrySpec.add(HttpClient.class, httpClient); + }) + .handlers(chain -> chain.insert(routerChainAction) + .insert(chainAction)); + + RatpackServer.start(ratpackServerSpecAction); + } + + private static List createEmpList() { + List employees = new ArrayList<>(); + employees.add(new Employee(1L, "Mr", "John Doe")); + employees.add(new Employee(2L, "Mr", "White Snow")); + return employees; + } + +} diff --git a/ratpack/src/main/java/com/baeldung/handler/EmployeeHandler.java b/ratpack/src/main/java/com/baeldung/handler/EmployeeHandler.java new file mode 100644 index 0000000000..9a6b79259c --- /dev/null +++ b/ratpack/src/main/java/com/baeldung/handler/EmployeeHandler.java @@ -0,0 +1,20 @@ +package com.baeldung.handler; + +import com.baeldung.repository.EmployeeRepository; +import com.baeldung.model.Employee; +import ratpack.exec.Promise; +import ratpack.handling.Context; +import ratpack.handling.Handler; + +public class EmployeeHandler implements Handler { + @Override + public void handle(Context ctx) throws Exception { + EmployeeRepository repository = ctx.get(EmployeeRepository.class); + Long id = Long.valueOf(ctx.getPathTokens() + .get("id")); + Promise employeePromise = repository.findEmployeeById(id); + employeePromise.map(employee -> employee.getName()) + .then(name -> ctx.getResponse() + .send(name)); + } +} diff --git a/ratpack/src/main/java/com/baeldung/handler/FooHandler.java b/ratpack/src/main/java/com/baeldung/handler/FooHandler.java new file mode 100644 index 0000000000..d2c4dbdce5 --- /dev/null +++ b/ratpack/src/main/java/com/baeldung/handler/FooHandler.java @@ -0,0 +1,12 @@ +package com.baeldung.handler; + +import ratpack.handling.Context; +import ratpack.handling.Handler; + +public class FooHandler implements Handler { + @Override + public void handle(Context ctx) throws Exception { + ctx.getResponse() + .send("Hello Foo!"); + } +} diff --git a/ratpack/src/main/java/com/baeldung/handler/RedirectHandler.java b/ratpack/src/main/java/com/baeldung/handler/RedirectHandler.java new file mode 100644 index 0000000000..c95543a961 --- /dev/null +++ b/ratpack/src/main/java/com/baeldung/handler/RedirectHandler.java @@ -0,0 +1,23 @@ +package com.baeldung.handler; + +import ratpack.exec.Promise; +import ratpack.handling.Context; +import ratpack.handling.Handler; +import ratpack.http.client.HttpClient; +import ratpack.http.client.ReceivedResponse; + +import java.net.URI; + +public class RedirectHandler implements Handler { + @Override + public void handle(Context ctx) throws Exception { + HttpClient client = ctx.get(HttpClient.class); + URI uri = URI.create("http://localhost:5050/employee/1"); + Promise responsePromise = client.get(uri); + responsePromise.map(response -> response.getBody() + .getText() + .toUpperCase()) + .then(responseText -> ctx.getResponse() + .send(responseText)); + } +} \ No newline at end of file diff --git a/ratpack/src/main/java/com/baeldung/repository/EmployeeRepository.java b/ratpack/src/main/java/com/baeldung/repository/EmployeeRepository.java new file mode 100644 index 0000000000..de04c23da5 --- /dev/null +++ b/ratpack/src/main/java/com/baeldung/repository/EmployeeRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.repository; + +import com.baeldung.model.Employee; +import ratpack.exec.Promise; + +public interface EmployeeRepository { + + Promise findEmployeeById(Long id) throws Exception; + +} diff --git a/ratpack/src/main/java/com/baeldung/repository/EmployeeRepositoryImpl.java b/ratpack/src/main/java/com/baeldung/repository/EmployeeRepositoryImpl.java new file mode 100644 index 0000000000..6d15012ccb --- /dev/null +++ b/ratpack/src/main/java/com/baeldung/repository/EmployeeRepositoryImpl.java @@ -0,0 +1,25 @@ +package com.baeldung.repository; + +import com.baeldung.model.Employee; +import ratpack.exec.Promise; + +import java.util.HashMap; +import java.util.Map; + +public class EmployeeRepositoryImpl implements EmployeeRepository { + + private static final Map EMPLOYEE_MAP = new HashMap<>(); + + public EmployeeRepositoryImpl() { + EMPLOYEE_MAP.put(1L, new Employee(1L, "Ms", "Jane Doe")); + EMPLOYEE_MAP.put(2L, new Employee(2L, "Mr", "NY")); + } + + @Override + public Promise findEmployeeById(Long id) throws Exception { + return Promise.async(downstream -> { + Thread.sleep(500); + downstream.success(EMPLOYEE_MAP.get(id)); + }); + } +} diff --git a/ratpack/src/main/resources/logback.xml b/ratpack/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/ratpack/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/ratpack/src/test/java/com/baeldung/AppHttpUnitTest.java b/ratpack/src/test/java/com/baeldung/AppHttpUnitTest.java new file mode 100644 index 0000000000..a97516dd74 --- /dev/null +++ b/ratpack/src/test/java/com/baeldung/AppHttpUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung; + +import com.baeldung.model.Employee; +import org.junit.Test; +import ratpack.exec.Promise; +import ratpack.func.Action; +import ratpack.handling.Chain; +import ratpack.handling.Handler; +import ratpack.registry.Registry; +import ratpack.test.embed.EmbeddedApp; +import ratpack.test.exec.ExecHarness; + +import static org.junit.Assert.assertEquals; + +public class AppHttpUnitTest { + + @Test + public void givenAnyUri_GetEmployeeFromSameRegistry() throws Exception { + Handler allHandler = ctx -> { + Long id = Long.valueOf(ctx.getPathTokens() + .get("id")); + Employee employee = new Employee(id, "Mr", "NY"); + ctx.next(Registry.single(Employee.class, employee)); + }; + Handler empNameHandler = ctx -> { + Employee employee = ctx.get(Employee.class); + ctx.getResponse() + .send("Name of employee with ID " + employee.getId() + " is " + employee.getName()); + }; + Handler empTitleHandler = ctx -> { + Employee employee = ctx.get(Employee.class); + ctx.getResponse() + .send("Title of employee with ID " + employee.getId() + " is " + employee.getTitle()); + }; + + Action chainAction = chain -> chain.prefix("employee/:id", empChain -> { + empChain.all(allHandler) + .get("name", empNameHandler) + .get("title", empTitleHandler); + }); + EmbeddedApp.fromHandlers(chainAction) + .test(testHttpClient -> { + assertEquals("Name of employee with ID 1 is NY", testHttpClient.get("employee/1/name") + .getBody() + .getText()); + assertEquals("Title of employee with ID 1 is Mr", testHttpClient.get("employee/1/title") + .getBody() + .getText()); + }); + } + + @Test + public void givenSyncDataSource_GetDataFromPromise() throws Exception { + String value = ExecHarness.yieldSingle(execution -> Promise.sync(() -> "Foo")) + .getValueOrThrow(); + assertEquals("Foo", value); + } +} diff --git a/reactor-core/pom.xml b/reactor-core/pom.xml index 41c42cac28..cf720ad6ea 100644 --- a/reactor-core/pom.xml +++ b/reactor-core/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung @@ -18,7 +18,6 @@ reactor-core ${reactor-core.version} - org.assertj assertj-core diff --git a/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java b/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java index 56650ba306..e3060b8e02 100644 --- a/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java +++ b/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java @@ -37,14 +37,14 @@ public class ReactorIntegrationTest { Flux.just(1, 2, 3, 4) .log() .map(i -> i * 2) - .zipWith(Flux.range(0, Integer.MAX_VALUE).log(), (two, one) -> String.format("First Flux: %d, Second Flux: %d", one, two)) + .zipWith(Flux.range(0, Integer.MAX_VALUE).log(), (one, two) -> String.format("First Flux: %d, Second Flux: %d", one, two)) .subscribe(elements::add); assertThat(elements).containsExactly( - "First Flux: 0, Second Flux: 2", - "First Flux: 1, Second Flux: 4", - "First Flux: 2, Second Flux: 6", - "First Flux: 3, Second Flux: 8"); + "First Flux: 2, Second Flux: 0", + "First Flux: 4, Second Flux: 1", + "First Flux: 6, Second Flux: 2", + "First Flux: 8, Second Flux: 3"); } @Test diff --git a/rest-with-spark-java/pom.xml b/rest-with-spark-java/pom.xml index ffdb86ebca..a0005b7dec 100644 --- a/rest-with-spark-java/pom.xml +++ b/rest-with-spark-java/pom.xml @@ -1,6 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 com.baeldung rest-with-spark-java @@ -15,12 +15,6 @@ - - junit - junit - ${junit.version} - test - com.sparkjava spark-core diff --git a/rest-with-spark-java/src/main/resources/logback.xml b/rest-with-spark-java/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/rest-with-spark-java/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/rest-with-spark-java/src/test/java/com/baeldung/AppTest.java b/rest-with-spark-java/src/test/java/com/baeldung/AppLiveTest.java similarity index 96% rename from rest-with-spark-java/src/test/java/com/baeldung/AppTest.java rename to rest-with-spark-java/src/test/java/com/baeldung/AppLiveTest.java index c7b88dd6d1..9e24879767 100644 --- a/rest-with-spark-java/src/test/java/com/baeldung/AppTest.java +++ b/rest-with-spark-java/src/test/java/com/baeldung/AppLiveTest.java @@ -16,16 +16,16 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -public class AppTest extends TestCase { +public class AppLiveTest extends TestCase { ObjectMapper mapper = new ObjectMapper(); - public AppTest( String testName ) { + public AppLiveTest( String testName ) { super( testName ); } public static Test suite() { - return new TestSuite( AppTest.class ); + return new TestSuite( AppLiveTest.class ); } public void testApp() throws IOException, ClassNotFoundException { diff --git a/resteasy/pom.xml b/resteasy/pom.xml index aca9fe3635..31a6ed485a 100644 --- a/resteasy/pom.xml +++ b/resteasy/pom.xml @@ -2,11 +2,11 @@ 4.0.0 - com.baeldung - resteasy-tutorial + resteasy 1.0 war + resteasy com.baeldung @@ -14,29 +14,6 @@ 1.0.0-SNAPSHOT - - RestEasyTutorial - - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - true - - jetty8x - embedded - - - - 8082 - - - - - - - @@ -81,6 +58,29 @@ + + RestEasyTutorial + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + jetty8x + embedded + + + + 8082 + + + + + + + live @@ -141,7 +141,6 @@ - 3.0.19.Final 2.5 diff --git a/resteasy/src/main/resources/logback.xml b/resteasy/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/resteasy/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/rule-engines/easy-rules/pom.xml b/rule-engines/easy-rules/pom.xml index 8399eff8a2..5b88ce4e94 100644 --- a/rule-engines/easy-rules/pom.xml +++ b/rule-engines/easy-rules/pom.xml @@ -1,11 +1,9 @@ + 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.easyrules easy-rules 1.0 - easy-rules @@ -18,7 +16,11 @@ org.jeasy easy-rules-core - 3.0.0 + ${easy-rules.version} + + + 3.0.0 + \ No newline at end of file diff --git a/rule-engines/easy-rules/src/main/resources/logback.xml b/rule-engines/easy-rules/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/rule-engines/easy-rules/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/rule-engines/openl-tablets/pom.xml b/rule-engines/openl-tablets/pom.xml index 8e3f1965b5..3bd6055fc9 100644 --- a/rule-engines/openl-tablets/pom.xml +++ b/rule-engines/openl-tablets/pom.xml @@ -1,11 +1,9 @@ + 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.openltablets openl-tablets 1.0 - openl-tablets @@ -18,12 +16,17 @@ org.openl org.openl.core - 5.19.4 + ${openl.version} org.openl.rules org.openl.rules - 5.19.4 + ${openl.version} + + + 5.19.4 + + \ No newline at end of file diff --git a/rule-engines/openl-tablets/src/main/resources/logback.xml b/rule-engines/openl-tablets/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/rule-engines/openl-tablets/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/rule-engines/rulebook/pom.xml b/rule-engines/rulebook/pom.xml index 675776eb6f..90b5e55417 100644 --- a/rule-engines/rulebook/pom.xml +++ b/rule-engines/rulebook/pom.xml @@ -1,11 +1,9 @@ + 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.rulebook rulebook 1.0 - rulebook @@ -18,7 +16,12 @@ com.deliveredtechnologies rulebook-core - 0.6.2 + ${rulebook.version} + + + 0.6.2 + + \ No newline at end of file diff --git a/rule-engines/rulebook/src/main/resources/logback.xml b/rule-engines/rulebook/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/rule-engines/rulebook/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/rxjava-2/README.md b/rxjava-2/README.md new file mode 100644 index 0000000000..78eb6e6428 --- /dev/null +++ b/rxjava-2/README.md @@ -0,0 +1,7 @@ +## Relevant articles: + +- [RxJava and Error Handling](http://www.baeldung.com/rxjava-error-handling) +- [RxJava 2 – Flowable](http://www.baeldung.com/rxjava-2-flowable) +- [RxJava 2 - Completable](http://www.baeldung.com/rxjava-completable) +- [RxJava Maybe](http://www.baeldung.com/rxjava-maybe) +- [Introduction to RxRelay for RxJava](http://www.baeldung.com/rx-relay) diff --git a/rxjava-2/pom.xml b/rxjava-2/pom.xml new file mode 100644 index 0000000000..a18b096b6d --- /dev/null +++ b/rxjava-2/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + rxjava-2 + 1.0-SNAPSHOT + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../parent-java + + + + + io.reactivex.rxjava2 + rxjava + ${rx.java2.version} + + + com.jayway.awaitility + awaitility + ${awaitility.version} + + + org.assertj + assertj-core + ${assertj.version} + + + com.jakewharton.rxrelay2 + rxrelay + ${rxrelay.version} + + + + + 3.8.0 + 2.2.2 + 1.7.0 + 2.0.0 + + \ No newline at end of file diff --git a/rxjava/src/main/java/com/baeldung/rxjava/RandomRelay.java b/rxjava-2/src/main/java/com/baeldung/rxjava/RandomRelay.java similarity index 100% rename from rxjava/src/main/java/com/baeldung/rxjava/RandomRelay.java rename to rxjava-2/src/main/java/com/baeldung/rxjava/RandomRelay.java diff --git a/rxjava-2/src/main/resources/logback.xml b/rxjava-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/rxjava-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/CompletableUnitTest.java b/rxjava-2/src/test/java/com/baeldung/rxjava/CompletableUnitTest.java new file mode 100644 index 0000000000..6acda310a5 --- /dev/null +++ b/rxjava-2/src/test/java/com/baeldung/rxjava/CompletableUnitTest.java @@ -0,0 +1,112 @@ +package com.baeldung.rxjava; + +import io.reactivex.Completable; +import io.reactivex.Flowable; +import io.reactivex.Single; +import io.reactivex.observers.DisposableCompletableObserver; +import org.junit.Before; +import org.junit.Test; + +public class CompletableUnitTest { + + Completable first; + Completable second; + Completable error; + Throwable throwable = new RuntimeException(); + + @Before + public void setUpCompletables() { + first = Completable.fromSingle(Single.just(1)); + second = Completable.fromRunnable(() -> {}); + error = Single.error(throwable) + .ignoreElement(); + } + + @Test + public void whenCompletableConstructed_thenCompletedSuccessfully() { + Completable completed = Completable.complete(); + completed.subscribe(new DisposableCompletableObserver() { + @Override + public void onComplete() { + System.out.println("Completed!"); + } + + @Override + public void onError(Throwable e) { + e.printStackTrace(); + } + }); + Flowable flowable = Flowable.just("request received", "user logged in"); + Completable flowableCompletable = Completable.fromPublisher(flowable); + Completable singleCompletable = Single.just(1) + .ignoreElement(); + + completed.andThen(flowableCompletable) + .andThen(singleCompletable) + .test() + .assertComplete(); + } + + @Test + public void whenCombiningCompletables_thenCompletedSuccessfully() { + first.andThen(second) + .test() + .assertComplete(); + } + + @Test + public void whenCombinedWithError_thenCompletedWithError() { + first.andThen(second) + .andThen(error) + .test() + .assertError(throwable); + } + + @Test + public void whenCombinedWithNever_thenDoesNotComplete() { + first.andThen(second) + .andThen(Completable.never()) + .test() + .assertNotComplete(); + } + + @Test + public void whenMergedCompletables_thenCompletedSuccessfully() { + Completable.mergeArray(first, second) + .test() + .assertComplete(); + } + + @Test + public void whenMergedWithError_thenCompletedWithError() { + Completable.mergeArray(first, second, error) + .test() + .assertError(throwable); + } + + @Test + public void whenFlatMaped_thenCompletedSuccessfully() { + Completable allElementsCompletable = Flowable.just("request received", "user logged in") + .flatMapCompletable(message -> Completable + .fromRunnable(() -> System.out.println(message)) + ); + allElementsCompletable + .test() + .assertComplete(); + } + + @Test + public void whenAmbWithNever_thenCompletedSuccessfully() { + Completable.ambArray(first, Completable.never(), second) + .test() + .assertComplete(); + } + + @Test + public void whenAmbWithError_thenCompletedWithError() { + Completable.ambArray(error, first, second) + .test() + .assertError(throwable); + } + +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/FlowableIntegrationTest.java b/rxjava-2/src/test/java/com/baeldung/rxjava/FlowableIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/FlowableIntegrationTest.java rename to rxjava-2/src/test/java/com/baeldung/rxjava/FlowableIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/MaybeUnitTest.java b/rxjava-2/src/test/java/com/baeldung/rxjava/MaybeUnitTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/MaybeUnitTest.java rename to rxjava-2/src/test/java/com/baeldung/rxjava/MaybeUnitTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxRelayIntegrationTest.java b/rxjava-2/src/test/java/com/baeldung/rxjava/RxRelayIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/RxRelayIntegrationTest.java rename to rxjava-2/src/test/java/com/baeldung/rxjava/RxRelayIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingIntegrationTest.java b/rxjava-2/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingIntegrationTest.java rename to rxjava-2/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingIntegrationTest.java diff --git a/rxjava/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryIntegrationTest.java b/rxjava-2/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryIntegrationTest.java similarity index 100% rename from rxjava/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryIntegrationTest.java rename to rxjava-2/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryIntegrationTest.java diff --git a/rxjava-2/src/test/java/com/baeldung/rxjava/operators/RxFlatmapAndSwitchmapUnitTest.java b/rxjava-2/src/test/java/com/baeldung/rxjava/operators/RxFlatmapAndSwitchmapUnitTest.java new file mode 100644 index 0000000000..ade48a2cb9 --- /dev/null +++ b/rxjava-2/src/test/java/com/baeldung/rxjava/operators/RxFlatmapAndSwitchmapUnitTest.java @@ -0,0 +1,65 @@ +package com.baeldung.rxjava.operators; + +import io.reactivex.Observable; +import io.reactivex.schedulers.TestScheduler; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.hamcrest.CoreMatchers.hasItems; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +public class RxFlatmapAndSwitchmapUnitTest { + @Test + public void givenObservable_whenFlatmap_shouldAssertAllItemsReturned() { + //given + List actualOutput = new ArrayList<>(); + final TestScheduler scheduler = new TestScheduler(); + final List keywordToSearch = Arrays.asList("b", "bo", "boo", "book", "books"); + + //when + Observable.fromIterable(keywordToSearch) + .flatMap(s -> Observable + .just(s + " FirstResult", s + " SecondResult") + .delay(10, TimeUnit.SECONDS, scheduler)) + .toList() + .doOnSuccess(s -> actualOutput.addAll(s)) + .subscribe(); + + scheduler.advanceTimeBy(1, TimeUnit.MINUTES); + + //then + assertThat(actualOutput, hasItems("b FirstResult", "b SecondResult", + "boo FirstResult", "boo SecondResult", + "bo FirstResult", "bo SecondResult", + "book FirstResult", "book SecondResult", + "books FirstResult", "books SecondResult")); + } + + @Test + public void givenObservable_whenSwitchmap_shouldAssertLatestItemReturned() { + //given + List actualOutput = new ArrayList<>(); + final TestScheduler scheduler = new TestScheduler(); + final List keywordToSearch = Arrays.asList("b", "bo", "boo", "book", "books"); + + //when + Observable.fromIterable(keywordToSearch) + .switchMap(s -> Observable + .just(s + " FirstResult", s + " SecondResult") + .delay(10, TimeUnit.SECONDS, scheduler)) + .toList() + .doOnSuccess(s -> actualOutput.addAll(s)) + .subscribe(); + + scheduler.advanceTimeBy(1, TimeUnit.MINUTES); + + //then + assertEquals(2, actualOutput.size()); + assertThat(actualOutput, hasItems("books FirstResult", "books SecondResult")); + } +} diff --git a/rxjava/README.md b/rxjava/README.md index 3376c49426..f8a4ca1dbe 100644 --- a/rxjava/README.md +++ b/rxjava/README.md @@ -4,14 +4,12 @@ - [How to Test RxJava?](http://www.baeldung.com/rxjava-testing) - [Implementing Custom Operators in RxJava](http://www.baeldung.com/rxjava-custom-operators) - [Introduction to RxJava](http://www.baeldung.com/rx-java) -- [RxJava and Error Handling](http://www.baeldung.com/rxjava-error-handling) - [Observable Utility Operators in RxJava](http://www.baeldung.com/rxjava-observable-operators) - [Introduction to rxjava-jdbc](http://www.baeldung.com/rxjava-jdbc) - [Schedulers in RxJava](http://www.baeldung.com/rxjava-schedulers) - [Mathematical and Aggregate Operators in RxJava](http://www.baeldung.com/rxjava-math) - [Combining Observables in RxJava](http://www.baeldung.com/rxjava-combine-observables) -- [RxJava 2 – Flowable](http://www.baeldung.com/rxjava-2-flowable) - [RxJava StringObservable](http://www.baeldung.com/rxjava-string) -- [RxJava Maybe](http://www.baeldung.com/rxjava-maybe) -- [Introduction to RxRelay for RxJava](http://www.baeldung.com/rx-relay) - [Filtering Observables in RxJava](http://www.baeldung.com/rxjava-filtering) +- [RxJava One Observable, Multiple Subscribers](http://www.baeldung.com/rxjava-multiple-subscribers-observable) +- [Difference Between Flatmap and Switchmap in RxJava](https://www.baeldung.com/rxjava-flatmap-switchmap) diff --git a/rxjava/pom.xml b/rxjava/pom.xml index 72d2859330..b316001d87 100644 --- a/rxjava/pom.xml +++ b/rxjava/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 rxjava @@ -9,8 +9,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java @@ -20,35 +20,22 @@ ${rx.java.version} - - io.reactivex.rxjava2 - rxjava - 2.1.3 - - io.reactivex rxjava-math - 1.0.0 + ${rx.java.math.version} io.reactivex rxjava-string - 1.1.1 - - - - junit - junit - 4.12 - test + ${rx.java.string.version} com.jayway.awaitility awaitility - 1.7.0 + ${awaitility.version} com.github.davidmoten @@ -66,19 +53,16 @@ assertj-core ${assertj.version} - - com.jakewharton.rxrelay2 - rxrelay - 2.0.0 - 3.8.0 1.2.5 0.7.11 + 1.0.0 + 1.1.1 + 1.7.0 1.4.196 - \ No newline at end of file diff --git a/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java new file mode 100644 index 0000000000..1d3e1b3f8a --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersColdObs.java @@ -0,0 +1,59 @@ +package com.baeldung.rxjava; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import rx.Observable; +import rx.Subscription; +import rx.observables.ConnectableObservable; +import rx.subscriptions.Subscriptions; + +public class MultipleSubscribersColdObs { + private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSubscribersColdObs.class); + + public static void main(String[] args) throws InterruptedException { + defaultBehaviour(); + // subscribeBeforeConnect(); + + } + + private static void defaultBehaviour() { + Observable obs = getObservable(); + + LOGGER.info("Subscribing"); + Subscription s1 = obs.subscribe(i -> LOGGER.info("subscriber#1 is printing " + i)); + Subscription s2 = obs.subscribe(i -> LOGGER.info("subscriber#2 is printing " + i)); + + s1.unsubscribe(); + s2.unsubscribe(); + } + + private static void subscribeBeforeConnect() throws InterruptedException { + ConnectableObservable obs = getObservable().publish(); + + LOGGER.info("Subscribing"); + obs.subscribe(i -> LOGGER.info("subscriber #1 is printing " + i)); + obs.subscribe(i -> LOGGER.info("subscriber #2 is printing " + i)); + Thread.sleep(1000); + LOGGER.info("Connecting"); + Subscription s = obs.connect(); + s.unsubscribe(); + + } + + private static Observable getObservable() { + return Observable.create(subscriber -> { + subscriber.onNext(gettingValue(1)); + subscriber.onNext(gettingValue(2)); + + subscriber.add(Subscriptions.create(() -> { + LOGGER.info("Clear resources"); + })); + }); + } + + private static Integer gettingValue(int i) { + LOGGER.info("Getting " + i); + return i; + } +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java new file mode 100644 index 0000000000..686c230003 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/MultipleSubscribersHotObs.java @@ -0,0 +1,152 @@ +package com.baeldung.rxjava; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.lang.reflect.InvocationTargetException; + +import javax.swing.JFrame; +import rx.Observable; +import rx.Subscription; +import rx.observables.ConnectableObservable; +import rx.subscriptions.Subscriptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MultipleSubscribersHotObs { + private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSubscribersHotObs.class); + private static JFrame frame; + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + + defaultBehaviour(); + // subscribeBeforeConnect(); + // connectBeforeSubscribe(); + // autoConnectAndSubscribe(); + // refCountAndSubscribe(); + } + + private static void createAndShowGUI() { + frame = new JFrame("Hot Observable Demo"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().setBackground(Color.GRAY); + frame.setPreferredSize(new Dimension(500, 500)); + frame.pack(); + frame.setVisible(true); + } + + public static void defaultBehaviour() throws InterruptedException { + Observable obs = getObservable(); + + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("unsubscribe#1"); + subscription1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe#2"); + subscription2.unsubscribe(); + } + + public static void subscribeBeforeConnect() throws InterruptedException { + + ConnectableObservable obs = getObservable().publish(); + + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("connecting:"); + Subscription s = obs.connect(); + Thread.sleep(1000); + LOGGER.info("unsubscribe connected"); + s.unsubscribe(); + + } + + public static void connectBeforeSubscribe() throws InterruptedException { + + ConnectableObservable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish(); + LOGGER.info("connecting:"); + Subscription s = obs.connect(); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + Thread.sleep(1000); + s.unsubscribe(); + + } + + public static void autoConnectAndSubscribe() throws InterruptedException { + Observable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish().autoConnect(); + + LOGGER.info("autoconnect()"); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + Subscription s1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription s2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("unsubscribe 1"); + s1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe 2"); + s2.unsubscribe(); + } + + public static void refCountAndSubscribe() throws InterruptedException { + Observable obs = getObservable().doOnNext(x -> LOGGER.info("saving " + x)).publish().refCount(); + + LOGGER.info("refcount()"); + Thread.sleep(1000); + LOGGER.info("subscribing #1"); + Subscription subscription1 = obs.subscribe((i) -> LOGGER.info("subscriber#1 is printing x-coordinate " + i)); + Thread.sleep(1000); + LOGGER.info("subscribing #2"); + Subscription subscription2 = obs.subscribe((i) -> LOGGER.info("subscriber#2 is printing x-coordinate " + i)); + + Thread.sleep(1000); + LOGGER.info("unsubscribe#1"); + subscription1.unsubscribe(); + Thread.sleep(1000); + LOGGER.info("unsubscribe#2"); + subscription2.unsubscribe(); + + } + + private static Observable getObservable() { + return Observable.create(subscriber -> { + frame.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + subscriber.onNext(e.getX()); + } + }); + subscriber.add(Subscriptions.create(() -> { + LOGGER.info("Clear resources"); + for (MouseListener listener : frame.getListeners(MouseListener.class)) { + frame.removeMouseListener(listener); + } + })); + }); + } +} diff --git a/rxjava/src/main/resources/logback.xml b/rxjava/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/rxjava/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/saas/pom.xml b/saas/pom.xml index bb951ceda8..2abc932497 100644 --- a/saas/pom.xml +++ b/saas/pom.xml @@ -37,20 +37,10 @@ - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.8 - 1.8 - - - org.codehaus.mojo exec-maven-plugin - 1.6.0 + ${exec-maven-plugin.version} java com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed @@ -74,11 +64,8 @@ - - 3.7.0 4.0.0 2.6.1 - 19.0 \ No newline at end of file diff --git a/saas/src/main/resources/logback.xml b/saas/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/saas/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spark-java/pom.xml b/spark-java/pom.xml index d8243345c5..ef33f4cbe0 100644 --- a/spark-java/pom.xml +++ b/spark-java/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung spark-java @@ -30,7 +29,6 @@ - UTF-8 2.5.4 2.8.0 diff --git a/spark-java/src/main/resources/logback.xml b/spark-java/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spark-java/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-4/README.md b/spring-4/README.md index 9855a9254d..4600a603ef 100644 --- a/spring-4/README.md +++ b/spring-4/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Guide to Flips For Spring](http://www.baeldung.com/guide-to-flips-for-spring/) - [A Guide to Flips for Spring](http://www.baeldung.com/flips-spring) +- [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari) diff --git a/spring-4/pom.xml b/spring-4/pom.xml index c81469d3eb..78939bba95 100644 --- a/spring-4/pom.xml +++ b/spring-4/pom.xml @@ -1,29 +1,45 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-4 spring-4 - 0.0.1-SNAPSHOT jar spring-4 - org.springframework.boot - spring-boot-starter-parent - 1.5.10.RELEASE - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 org.springframework.boot spring-boot-starter-web - ${spring-boot-starter-web.version} + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.apache.tomcat + tomcat-jdbc + + + + + com.h2database + h2 + test + + + com.zaxxer + HikariCP + org.springframework.boot spring-boot-starter-test - ${spring-boot-starter-test.version} com.github.feature-flip @@ -34,7 +50,6 @@ org.projectlombok lombok - ${lombok.version} provided @@ -56,12 +71,9 @@ - UTF-8 - 1.5.10.RELEASE - 1.5.9.RELEASE 1.0.1 1.16.18 - 1.8 + 1.4.197 diff --git a/spring-4/src/main/resources/logback.xml b/spring-4/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-4/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-4/src/test/java/com/baeldung/connectionpool/ApplicationWithHikariConnectionPool.java b/spring-4/src/test/java/com/baeldung/connectionpool/ApplicationWithHikariConnectionPool.java new file mode 100644 index 0000000000..0bd8637681 --- /dev/null +++ b/spring-4/src/test/java/com/baeldung/connectionpool/ApplicationWithHikariConnectionPool.java @@ -0,0 +1,12 @@ +package com.baeldung.connectionpool; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ApplicationWithHikariConnectionPool { + + public static void main(String[] args) { + SpringApplication.run(ApplicationWithHikariConnectionPool.class, args); + } +} diff --git a/spring-4/src/test/java/com/baeldung/connectionpool/HikariIntegrationTest.java b/spring-4/src/test/java/com/baeldung/connectionpool/HikariIntegrationTest.java new file mode 100644 index 0000000000..0cc876d5b1 --- /dev/null +++ b/spring-4/src/test/java/com/baeldung/connectionpool/HikariIntegrationTest.java @@ -0,0 +1,28 @@ +package com.baeldung.connectionpool; + +import static org.junit.Assert.*; + +import javax.sql.DataSource; + +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.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest( + // instead of setting this property, we can exclude the dependency to org.apache.tomcat:tomcat-jdbc in pom.xml + properties = "spring.datasource.type=com.zaxxer.hikari.HikariDataSource") +public class HikariIntegrationTest { + + @Autowired + private DataSource dataSource; + + @Test + public void hikariConnectionPoolIsConfigured() { + assertEquals("com.zaxxer.hikari.HikariDataSource", dataSource.getClass() + .getName()); + } + +} diff --git a/spring-4/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-4/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..9dfac2bd9e --- /dev/null +++ b/spring-4/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.flips.ApplicationConfig; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ApplicationConfig.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-5-data-reactive/README.md b/spring-5-data-reactive/README.md new file mode 100644 index 0000000000..f8886ac18b --- /dev/null +++ b/spring-5-data-reactive/README.md @@ -0,0 +1,8 @@ +## Spring Data Reactive Project + +### The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles +- [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-data-5-reactive/pom.xml b/spring-5-data-reactive/pom.xml similarity index 54% rename from spring-data-5-reactive/pom.xml rename to spring-5-data-reactive/pom.xml index 710f6f9d67..5c723c6e29 100644 --- a/spring-data-5-reactive/pom.xml +++ b/spring-5-data-reactive/pom.xml @@ -1,27 +1,16 @@ + 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 spring-5-data-reactive - 0.0.1-SNAPSHOT jar - Spring-5-data-reactive - Spring-5-data-reactive with Springboot 2.0.1 - - - org.springframework.boot - spring-boot-starter-parent - 2.0.1.RELEASE - - - - UTF-8 - UTF-8 - 1.8 - 1.2.40 - + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + @@ -32,11 +21,6 @@ org.springframework.boot spring-boot-starter-web - - javax.ws.rs - javax.ws.rs-api - ${javax.ws.rs-api.version} - com.fasterxml.jackson.module jackson-module-kotlin @@ -58,39 +42,29 @@ reactor-test test - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - org.jetbrains.kotlin kotlin-test ${kotlin.version} test + + io.reactivex.rxjava2 + rxjava + + - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} + org.springframework + spring-test + + + org.springframework.boot + spring-boot-starter-test + test - - - - spring-libs-snapshot - Spring Snapshot Repository - http://repo.spring.io/libs-snapshot - - - + - src/main/kotlin org.springframework.boot @@ -98,21 +72,31 @@ kotlin-maven-plugin - ${kotlin.version} - + ${kotlin-maven-plugin.version} + compile - compile compile + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/main/java + + test-compile - test-compile test-compile + + + ${project.basedir}/src/test/kotlin + ${project.basedir}/src/test/java + + org.jetbrains.kotlin @@ -133,6 +117,49 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + + compile + + + + java-test-compile + test-compile + + testCompile + + + + + + + 1.2.40 + 1.2.40 + + + diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/reactive/Spring5ReactiveApplication.java b/spring-5-data-reactive/src/main/java/com/baeldung/reactive/Spring5ReactiveApplication.java new file mode 100644 index 0000000000..e96767145e --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/reactive/Spring5ReactiveApplication.java @@ -0,0 +1,25 @@ +package com.baeldung.reactive; + +import com.mongodb.reactivestreams.client.MongoClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; + +@SpringBootApplication +public class Spring5ReactiveApplication{ + + public static void main(String[] args) { + SpringApplication.run(Spring5ReactiveApplication.class, args); + } + + @Autowired + MongoClient mongoClient; + + @Bean + public ReactiveMongoTemplate reactiveMongoTemplate() { + return new ReactiveMongoTemplate(mongoClient, "test"); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/model/Account.java b/spring-5-data-reactive/src/main/java/com/baeldung/reactive/model/Account.java similarity index 100% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/model/Account.java rename to spring-5-data-reactive/src/main/java/com/baeldung/reactive/model/Account.java diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/repository/AccountCrudRepository.java b/spring-5-data-reactive/src/main/java/com/baeldung/reactive/repository/AccountCrudRepository.java similarity index 100% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/repository/AccountCrudRepository.java rename to spring-5-data-reactive/src/main/java/com/baeldung/reactive/repository/AccountCrudRepository.java diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/repository/AccountMongoRepository.java b/spring-5-data-reactive/src/main/java/com/baeldung/reactive/repository/AccountMongoRepository.java similarity index 100% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/repository/AccountMongoRepository.java rename to spring-5-data-reactive/src/main/java/com/baeldung/reactive/repository/AccountMongoRepository.java diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/repository/AccountRxJavaRepository.java b/spring-5-data-reactive/src/main/java/com/baeldung/reactive/repository/AccountRxJavaRepository.java similarity index 100% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/repository/AccountRxJavaRepository.java rename to spring-5-data-reactive/src/main/java/com/baeldung/reactive/repository/AccountRxJavaRepository.java diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/template/AccountTemplateOperations.java b/spring-5-data-reactive/src/main/java/com/baeldung/reactive/template/AccountTemplateOperations.java similarity index 100% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/template/AccountTemplateOperations.java rename to spring-5-data-reactive/src/main/java/com/baeldung/reactive/template/AccountTemplateOperations.java diff --git a/spring-data-5-reactive/src/main/kotlin/com/baeldung/Application.kt b/spring-5-data-reactive/src/main/kotlin/com/baeldung/Application.kt similarity index 100% rename from spring-data-5-reactive/src/main/kotlin/com/baeldung/Application.kt rename to spring-5-data-reactive/src/main/kotlin/com/baeldung/Application.kt diff --git a/spring-data-5-reactive/src/main/kotlin/com/baeldung/Event.kt b/spring-5-data-reactive/src/main/kotlin/com/baeldung/Event.kt similarity index 100% rename from spring-data-5-reactive/src/main/kotlin/com/baeldung/Event.kt rename to spring-5-data-reactive/src/main/kotlin/com/baeldung/Event.kt diff --git a/spring-data-5-reactive/src/main/kotlin/com/baeldung/EventRepository.kt b/spring-5-data-reactive/src/main/kotlin/com/baeldung/EventRepository.kt similarity index 78% rename from spring-data-5-reactive/src/main/kotlin/com/baeldung/EventRepository.kt rename to spring-5-data-reactive/src/main/kotlin/com/baeldung/EventRepository.kt index a73ef8c807..e66af71ea6 100644 --- a/spring-data-5-reactive/src/main/kotlin/com/baeldung/EventRepository.kt +++ b/spring-5-data-reactive/src/main/kotlin/com/baeldung/EventRepository.kt @@ -4,6 +4,3 @@ import org.springframework.data.mongodb.core.mapping.Document import org.springframework.data.mongodb.repository.ReactiveMongoRepository interface EventRepository : ReactiveMongoRepository - -@Document -data class Event(val id: String, val name: String) diff --git a/spring-data-5-reactive/src/main/kotlin/com/baeldung/MongoConfig.kt b/spring-5-data-reactive/src/main/kotlin/com/baeldung/MongoConfig.kt similarity index 100% rename from spring-data-5-reactive/src/main/kotlin/com/baeldung/MongoConfig.kt rename to spring-5-data-reactive/src/main/kotlin/com/baeldung/MongoConfig.kt diff --git a/spring-data-5-reactive/src/main/kotlin/com/baeldung/SendEmitter.kt b/spring-5-data-reactive/src/main/kotlin/com/baeldung/SendEmitter.kt similarity index 100% rename from spring-data-5-reactive/src/main/kotlin/com/baeldung/SendEmitter.kt rename to spring-5-data-reactive/src/main/kotlin/com/baeldung/SendEmitter.kt diff --git a/spring-5-data-reactive/src/main/resources/logback.xml b/spring-5-data-reactive/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-5-data-reactive/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-data-5-reactive/src/main/resources/static/index.html b/spring-5-data-reactive/src/main/resources/static/index.html similarity index 100% rename from spring-data-5-reactive/src/main/resources/static/index.html rename to spring-5-data-reactive/src/main/resources/static/index.html diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryIntegrationTest.java similarity index 100% rename from spring-5-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryIntegrationTest.java rename to spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountCrudRepositoryIntegrationTest.java diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryIntegrationTest.java similarity index 100% rename from spring-5-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryIntegrationTest.java rename to spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountMongoRepositoryIntegrationTest.java diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryIntegrationTest.java similarity index 100% rename from spring-5-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryIntegrationTest.java rename to spring-5-data-reactive/src/test/java/com/baeldung/reactive/repository/AccountRxJavaRepositoryIntegrationTest.java diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsIntegrationTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsIntegrationTest.java similarity index 100% rename from spring-5-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsIntegrationTest.java rename to spring-5-data-reactive/src/test/java/com/baeldung/reactive/template/AccountTemplateOperationsIntegrationTest.java diff --git a/spring-5-data-reactive/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-5-data-reactive/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ce4c172960 --- /dev/null +++ b/spring-5-data-reactive/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.reactive.Spring5ReactiveApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Spring5ReactiveApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-5-mvc/README.md b/spring-5-mvc/README.md index c031a9d10e..fa9d48ab72 100644 --- a/spring-5-mvc/README.md +++ b/spring-5-mvc/README.md @@ -1,2 +1,5 @@ ### Relevant Articles: - [Spring Boot and Kotlin](http://www.baeldung.com/spring-boot-kotlin) +- [Spring MVC Streaming and SSE Request Processing](https://www.baeldung.com/spring-mvc-sse-streams) +- [Overview and Need for DelegatingFilterProxy in Spring](https://www.baeldung.com/spring-delegating-filter-proxy) +- [A Controller, Service and DAO Example with Spring Boot and JSF](https://www.baeldung.com/jsf-spring-boot-controller-service-dao) diff --git a/spring-5-mvc/pom.xml b/spring-5-mvc/pom.xml index ae9ceb990a..f5346a0fa0 100644 --- a/spring-5-mvc/pom.xml +++ b/spring-5-mvc/pom.xml @@ -1,6 +1,6 @@ + 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 spring-5-mvc @@ -82,11 +82,6 @@ spring-boot-starter-test test - - junit - junit - test - com.jayway.restassured rest-assured @@ -111,7 +106,7 @@ spring - 1.8 + ${java.version} @@ -137,50 +132,11 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - - false - - **/*IntegrationTest.java - **/*IntTest.java - **/*LiveTest.java - - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - + 2.9.0 - UTF-8 - UTF-8 - 1.8 - 5.0.2.RELEASE 1.1.2 - diff --git a/spring-5-mvc/src/main/java/com/baeldung/Constants.java b/spring-5-mvc/src/main/java/com/baeldung/Constants.java new file mode 100644 index 0000000000..472f3280b7 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/Constants.java @@ -0,0 +1,21 @@ +package com.baeldung; + +public class Constants { + + public static final String GENERIC_EXCEPTION = "Exception encountered!"; + + /** + * API endpoints. + */ + public static final String API_RBE = "/rbe"; + public static final String API_SSE = "/sse"; + public static final String API_SRB = "/srb"; + + /** + * API Responses. + */ + public static final String API_RBE_MSG = "I Was Sent From a Response Body Emitter!"; + public static final String API_SSE_MSG = "I Was Sent From a Sse!"; + public static final String API_SRB_MSG = "I Was Sent From a Streaming Response Body!"; + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java b/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java index 41b5c1eed1..8251467122 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java +++ b/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java @@ -1,7 +1,11 @@ package com.baeldung; +import javax.servlet.Filter; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.filter.DelegatingFilterProxy; +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; @SpringBootApplication public class Spring5Application { @@ -10,4 +14,31 @@ public class Spring5Application { SpringApplication.run(Spring5Application.class, args); } + public static class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + @Override + protected Class[] getRootConfigClasses() { + return null; + } + + @Override + protected Class[] getServletConfigClasses() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected String[] getServletMappings() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected javax.servlet.Filter[] getServletFilters() { + DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy(); + delegateFilterProxy.setTargetBeanName("loggingFilter"); + return new Filter[] { delegateFilterProxy }; + } + } + } diff --git a/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java b/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java index a9ffee14da..b06f50b742 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java +++ b/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java @@ -49,8 +49,6 @@ public class Foo { this.name = name; } - // - @Override public int hashCode() { final int prime = 31; diff --git a/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java b/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java index cf78977961..fa07555bba 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java +++ b/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java @@ -16,8 +16,6 @@ public class DataSetupBean implements InitializingBean { @Autowired private FooRepository repo; - // - @Override public void afterPropertiesSet() throws Exception { IntStream.range(1, 5).forEach(i -> repo.save(new Foo(randomAlphabetic(8)))); diff --git a/spring-5-mvc/src/main/java/com/baeldung/spring/filter/CustomFilter.java b/spring-5-mvc/src/main/java/com/baeldung/spring/filter/CustomFilter.java new file mode 100644 index 0000000000..4aa33cd749 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/spring/filter/CustomFilter.java @@ -0,0 +1,38 @@ +package com.baeldung.spring.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component("loggingFilter") +public class CustomFilter implements Filter { + + private static Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class); + + @Override + public void init(FilterConfig config) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + LOGGER.info("Request Info : " + req); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // cleanup code, if necessary + } +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java b/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java new file mode 100644 index 0000000000..c5f63486fe --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java @@ -0,0 +1,35 @@ +package com.baeldung.web; + +import com.baeldung.Constants; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; + +@Controller +public class ResponseBodyEmitterController { + private ExecutorService nonBlockingService = Executors.newCachedThreadPool(); + + @GetMapping(Constants.API_RBE) + public ResponseEntity handleRbe() { + ResponseBodyEmitter emitter = new ResponseBodyEmitter(); + + nonBlockingService.execute(() -> { + try { + emitter.send(Constants.API_RBE_MSG + " @ " + new Date(), MediaType.TEXT_PLAIN); + emitter.complete(); + } catch (Exception ex) { + System.out.println(Constants.GENERIC_EXCEPTION); + emitter.completeWithError(ex); + } + }); + + return new ResponseEntity(emitter, HttpStatus.OK); + } + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java b/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java new file mode 100644 index 0000000000..00113c5ff7 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java @@ -0,0 +1,59 @@ +package com.baeldung.web; + +import java.time.LocalTime; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter.SseEventBuilder; + +import com.baeldung.Constants; + +@Controller +public class SseEmitterController { + private ExecutorService nonBlockingService = Executors.newCachedThreadPool(); + + @GetMapping(Constants.API_SSE) + public SseEmitter handleSse() { + SseEmitter emitter = new SseEmitter(); + + nonBlockingService.execute(() -> { + try { + emitter.send(Constants.API_SSE_MSG + " @ " + new Date()); + emitter.complete(); + } catch (Exception ex) { + System.out.println(Constants.GENERIC_EXCEPTION); + emitter.completeWithError(ex); + } + }); + + return emitter; + } + + @GetMapping("/stream-sse-mvc") + public SseEmitter streamSseMvc() { + SseEmitter emitter = new SseEmitter(); + ExecutorService sseMvcExecutor = Executors.newSingleThreadExecutor(); + + sseMvcExecutor.execute(() -> { + try { + for (int i = 0; true; i++) { + SseEventBuilder event = SseEmitter.event() + .data("SSE MVC - " + LocalTime.now() + .toString()) + .id(String.valueOf(i)) + .name("sse event - mvc"); + emitter.send(event); + Thread.sleep(1000); + } + } catch (Exception ex) { + emitter.completeWithError(ex); + } + }); + return emitter; + } + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java b/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java new file mode 100644 index 0000000000..1722ad85cd --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java @@ -0,0 +1,23 @@ +package com.baeldung.web; + +import com.baeldung.Constants; +import java.util.Date; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +@Controller +public class StreamingResponseBodyController { + + @GetMapping(Constants.API_SRB) + public ResponseEntity handleRbe() { + StreamingResponseBody stream = out -> { + String msg = Constants.API_SRB_MSG + " @ " + new Date(); + out.write(msg.getBytes()); + }; + return new ResponseEntity(stream, HttpStatus.OK); + } + +} diff --git a/spring-5-mvc/src/main/resources/logback.xml b/spring-5-mvc/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-5-mvc/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp new file mode 100644 index 0000000000..df5baf7adb --- /dev/null +++ b/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp @@ -0,0 +1,86 @@ +<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> + + + + + + + Spring MVC Async + " rel="stylesheet"> + + +
    +

    Spring MVC Async

    +
    +
    +
    +
    + + + diff --git a/spring-5-mvc/src/main/webapp/WEB-INF/web.xml b/spring-5-mvc/src/main/webapp/WEB-INF/web.xml index bfcf43dad2..43c7143e5b 100644 --- a/spring-5-mvc/src/main/webapp/WEB-INF/web.xml +++ b/spring-5-mvc/src/main/webapp/WEB-INF/web.xml @@ -16,6 +16,14 @@ functional / + + loggingFilter + org.springframework.web.filter.DelegatingFilterProxy + + + loggingFilter + /* + \ No newline at end of file diff --git a/spring-5-reactive-client/pom.xml b/spring-5-reactive-client/pom.xml index ca1cbc475a..6e39743ed0 100644 --- a/spring-5-reactive-client/pom.xml +++ b/spring-5-reactive-client/pom.xml @@ -1,19 +1,18 @@ - + 4.0.0 - com.baeldung spring-5-reactive-client - 0.0.1-SNAPSHOT jar spring-5-reactive-client spring 5 sample project about new features - org.springframework.boot - spring-boot-starter-parent - 2.0.0.M7 - + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 @@ -42,20 +41,6 @@ javax.json.bind javax.json.bind-api - - - - - - - - - - - - - - org.apache.geronimo.specs geronimo-json_1.1_spec @@ -101,37 +86,10 @@ test - - org.junit.jupiter - junit-jupiter-api - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - test - - - org.junit.platform - junit-platform-runner - ${junit.platform.version} - test - - org.projectlombok lombok - - org.apache.commons - commons-lang3 - - @@ -144,54 +102,10 @@ JAR - - - org.apache.maven.plugins - maven-surefire-plugin - - 3 - true - methods - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LiveTest.java - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - UTF-8 - UTF-8 - 1.8 - 1.0.0 - 5.0.0 - 2.20 - 5.0.2.RELEASE 1.0.1.RELEASE 1.1.3 1.0 diff --git a/spring-5-reactive-client/src/main/resources/logback.xml b/spring-5-reactive-client/src/main/resources/logback.xml index 8bbe8c1d67..7072369b8d 100644 --- a/spring-5-reactive-client/src/main/resources/logback.xml +++ b/spring-5-reactive-client/src/main/resources/logback.xml @@ -3,7 +3,7 @@ # Pattern of log message for console appender - %d{yyyy-MM-dd HH:mm:ss} %-5p %m%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-5-reactive-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-5-reactive-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7843a8968d --- /dev/null +++ b/spring-5-reactive-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.reactive.Spring5ReactiveTestApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Spring5ReactiveTestApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-5-reactive-client/src/test/resources/logback-test.xml b/spring-5-reactive-client/src/test/resources/logback-test.xml index 8bbe8c1d67..7072369b8d 100644 --- a/spring-5-reactive-client/src/test/resources/logback-test.xml +++ b/spring-5-reactive-client/src/test/resources/logback-test.xml @@ -3,7 +3,7 @@ # Pattern of log message for console appender - %d{yyyy-MM-dd HH:mm:ss} %-5p %m%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-5-reactive-functional/src/main/resources/logback.xml b/spring-5-reactive-functional/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-5-reactive-functional/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jsonb/.gitignore b/spring-5-reactive-security/.gitignore similarity index 100% rename from jsonb/.gitignore rename to spring-5-reactive-security/.gitignore diff --git a/spring-5-reactive-security/README.md b/spring-5-reactive-security/README.md new file mode 100644 index 0000000000..3395cf5562 --- /dev/null +++ b/spring-5-reactive-security/README.md @@ -0,0 +1,11 @@ +## Spring 5 Reactive Security Examples + +### The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles + +- [Spring Boot Actuator](http://www.baeldung.com/spring-boot-actuators) +- [Spring Security 5 for Reactive Applications](http://www.baeldung.com/spring-security-5-reactive) +- [Guide to Spring 5 WebFlux](http://www.baeldung.com/spring-webflux) + diff --git a/spring-5-reactive-security/pom.xml b/spring-5-reactive-security/pom.xml new file mode 100644 index 0000000000..3b64b9b3ac --- /dev/null +++ b/spring-5-reactive-security/pom.xml @@ -0,0 +1,135 @@ + + + 4.0.0 + + com.baeldung + spring-5-reactive-security + 0.0.1-SNAPSHOT + jar + spring-5-reactive-security + spring 5 security sample project about new features + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-tomcat + + + org.springframework.boot + spring-boot-starter-webflux + + + org.projectreactor + reactor-spring + ${reactor-spring.version} + + + javax.json.bind + javax.json.bind-api + + + org.springframework.boot + spring-boot-starter-actuator + + + org.projectlombok + lombok + compile + + + org.apache.geronimo.specs + geronimo-json_1.1_spec + ${geronimo-json_1.1_spec.version} + + + org.apache.johnzon + johnzon-jsonb + + + + org.apache.commons + commons-lang3 + + + + + + org.springframework.boot + spring-boot-devtools + runtime + + + org.springframework + spring-test + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + test + + + + io.reactivex.rxjava2 + rxjava + ${rxjava-version} + + + io.projectreactor + reactor-test + ${project-reactor-test} + test + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.webflux.EmployeeSpringApplication + JAR + + + + + + + 1.0.1.RELEASE + 2.1.12 + 1.1.3 + 1.0 + 1.0 + 4.1 + 3.1.6.RELEASE + + + diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/actuator/DownstreamServiceReactiveHealthIndicator.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/DownstreamServiceReactiveHealthIndicator.java similarity index 100% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/actuator/DownstreamServiceReactiveHealthIndicator.java rename to spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/DownstreamServiceReactiveHealthIndicator.java diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/actuator/FeaturesEndpoint.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/FeaturesEndpoint.java similarity index 100% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/actuator/FeaturesEndpoint.java rename to spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/FeaturesEndpoint.java diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/actuator/InfoWebEndpointExtension.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/InfoWebEndpointExtension.java similarity index 100% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/actuator/InfoWebEndpointExtension.java rename to spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/InfoWebEndpointExtension.java diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/Spring5ReactiveApplication.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/Spring5ReactiveApplication.java new file mode 100644 index 0000000000..f07ddfb0f7 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/Spring5ReactiveApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.reactive.actuator; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class Spring5ReactiveApplication{ + + public static void main(String[] args) { + SpringApplication.run(Spring5ReactiveApplication.class, args); + } + +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/WebSecurityConfig.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/WebSecurityConfig.java new file mode 100644 index 0000000000..07f805fea4 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/actuator/WebSecurityConfig.java @@ -0,0 +1,28 @@ +package com.baeldung.reactive.actuator; + +import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@Configuration +@EnableWebFluxSecurity +public class WebSecurityConfig { + + + @Bean + public SecurityWebFilterChain securitygWebFilterChain( + ServerHttpSecurity http) { + return http + + .authorizeExchange() + .matchers(EndpointRequest.to( + FeaturesEndpoint.class + )).permitAll().anyExchange().permitAll().and().csrf().disable().build(); + } + +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/reactive/functional/EmployeeFunctionalConfig.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/functional/EmployeeFunctionalConfig.java new file mode 100644 index 0000000000..76b697c1aa --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/functional/EmployeeFunctionalConfig.java @@ -0,0 +1,75 @@ +package com.baeldung.reactive.functional; + +import static org.springframework.web.reactive.function.BodyExtractors.toMono; +import static org.springframework.web.reactive.function.server.RequestPredicates.GET; +import static org.springframework.web.reactive.function.server.RequestPredicates.POST; +import static org.springframework.web.reactive.function.server.RouterFunctions.route; +import static org.springframework.web.reactive.function.server.ServerResponse.ok; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.webflux.Employee; +import com.baeldung.webflux.EmployeeRepository; + +@Configuration +public class EmployeeFunctionalConfig { + + @Bean + EmployeeRepository employeeRepository() { + return new EmployeeRepository(); + } + + @Bean + RouterFunction getAllEmployeesRoute() { + return route(GET("/employees"), + req -> ok().body( + employeeRepository().findAllEmployees(), Employee.class)); + } + + @Bean + RouterFunction getEmployeeByIdRoute() { + return route(GET("/employees/{id}"), + req -> ok().body( + employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)); + } + + @Bean + RouterFunction updateEmployeeRoute() { + return route(POST("/employees/update"), + req -> req.body(toMono(Employee.class)) + .doOnNext(employeeRepository()::updateEmployee) + .then(ok().build())); + } + + @Bean + RouterFunction composedRoutes() { + return + route(GET("/employees"), + req -> ok().body( + employeeRepository().findAllEmployees(), Employee.class)) + + .and(route(GET("/employees/{id}"), + req -> ok().body( + employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class))) + + .and(route(POST("/employees/update"), + req -> req.body(toMono(Employee.class)) + .doOnNext(employeeRepository()::updateEmployee) + .then(ok().build()))); + } + + @Bean + public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + http.csrf() + .disable() + .authorizeExchange() + .anyExchange() + .permitAll(); + return http.build(); + } +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/reactive/functional/EmployeeSpringFunctionalApplication.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/functional/EmployeeSpringFunctionalApplication.java new file mode 100644 index 0000000000..1f2bd871fc --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/functional/EmployeeSpringFunctionalApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.reactive.functional; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class EmployeeSpringFunctionalApplication { + + public static void main(String[] args) { + SpringApplication.run(EmployeeSpringFunctionalApplication.class, args); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/security/GreetController.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/GreetController.java similarity index 95% rename from spring-5/src/main/java/com/baeldung/security/GreetController.java rename to spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/GreetController.java index 6b69e3bc9b..99b79d88ea 100644 --- a/spring-5/src/main/java/com/baeldung/security/GreetController.java +++ b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/GreetController.java @@ -1,4 +1,4 @@ -package com.baeldung.security; +package com.baeldung.reactive.security; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/spring-5/src/main/java/com/baeldung/security/GreetService.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/GreetService.java similarity index 88% rename from spring-5/src/main/java/com/baeldung/security/GreetService.java rename to spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/GreetService.java index 7622b360be..93df64bced 100644 --- a/spring-5/src/main/java/com/baeldung/security/GreetService.java +++ b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/GreetService.java @@ -1,4 +1,4 @@ -package com.baeldung.security; +package com.baeldung.reactive.security; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/SecurityConfig.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/SecurityConfig.java new file mode 100644 index 0000000000..225f78b3f7 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/SecurityConfig.java @@ -0,0 +1,60 @@ +package com.baeldung.reactive.security; + +import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.server.SecurityWebFilterChain; + +import com.baeldung.reactive.actuator.FeaturesEndpoint; + +@EnableWebFluxSecurity +@EnableReactiveMethodSecurity +public class SecurityConfig { + + @Bean + public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) { + return http.authorizeExchange() + .pathMatchers("/", "/admin") + .hasAuthority("ROLE_ADMIN") + .matchers(EndpointRequest.to(FeaturesEndpoint.class)) + .permitAll() + .anyExchange() + .permitAll() + .and() + .formLogin() + .and() + .csrf() + .disable() + .build(); + } + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + UserDetails user = User + .withUsername("user") + .password(passwordEncoder().encode("password")) + .roles("USER") + .build(); + + UserDetails admin = User + .withUsername("admin") + .password(passwordEncoder().encode("password")) + .roles("ADMIN") + .build(); + + return new MapReactiveUserDetailsService(user, admin); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/SpringSecurity5Application.java similarity index 92% rename from spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java rename to spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/SpringSecurity5Application.java index 02c91a1879..f2963c4fa5 100644 --- a/spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java +++ b/spring-5-reactive-security/src/main/java/com/baeldung/reactive/security/SpringSecurity5Application.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.reactive.security; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -11,7 +11,7 @@ import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import reactor.ipc.netty.NettyContext; import reactor.ipc.netty.http.server.HttpServer; -@ComponentScan(basePackages = {"com.baeldung.security"}) +@ComponentScan(basePackages = {"com.baeldung.reactive.security"}) @EnableWebFlux public class SpringSecurity5Application { diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/Employee.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/Employee.java new file mode 100644 index 0000000000..bbdf85d293 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/Employee.java @@ -0,0 +1,17 @@ +package com.baeldung.webflux; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Employee { + + private String id; + private String name; + + // standard getters and setters + +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeConfig.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeConfig.java new file mode 100644 index 0000000000..6e73004650 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeConfig.java @@ -0,0 +1,33 @@ +package com.baeldung.webflux; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.HandlerMapping; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; +import org.springframework.web.reactive.socket.WebSocketHandler; +import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; + +@Configuration +@EnableWebFlux +public class EmployeeConfig { + + @Bean + public HandlerMapping handlerMapping() { + Map map = new HashMap<>(); + map.put("/employee-feed", new EmployeeWebSocketHandler()); + + SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); + mapping.setUrlMap(map); + mapping.setOrder(10); + return mapping; + } + + @Bean + public WebSocketHandlerAdapter handlerAdapter() { + return new WebSocketHandlerAdapter(); + } +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeController.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeController.java new file mode 100644 index 0000000000..34e44afc8b --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeController.java @@ -0,0 +1,38 @@ +package com.baeldung.webflux; + +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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/employees") +public class EmployeeController { + + private EmployeeRepository employeeRepository; + + public EmployeeController(EmployeeRepository employeeRepository) { + this.employeeRepository = employeeRepository; + } + + @GetMapping("/{id}") + private Mono getEmployeeById(@PathVariable String id) { + return employeeRepository.findEmployeeById(id); + } + + @GetMapping + private Flux getAllEmployees() { + return employeeRepository.findAllEmployees(); + } + + @PostMapping("/update") + private Mono updateEmployee(@RequestBody Employee employee) { + return employeeRepository.updateEmployee(employee); + } + +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeCreationEvent.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeCreationEvent.java new file mode 100644 index 0000000000..d4f9a4fb02 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeCreationEvent.java @@ -0,0 +1,15 @@ +package com.baeldung.webflux; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +public class EmployeeCreationEvent { + private String employeeId; + private String creationTime; + public EmployeeCreationEvent(String employeeId, String creationTime) { + super(); + this.employeeId = employeeId; + this.creationTime = creationTime; + } +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeRepository.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeRepository.java new file mode 100644 index 0000000000..d7f618f178 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeRepository.java @@ -0,0 +1,64 @@ +package com.baeldung.webflux; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.stereotype.Repository; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Repository +public class EmployeeRepository { + + static Map employeeData; + + static Map employeeAccessData; + + static + { + employeeData = new HashMap<>(); + employeeData.put("1",new Employee("1","Employee 1")); + employeeData.put("2",new Employee("2","Employee 2")); + employeeData.put("3",new Employee("3","Employee 3")); + employeeData.put("4",new Employee("4","Employee 4")); + employeeData.put("5",new Employee("5","Employee 5")); + employeeData.put("6",new Employee("6","Employee 6")); + employeeData.put("7",new Employee("7","Employee 7")); + employeeData.put("8",new Employee("8","Employee 8")); + employeeData.put("9",new Employee("9","Employee 9")); + employeeData.put("10",new Employee("10","Employee 10")); + + employeeAccessData=new HashMap<>(); + employeeAccessData.put("1", "Employee 1 Access Key"); + employeeAccessData.put("2", "Employee 2 Access Key"); + employeeAccessData.put("3", "Employee 3 Access Key"); + employeeAccessData.put("4", "Employee 4 Access Key"); + employeeAccessData.put("5", "Employee 5 Access Key"); + employeeAccessData.put("6", "Employee 6 Access Key"); + employeeAccessData.put("7", "Employee 7 Access Key"); + employeeAccessData.put("8", "Employee 8 Access Key"); + employeeAccessData.put("9", "Employee 9 Access Key"); + employeeAccessData.put("10", "Employee 10 Access Key"); + } + + public Mono findEmployeeById(String id) + { + return Mono.just(employeeData.get(id)); + } + + public Flux findAllEmployees() + { + return Flux.fromIterable(employeeData.values()); + } + + public Mono updateEmployee(Employee employee) + { + Employee existingEmployee=employeeData.get(employee.getId()); + if(existingEmployee!=null) + { + existingEmployee.setName(employee.getName()); + } + return Mono.just(existingEmployee); + } +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeSpringApplication.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeSpringApplication.java new file mode 100644 index 0000000000..2652c36695 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeSpringApplication.java @@ -0,0 +1,17 @@ +package com.baeldung.webflux; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class EmployeeSpringApplication { + + public static void main(String[] args) { + + SpringApplication.run(EmployeeSpringApplication.class, args); + + EmployeeWebClient employeeWebClient = new EmployeeWebClient(); + employeeWebClient.consume(); + } + +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebClient.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebClient.java new file mode 100644 index 0000000000..eb32408a7f --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebClient.java @@ -0,0 +1,28 @@ +package com.baeldung.webflux; + +import org.springframework.web.reactive.function.client.WebClient; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public class EmployeeWebClient { + + WebClient client = WebClient.create("http://localhost:8080"); + + public void consume() { + + Mono employeeMono = client.get() + .uri("/employees/{id}", "1") + .retrieve() + .bodyToMono(Employee.class); + + employeeMono.subscribe(System.out::println); + + Flux employeeFlux = client.get() + .uri("/employees") + .retrieve() + .bodyToFlux(Employee.class); + + employeeFlux.subscribe(System.out::println); + } +} \ No newline at end of file diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSecurityConfig.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSecurityConfig.java new file mode 100644 index 0000000000..75475a0f08 --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSecurityConfig.java @@ -0,0 +1,46 @@ +package com.baeldung.webflux; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@EnableWebFluxSecurity +public class EmployeeWebSecurityConfig { + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + UserDetails user = User + .withUsername("admin") + .password(passwordEncoder().encode("password")) + .roles("ADMIN") + .build(); + return new MapReactiveUserDetailsService(user); + } + + @Bean + public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { + http.csrf() + .disable() + .authorizeExchange() + .pathMatchers(HttpMethod.POST, "/employees/update") + .hasRole("ADMIN") + .pathMatchers("/**") + .permitAll() + .and() + .httpBasic(); + return http.build(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSocketClient.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSocketClient.java new file mode 100644 index 0000000000..feb1eb62fb --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSocketClient.java @@ -0,0 +1,21 @@ +package com.baeldung.webflux; + +import java.net.URI; + +import org.springframework.web.reactive.socket.WebSocketMessage; +import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient; +import org.springframework.web.reactive.socket.client.WebSocketClient; + +public class EmployeeWebSocketClient { + + public static void main(String[] args) { + + WebSocketClient client = new ReactorNettyWebSocketClient(); + + client.execute(URI.create("ws://localhost:8080/employee-feed"), session -> session.receive() + .map(WebSocketMessage::getPayloadAsText) + .doOnNext(System.out::println) + .then()) + .block(); // to subscribe and return the value + } +} diff --git a/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSocketHandler.java b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSocketHandler.java new file mode 100644 index 0000000000..40b7b760ee --- /dev/null +++ b/spring-5-reactive-security/src/main/java/com/baeldung/webflux/EmployeeWebSocketHandler.java @@ -0,0 +1,39 @@ +package com.baeldung.webflux; + +import static java.time.LocalDateTime.now; +import static java.util.UUID.randomUUID; + +import java.time.Duration; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.socket.WebSocketHandler; +import org.springframework.web.reactive.socket.WebSocketSession; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Component("EmployeeWebSocketHandler") +public class EmployeeWebSocketHandler implements WebSocketHandler { + + ObjectMapper om = new ObjectMapper(); + + @Override + public Mono handle(WebSocketSession webSocketSession) { + + Flux employeeCreationEvent = Flux.generate(sink -> { + EmployeeCreationEvent event = new EmployeeCreationEvent(randomUUID().toString(), now().toString()); + try { + sink.next(om.writeValueAsString(event)); + } catch (JsonProcessingException e) { + sink.error(e); + } + }); + + return webSocketSession.send(employeeCreationEvent + .map(webSocketSession::textMessage) + .delayElements(Duration.ofSeconds(1))); + } +} diff --git a/spring-5-reactive-security/src/main/resources/application.properties b/spring-5-reactive-security/src/main/resources/application.properties new file mode 100644 index 0000000000..234834b894 --- /dev/null +++ b/spring-5-reactive-security/src/main/resources/application.properties @@ -0,0 +1,5 @@ +logging.level.root=INFO + +management.endpoints.web.exposure.include.=* + +info.app.name=Spring Boot 2 actuator Application diff --git a/spring-5-reactive-security/src/main/resources/files/hello.txt b/spring-5-reactive-security/src/main/resources/files/hello.txt new file mode 100644 index 0000000000..b6fc4c620b --- /dev/null +++ b/spring-5-reactive-security/src/main/resources/files/hello.txt @@ -0,0 +1 @@ +hello \ No newline at end of file diff --git a/spring-5-reactive-security/src/main/resources/files/test/test.txt b/spring-5-reactive-security/src/main/resources/files/test/test.txt new file mode 100644 index 0000000000..30d74d2584 --- /dev/null +++ b/spring-5-reactive-security/src/main/resources/files/test/test.txt @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/spring-5-reactive-security/src/main/resources/logback.xml b/spring-5-reactive-security/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-5-reactive-security/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-5-reactive-security/src/main/resources/static/client-websocket.html b/spring-5-reactive-security/src/main/resources/static/client-websocket.html new file mode 100644 index 0000000000..3f840e8bd4 --- /dev/null +++ b/spring-5-reactive-security/src/main/resources/static/client-websocket.html @@ -0,0 +1,34 @@ + + + + +Baeldung: Spring 5 Reactive Client WebSocket (Browser) + + + +
    + + + \ No newline at end of file diff --git a/spring-5-reactive-security/src/main/webapp/WEB-INF/web.xml b/spring-5-reactive-security/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..bfcf43dad2 --- /dev/null +++ b/spring-5-reactive-security/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,21 @@ + + + + Spring Functional Application + + + functional + com.baeldung.functional.RootServlet + 1 + true + + + functional + / + + + + \ No newline at end of file diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/actuator/ActuatorInfoIntegrationTest.java b/spring-5-reactive-security/src/test/java/com/baeldung/reactive/actuator/ActuatorInfoIntegrationTest.java similarity index 95% rename from spring-5-reactive/src/test/java/com/baeldung/reactive/actuator/ActuatorInfoIntegrationTest.java rename to spring-5-reactive-security/src/test/java/com/baeldung/reactive/actuator/ActuatorInfoIntegrationTest.java index 3020e86723..94979a18ca 100644 --- a/spring-5-reactive/src/test/java/com/baeldung/reactive/actuator/ActuatorInfoIntegrationTest.java +++ b/spring-5-reactive-security/src/test/java/com/baeldung/reactive/actuator/ActuatorInfoIntegrationTest.java @@ -9,8 +9,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.reactive.Spring5ReactiveApplication; - import java.io.IOException; import static org.junit.Assert.assertEquals; diff --git a/spring-5-reactive-security/src/test/java/com/baeldung/reactive/functional/EmployeeSpringFunctionalIntegrationTest.java b/spring-5-reactive-security/src/test/java/com/baeldung/reactive/functional/EmployeeSpringFunctionalIntegrationTest.java new file mode 100644 index 0000000000..6e73e8072c --- /dev/null +++ b/spring-5-reactive-security/src/test/java/com/baeldung/reactive/functional/EmployeeSpringFunctionalIntegrationTest.java @@ -0,0 +1,98 @@ +package com.baeldung.reactive.functional; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +import com.baeldung.webflux.Employee; +import com.baeldung.webflux.EmployeeRepository; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = EmployeeSpringFunctionalApplication.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class EmployeeSpringFunctionalIntegrationTest { + + @Autowired + private EmployeeFunctionalConfig config; + + @MockBean + private EmployeeRepository employeeRepository; + + @Test + public void givenEmployeeId_whenGetEmployeeById_thenCorrectEmployee() { + WebTestClient client = WebTestClient + .bindToRouterFunction(config.getEmployeeByIdRoute()) + .build(); + + Employee employee = new Employee("1", "Employee 1"); + + given(employeeRepository.findEmployeeById("1")).willReturn(Mono.just(employee)); + + client.get() + .uri("/employees/1") + .exchange() + .expectStatus() + .isOk() + .expectBody(Employee.class) + .isEqualTo(employee); + } + + @Test + public void whenGetAllEmployees_thenCorrectEmployees() { + WebTestClient client = WebTestClient + .bindToRouterFunction(config.getAllEmployeesRoute()) + .build(); + + List employeeList = new ArrayList<>(); + + Employee employee1 = new Employee("1", "Employee 1"); + Employee employee2 = new Employee("2", "Employee 2"); + + employeeList.add(employee1); + employeeList.add(employee2); + + Flux employeeFlux = Flux.fromIterable(employeeList); + given(employeeRepository.findAllEmployees()).willReturn(employeeFlux); + + client.get() + .uri("/employees") + .exchange() + .expectStatus() + .isOk() + .expectBodyList(Employee.class) + .isEqualTo(employeeList); + } + + @Test + public void whenUpdateEmployee_thenEmployeeUpdated() { + WebTestClient client = WebTestClient + .bindToRouterFunction(config.updateEmployeeRoute()) + .build(); + + Employee employee = new Employee("1", "Employee 1 Updated"); + + client.post() + .uri("/employees/update") + .body(Mono.just(employee), Employee.class) + .exchange() + .expectStatus() + .isOk(); + + verify(employeeRepository).updateEmployee(employee); + } +} diff --git a/spring-5-reactive-security/src/test/java/com/baeldung/reactive/webflux/EmployeeControllerIntegrationTest.java b/spring-5-reactive-security/src/test/java/com/baeldung/reactive/webflux/EmployeeControllerIntegrationTest.java new file mode 100644 index 0000000000..3dc832d781 --- /dev/null +++ b/spring-5-reactive-security/src/test/java/com/baeldung/reactive/webflux/EmployeeControllerIntegrationTest.java @@ -0,0 +1,76 @@ +package com.baeldung.reactive.webflux; + +import static org.mockito.BDDMockito.given; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +import com.baeldung.reactive.actuator.Spring5ReactiveApplication; +import com.baeldung.webflux.Employee; +import com.baeldung.webflux.EmployeeRepository; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes=Spring5ReactiveApplication.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class EmployeeControllerIntegrationTest { + + @Autowired + private WebTestClient testClient; + + @MockBean + private EmployeeRepository employeeRepository; + + @Test + public void givenEmployeeId_whenGetEmployeeById_thenCorrectEmployee() { + + Employee employee = new Employee("1", "Employee 1 Name"); + + given(employeeRepository.findEmployeeById("1")).willReturn(Mono.just(employee)); + testClient.get() + .uri("/employees/1") + .exchange() + .expectStatus() + .isOk() + .expectBody(Employee.class) + .isEqualTo(employee); + } + + @Test + public void whenGetAllEmployees_thenCorrectEmployees() { + + List employeeList = new ArrayList<>(); + + Employee employee1 = new Employee("1", "Employee 1 Name"); + Employee employee2 = new Employee("2", "Employee 2 Name"); + Employee employee3 = new Employee("3", "Employee 3 Name"); + + employeeList.add(employee1); + employeeList.add(employee2); + employeeList.add(employee3); + + Flux employeeFlux = Flux.fromIterable(employeeList); + + given(employeeRepository.findAllEmployees()).willReturn(employeeFlux); + testClient.get() + .uri("/employees") + .exchange() + .expectStatus() + .isOk() + .expectBodyList(Employee.class) + .hasSize(3) + .isEqualTo(employeeList); + } +} diff --git a/spring-5/src/test/java/com/baeldung/security/SecurityIntegrationTest.java b/spring-5-reactive-security/src/test/java/com/baeldung/security/SecurityIntegrationTest.java similarity index 94% rename from spring-5/src/test/java/com/baeldung/security/SecurityIntegrationTest.java rename to spring-5-reactive-security/src/test/java/com/baeldung/security/SecurityIntegrationTest.java index 1f8bb549c7..423500e09c 100644 --- a/spring-5/src/test/java/com/baeldung/security/SecurityIntegrationTest.java +++ b/spring-5-reactive-security/src/test/java/com/baeldung/security/SecurityIntegrationTest.java @@ -1,6 +1,5 @@ package com.baeldung.security; -import com.baeldung.SpringSecurity5Application; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -12,6 +11,8 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; +import com.baeldung.reactive.security.SpringSecurity5Application; + @RunWith(SpringRunner.class) @ContextConfiguration(classes = SpringSecurity5Application.class) public class SecurityIntegrationTest { diff --git a/spring-5-reactive-security/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-5-reactive-security/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2bcd974510 --- /dev/null +++ b/spring-5-reactive-security/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.reactive.security.SpringSecurity5Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringSecurity5Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-5-reactive-security/src/test/resources/baeldung-weekly.png b/spring-5-reactive-security/src/test/resources/baeldung-weekly.png new file mode 100644 index 0000000000..a1b7eebcab Binary files /dev/null and b/spring-5-reactive-security/src/test/resources/baeldung-weekly.png differ diff --git a/spring-5-reactive/README.md b/spring-5-reactive/README.md index df96d933ba..7977fd820f 100644 --- a/spring-5-reactive/README.md +++ b/spring-5-reactive/README.md @@ -1,20 +1,16 @@ -## Spring REST Example Project +## Spring 5 Reactive Project ### The Course The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles -- [Concurrent Test Execution in Spring 5](http://www.baeldung.com/spring-5-concurrent-tests) - [Introduction to the Functional Web Framework in Spring 5](http://www.baeldung.com/spring-5-functional-web) -- [Exploring the Spring 5 MVC URL Matching Improvements](http://www.baeldung.com/spring-5-mvc-url-matching) - [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient) -- [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans) -- [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](http://www.baeldung.com/spring-5-junit-config) -- [Spring Security 5 for Reactive Applications](http://www.baeldung.com/spring-security-5-reactive) -- [Spring 5 Testing with @EnabledIf Annotation](https://github.com/eugenp/tutorials/tree/master/spring-5) +- [Exploring the Spring 5 MVC URL Matching Improvements](http://www.baeldung.com/spring-5-mvc-url-matching) - [Reactive WebSockets with Spring 5](http://www.baeldung.com/spring-5-reactive-websockets) -- [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) +- [How to Set a Header on a Response with Spring 5](http://www.baeldung.com/spring-response-header) +- [Spring Webflux and CORS](http://www.baeldung.com/spring-webflux-cors) +- [Handling Errors in Spring WebFlux](http://www.baeldung.com/spring-webflux-errors) +- [Server-Sent Events in Spring](https://www.baeldung.com/spring-server-sent-events) diff --git a/spring-5-reactive/pom.xml b/spring-5-reactive/pom.xml index 6bec7f18cc..5f455c3906 100644 --- a/spring-5-reactive/pom.xml +++ b/spring-5-reactive/pom.xml @@ -1,6 +1,6 @@ + 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 @@ -39,24 +39,6 @@ javax.json.bind javax.json.bind-api - - org.springframework.boot - spring-boot-starter-actuator - - - - - - - - - - - - - - - org.projectlombok lombok @@ -101,41 +83,6 @@ test - - org.junit.jupiter - junit-jupiter-api - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - test - - - org.junit.platform - junit-platform-runner - ${junit.platform.version} - test - - - org.apache.commons - commons-lang3 - - - - org.springframework.boot - spring-boot-starter-data-mongodb-reactive - - - de.flapdoodle.embed - de.flapdoodle.embed.mongo - test - io.reactivex.rxjava2 rxjava @@ -147,7 +94,12 @@ ${project-reactor-test} test - + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + @@ -160,32 +112,10 @@ JAR - - - org.apache.maven.plugins - maven-surefire-plugin - - 3 - true - methods - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LiveTest.java - - - - UTF-8 - UTF-8 - 1.8 - 1.0.0 - 5.0.2 - 2.20 1.0.1.RELEASE 2.1.12 1.1.3 @@ -193,6 +123,7 @@ 1.0 4.1 3.1.6.RELEASE + 1.2.0 diff --git a/spring-5-reactive/src/main/java/com/baeldung/functional/Actor.java b/spring-5-reactive/src/main/java/com/baeldung/functional/Actor.java new file mode 100644 index 0000000000..23c88b89e1 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/functional/Actor.java @@ -0,0 +1,23 @@ +package com.baeldung.functional; + +class Actor { + private String firstname; + private String lastname; + + public Actor() { + } + + public Actor(String firstname, String lastname) { + this.firstname = firstname; + this.lastname = lastname; + } + + public String getFirstname() { + return firstname; + } + + public String getLastname() { + return lastname; + } + +} diff --git a/spring-5/src/main/java/com/baeldung/functional/FormHandler.java b/spring-5-reactive/src/main/java/com/baeldung/functional/FormHandler.java similarity index 94% rename from spring-5/src/main/java/com/baeldung/functional/FormHandler.java rename to spring-5-reactive/src/main/java/com/baeldung/functional/FormHandler.java index 05069735bb..c4f8c9f41f 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FormHandler.java +++ b/spring-5-reactive/src/main/java/com/baeldung/functional/FormHandler.java @@ -34,8 +34,7 @@ public class FormHandler { private AtomicLong extractData(List dataBuffers) { AtomicLong atomicLong = new AtomicLong(0); - dataBuffers.forEach(d -> atomicLong.addAndGet(d.asByteBuffer() - .array().length)); + dataBuffers.forEach(d -> atomicLong.addAndGet(d.readableByteCount())); return atomicLong; } } diff --git a/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java b/spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java similarity index 85% rename from spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java rename to spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java index 402b607b19..a1d5d87d5c 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java +++ b/spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java @@ -21,9 +21,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.core.io.ClassPathResource; import org.springframework.http.server.reactive.HttpHandler; -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.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; @@ -68,18 +65,6 @@ public class FunctionalSpringBootApplication { return registrationBean; } - @Configuration - @EnableWebSecurity - @Profile("!https") - static class SecurityConfig extends WebSecurityConfigurerAdapter { - @Override - protected void configure(final HttpSecurity http) throws Exception { - http.authorizeRequests() - .anyRequest() - .permitAll(); - } - } - public static void main(String[] args) { SpringApplication.run(FunctionalSpringBootApplication.class, args); } diff --git a/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java b/spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalWebApplication.java similarity index 95% rename from spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java rename to spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalWebApplication.java index 5a7d70d3db..1f40798ada 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java +++ b/spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalWebApplication.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.catalina.Context; +import org.apache.catalina.Wrapper; import org.apache.catalina.startup.Tomcat; import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; import org.springframework.boot.web.server.WebServer; @@ -61,7 +62,8 @@ public class FunctionalWebApplication { tomcat.setPort(9090); Context rootContext = tomcat.addContext("", System.getProperty("java.io.tmpdir")); ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler); - Tomcat.addServlet(rootContext, "httpHandlerServlet", servlet); + Wrapper servletWrapper = Tomcat.addServlet(rootContext, "httpHandlerServlet", servlet); + servletWrapper.setAsyncSupported(true); rootContext.addServletMappingDecoded("/", "httpHandlerServlet"); TomcatWebServer server = new TomcatWebServer(tomcat); diff --git a/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java b/spring-5-reactive/src/main/java/com/baeldung/functional/IndexRewriteFilter.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java rename to spring-5-reactive/src/main/java/com/baeldung/functional/IndexRewriteFilter.java diff --git a/spring-5/src/main/java/com/baeldung/functional/RootServlet.java b/spring-5-reactive/src/main/java/com/baeldung/functional/RootServlet.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/functional/RootServlet.java rename to spring-5-reactive/src/main/java/com/baeldung/functional/RootServlet.java diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/Spring5ReactiveApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/Spring5ReactiveApplication.java index e96767145e..1656f70221 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/Spring5ReactiveApplication.java +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/Spring5ReactiveApplication.java @@ -1,11 +1,9 @@ package com.baeldung.reactive; -import com.mongodb.reactivestreams.client.MongoClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.data.mongodb.core.ReactiveMongoTemplate; @SpringBootApplication public class Spring5ReactiveApplication{ @@ -14,12 +12,4 @@ public class Spring5ReactiveApplication{ SpringApplication.run(Spring5ReactiveApplication.class, args); } - @Autowired - MongoClient mongoClient; - - @Bean - public ReactiveMongoTemplate reactiveMongoTemplate() { - return new ReactiveMongoTemplate(mongoClient, "test"); - } - } diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/CorsOnAnnotatedElementsApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/CorsOnAnnotatedElementsApplication.java new file mode 100644 index 0000000000..d990928abe --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/CorsOnAnnotatedElementsApplication.java @@ -0,0 +1,17 @@ +package com.baeldung.reactive.cors.annotated; + +import java.util.Collections; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CorsOnAnnotatedElementsApplication { + + public static void main(String[] args) { + SpringApplication app = new SpringApplication(CorsOnAnnotatedElementsApplication.class); + app.setDefaultProperties(Collections.singletonMap("server.port", "8081")); + app.run(args); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/controllers/CorsOnClassController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/controllers/CorsOnClassController.java new file mode 100644 index 0000000000..00bc93a101 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/controllers/CorsOnClassController.java @@ -0,0 +1,49 @@ +package com.baeldung.reactive.cors.annotated.controllers; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +@CrossOrigin(value = { "http://allowed-origin.com" }, allowedHeaders = { "Baeldung-Another-Allowed" }, maxAge = 900) +@RestController +@RequestMapping("/cors-on-controller") +public class CorsOnClassController { + + @PutMapping("/regular-endpoint") + public Mono corsDisabledEndpoint() { + return Mono.just("Regular endpoint"); + } + + @CrossOrigin + @PutMapping("/cors-enabled-endpoint") + public Mono corsEnabledEndpoint() { + return Mono.just("CORS enabled endpoint"); + } + + @CrossOrigin({ "http://another-allowed-origin.com" }) + @PutMapping("/cors-enabled-origin-restrictive-endpoint") + public Mono corsEnabledOriginRestrictiveEndpoint() { + return Mono.just("CORS enabled endpoint - Origin Restrictive"); + } + + @CrossOrigin(allowedHeaders = { "Baeldung-Allowed" }) + @PutMapping("/cors-enabled-header-restrictive-endpoint") + public Mono corsEnabledHeaderRestrictiveEndpoint() { + return Mono.just("CORS enabled endpoint - Header Restrictive"); + } + + @CrossOrigin(exposedHeaders = { "Baeldung-Exposed" }) + @PutMapping("/cors-enabled-exposed-header-endpoint") + public Mono corsEnabledExposedHeadersEndpoint() { + return Mono.just("CORS enabled endpoint - Exposed Header"); + } + + @PutMapping("/cors-enabled-mixed-config-endpoint") + @CrossOrigin(allowedHeaders = { "Baeldung-Allowed", "Baeldung-Other-Allowed" }, exposedHeaders = { "Baeldung-Allowed", "Baeldung-Exposed" }, maxAge = 3600) + public Mono corsEnabledHeaderExposedEndpoint() { + return Mono.just("CORS enabled endpoint - Mixed Config"); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/controllers/CorsOnMethodsController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/controllers/CorsOnMethodsController.java new file mode 100644 index 0000000000..3c72d25840 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/annotated/controllers/CorsOnMethodsController.java @@ -0,0 +1,48 @@ +package com.baeldung.reactive.cors.annotated.controllers; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/cors-on-methods") +public class CorsOnMethodsController { + + @PutMapping("/cors-disabled-endpoint") + public Mono corsDisabledEndpoint() { + return Mono.just("CORS disabled endpoint"); + } + + @CrossOrigin + @PutMapping("/cors-enabled-endpoint") + public Mono corsEnabledEndpoint() { + return Mono.just("CORS enabled endpoint"); + } + + @CrossOrigin({ "http://allowed-origin.com" }) + @PutMapping("/cors-enabled-origin-restrictive-endpoint") + public Mono corsEnabledOriginRestrictiveEndpoint() { + return Mono.just("CORS enabled endpoint - Origin Restrictive"); + } + + @CrossOrigin(allowedHeaders = { "Baeldung-Allowed" }) + @PutMapping("/cors-enabled-header-restrictive-endpoint") + public Mono corsEnabledHeaderRestrictiveEndpoint() { + return Mono.just("CORS enabled endpoint - Header Restrictive"); + } + + @CrossOrigin(exposedHeaders = { "Baeldung-Exposed" }) + @PutMapping("/cors-enabled-exposed-header-endpoint") + public Mono corsEnabledExposedHeadersEndpoint() { + return Mono.just("CORS enabled endpoint - Exposed Header"); + } + + @PutMapping("/cors-enabled-mixed-config-endpoint") + @CrossOrigin(allowedHeaders = { "Baeldung-Allowed", "Baeldung-Other-Allowed" }, exposedHeaders = { "Baeldung-Allowed", "Baeldung-Exposed" }, maxAge = 3600) + public Mono corsEnabledHeaderExposedEndpoint() { + return Mono.just("CORS enabled endpoint - Mixed Config"); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/CorsGlobalConfigApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/CorsGlobalConfigApplication.java new file mode 100644 index 0000000000..8228944569 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/CorsGlobalConfigApplication.java @@ -0,0 +1,25 @@ +package com.baeldung.reactive.cors.global; + +import java.util.Collections; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; + +@SpringBootApplication(exclude = { MongoAutoConfiguration.class, + MongoDataAutoConfiguration.class, + MongoReactiveDataAutoConfiguration.class, + MongoReactiveAutoConfiguration.class } +) +public class CorsGlobalConfigApplication { + + public static void main(String[] args) { + SpringApplication app = new SpringApplication(CorsGlobalConfigApplication.class); + app.setDefaultProperties(Collections.singletonMap("server.port", "8082")); + app.run(args); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/config/CorsGlobalConfiguration.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/config/CorsGlobalConfiguration.java new file mode 100644 index 0000000000..92cd6ec50a --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/config/CorsGlobalConfiguration.java @@ -0,0 +1,22 @@ +package com.baeldung.reactive.cors.global.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.config.CorsRegistry; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +@Configuration +@EnableWebFlux +public class CorsGlobalConfiguration implements WebFluxConfigurer { + + @Override + public void addCorsMappings(CorsRegistry corsRegistry) { + corsRegistry.addMapping("/**") + .allowedOrigins("http://allowed-origin.com") + .allowedMethods("PUT") + .allowedHeaders("Baeldung-Allowed", "Baledung-Another-Allowed") + .exposedHeaders("Baeldung-Allowed", "Baeldung-Exposed") + .maxAge(3600); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/controllers/FurtherCorsConfigsController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/controllers/FurtherCorsConfigsController.java new file mode 100644 index 0000000000..4358326df8 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/controllers/FurtherCorsConfigsController.java @@ -0,0 +1,24 @@ +package com.baeldung.reactive.cors.global.controllers; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +@RestController("FurtherCorsConfigsController-cors-on-global-config-and-more") +@RequestMapping("/cors-on-global-config-and-more") +public class FurtherCorsConfigsController { + + @DeleteMapping("/further-mixed-config-endpoint") + @CrossOrigin(methods = { RequestMethod.DELETE }, + allowedHeaders = { "Baeldung-Other-Allowed" }, + exposedHeaders = { "Baeldung-Other-Exposed" } + ) + public Mono corsEnabledHeaderExposedEndpoint() { + return Mono.just("CORS Global Configured + Request Configs."); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/controllers/RegularRestController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/controllers/RegularRestController.java new file mode 100644 index 0000000000..e57e573146 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/controllers/RegularRestController.java @@ -0,0 +1,23 @@ +package com.baeldung.reactive.cors.global.controllers; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +@RestController("RegularRestController-cors-on-global-config") +@RequestMapping("/cors-on-global-config") +public class RegularRestController { + + @PutMapping("/regular-put-endpoint") + public Mono regularPutEndpoint() { + return Mono.just("Regular PUT endpoint"); + } + + @DeleteMapping("/regular-delete-endpoint") + public Mono regularDeleteEndpoint() { + return Mono.just("Regular DELETE endpoint"); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/functional/handlers/FunctionalHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/functional/handlers/FunctionalHandler.java new file mode 100644 index 0000000000..e6e32d7cc8 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/functional/handlers/FunctionalHandler.java @@ -0,0 +1,18 @@ +package com.baeldung.reactive.cors.global.functional.handlers; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import reactor.core.publisher.Mono; + +@Component +public class FunctionalHandler { + + public Mono useHandler(final ServerRequest request) { + final String responseMessage = "CORS GLOBAL CONFIG IS NOT EFFECTIVE ON FUNCTIONAL ENDPOINTS!!!"; + + return ServerResponse.ok() + .body(Mono.just(responseMessage), String.class); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/functional/routers/CorsRouterFunctions.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/functional/routers/CorsRouterFunctions.java new file mode 100644 index 0000000000..19621a9e97 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/global/functional/routers/CorsRouterFunctions.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.cors.global.functional.routers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.reactive.cors.global.functional.handlers.FunctionalHandler; + +@Configuration +public class CorsRouterFunctions { + + @Bean + public RouterFunction responseHeaderRoute(@Autowired FunctionalHandler handler) { + return RouterFunctions.route(RequestPredicates.PUT("/global-config-on-functional/cors-disabled-functional-endpoint"), handler::useHandler); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/CorsWebFilterApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/CorsWebFilterApplication.java new file mode 100644 index 0000000000..38140c0d71 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/CorsWebFilterApplication.java @@ -0,0 +1,25 @@ +package com.baeldung.reactive.cors.webfilter; + +import java.util.Collections; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; + +@SpringBootApplication(exclude = { MongoAutoConfiguration.class, + MongoDataAutoConfiguration.class, + MongoReactiveDataAutoConfiguration.class, + MongoReactiveAutoConfiguration.class } +) +public class CorsWebFilterApplication { + + public static void main(String[] args) { + SpringApplication app = new SpringApplication(CorsWebFilterApplication.class); + app.setDefaultProperties(Collections.singletonMap("server.port", "8083")); + app.run(args); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/config/CorsWebFilterConfig.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/config/CorsWebFilterConfig.java new file mode 100644 index 0000000000..55fbcc2903 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/config/CorsWebFilterConfig.java @@ -0,0 +1,29 @@ +package com.baeldung.reactive.cors.webfilter.config; + +import java.util.Arrays; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.reactive.CorsWebFilter; +import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; +import org.springframework.web.util.pattern.PathPatternParser; + +@Configuration +public class CorsWebFilterConfig { + + @Bean + CorsWebFilter corsWebFilter() { + CorsConfiguration corsConfig = new CorsConfiguration(); + corsConfig.setAllowedOrigins(Arrays.asList("http://allowed-origin.com")); + corsConfig.setMaxAge(8000L); + corsConfig.addAllowedMethod("PUT"); + corsConfig.addAllowedHeader("Baeldung-Allowed"); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); + source.registerCorsConfiguration("/**", corsConfig); + + return new CorsWebFilter(source); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/controllers/FurtherCorsConfigsController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/controllers/FurtherCorsConfigsController.java new file mode 100644 index 0000000000..bc5b483935 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/controllers/FurtherCorsConfigsController.java @@ -0,0 +1,26 @@ +package com.baeldung.reactive.cors.webfilter.controllers; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +//@RestController +//@RequestMapping("/web-filter-and-more-on-annotated") +public class FurtherCorsConfigsController { + + @DeleteMapping("/further-mixed-config-endpoint") + @CrossOrigin(methods = { RequestMethod.DELETE }, + allowedHeaders = { "Baeldung-Other-Allowed" }, + exposedHeaders = { "Baeldung-Other-Exposed" } + ) + public Mono corsEnabledHeaderExposedEndpoint() { + final String responseMessage = "CORS @CrossOrigin IS NOT EFFECTIVE with WebFilter!!!"; + + return Mono.just(responseMessage); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/controllers/RegularRestController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/controllers/RegularRestController.java new file mode 100644 index 0000000000..1d382b222a --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/controllers/RegularRestController.java @@ -0,0 +1,23 @@ +package com.baeldung.reactive.cors.webfilter.controllers; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +//@RestController +//@RequestMapping("/web-filter-on-annotated") +public class RegularRestController { + + @PutMapping("/regular-put-endpoint") + public Mono regularPutEndpoint() { + return Mono.just("Regular PUT endpoint"); + } + + @DeleteMapping("/regular-delete-endpoint") + public Mono regularDeleteEndpoint() { + return Mono.just("Regular DELETE endpoint"); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/functional/handlers/CorsWithWebFilterHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/functional/handlers/CorsWithWebFilterHandler.java new file mode 100644 index 0000000000..04e4602049 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/functional/handlers/CorsWithWebFilterHandler.java @@ -0,0 +1,16 @@ +package com.baeldung.reactive.cors.webfilter.functional.handlers; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import reactor.core.publisher.Mono; + +@Component +public class CorsWithWebFilterHandler { + + public Mono useHandler(final ServerRequest request) { + return ServerResponse.ok() + .body(Mono.just("Functional Endpoint"), String.class); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/functional/routers/CorsWithWebFilterRouterFunctions.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/functional/routers/CorsWithWebFilterRouterFunctions.java new file mode 100644 index 0000000000..a3905bb79f --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/cors/webfilter/functional/routers/CorsWithWebFilterRouterFunctions.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.cors.webfilter.functional.routers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.reactive.cors.webfilter.functional.handlers.CorsWithWebFilterHandler; + +@Configuration +public class CorsWithWebFilterRouterFunctions { + + @Bean + public RouterFunction responseHeaderRoute(@Autowired CorsWithWebFilterHandler handler) { + return RouterFunctions.route(RequestPredicates.PUT("/web-filter-on-functional/functional-endpoint"), handler::useHandler); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java new file mode 100644 index 0000000000..a50651ced7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java @@ -0,0 +1,55 @@ + +package com.baeldung.reactive.errorhandling; + +import java.util.Map; +import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; + +@Component +public class GlobalErrorAttributes extends DefaultErrorAttributes{ + + private HttpStatus status = HttpStatus.BAD_REQUEST; + private String message = "please provide a name"; + + public GlobalErrorAttributes() { + super(false); + } + + @Override + public Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) { + Map map = super.getErrorAttributes(request, includeStackTrace); + map.put("status", getStatus()); + map.put("message", getMessage()); + return map; + } + + /** + * @return the status + */ + public HttpStatus getStatus() { + return status; + } + + /** + * @param status the status to set + */ + public void setStatus(HttpStatus status) { + this.status = status; + } + + /** + * @return the message + */ + public String getMessage() { + return message; + } + + /** + * @param message the message to set + */ + public void setMessage(String message) { + this.message = message; + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java new file mode 100644 index 0000000000..09bccb0d5e --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorWebExceptionHandler.java @@ -0,0 +1,47 @@ + +package com.baeldung.reactive.errorhandling; + +import java.util.Map; +import org.springframework.boot.autoconfigure.web.ResourceProperties; +import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; +import org.springframework.boot.web.reactive.error.ErrorAttributes; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +@Order(-2) +public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { + + public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext, + ServerCodecConfigurer serverCodecConfigurer) { + super(g, new ResourceProperties(), applicationContext); + super.setMessageWriters(serverCodecConfigurer.getWriters()); + super.setMessageReaders(serverCodecConfigurer.getReaders()); + } + + @Override + protected RouterFunction getRoutingFunction(final ErrorAttributes errorAttributes) { + return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); + } + + private Mono renderErrorResponse(final ServerRequest request) { + + final Map errorPropertiesMap = getErrorAttributes(request, false); + + return ServerResponse.status(HttpStatus.BAD_REQUEST) + .contentType(MediaType.APPLICATION_JSON_UTF8) + .body(BodyInserters.fromObject(errorPropertiesMap)); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java new file mode 100644 index 0000000000..38d35544a7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/NameRequiredException.java @@ -0,0 +1,12 @@ + +package com.baeldung.reactive.errorhandling; + +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + +public class NameRequiredException extends ResponseStatusException { + + public NameRequiredException(HttpStatus status, String message, Throwable e) { + super(status, message, e); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java new file mode 100644 index 0000000000..87b78a4654 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java @@ -0,0 +1,29 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler1 { + + public Mono handleRequest1(ServerRequest request) { + return sayHello(request).onErrorReturn("Hello, Stranger") + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)); + } + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java new file mode 100644 index 0000000000..12172a0f54 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java @@ -0,0 +1,38 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler2 { + +public Mono handleRequest2(ServerRequest request) { + return + sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)) + .onErrorResume(e -> sayHelloFallback() + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s))); +} + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + + private Mono sayHelloFallback() { + return Mono.just("Hello, Stranger"); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java new file mode 100644 index 0000000000..e95b039cce --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java @@ -0,0 +1,34 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler3 { + + public Mono handleRequest3(ServerRequest request) { + return + sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s)) + .onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " + + e.getMessage())).flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .syncBody(s))); + } + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name") + .get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java new file mode 100644 index 0000000000..3d6ef258d3 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java @@ -0,0 +1,30 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import com.baeldung.reactive.errorhandling.NameRequiredException; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler4 { + +public Mono handleRequest4(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request) + .onErrorResume(e -> + Mono.error(new NameRequiredException( + HttpStatus.BAD_REQUEST, "please provide a name", e))), String.class); +} + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name").get()); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java new file mode 100644 index 0000000000..41605b355b --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.handlers; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler5 { + + public Mono handleRequest5(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request), String.class); + + } + + private Mono sayHello(ServerRequest request) { + return Mono.just("Hello, " + request.queryParam("name").get()); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java new file mode 100644 index 0000000000..91be24571c --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler1; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router1 { + + @Bean + public RouterFunction routeRequest1(Handler1 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint1") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest1); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java new file mode 100644 index 0000000000..bc7831f494 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler2; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router2 { + + @Bean + public RouterFunction routeRequest2(Handler2 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint2") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest2); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java new file mode 100644 index 0000000000..461e6fe9e7 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler3; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router3 { + + @Bean + public RouterFunction routeRequest3(Handler3 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint3") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest3); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java new file mode 100644 index 0000000000..9dccc6858f --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler4; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router4 { + + @Bean + public RouterFunction routeRequest4(Handler4 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint4") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest4); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java new file mode 100644 index 0000000000..59fd587fc8 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java @@ -0,0 +1,22 @@ + +package com.baeldung.reactive.errorhandling.routers; + +import com.baeldung.reactive.errorhandling.handlers.Handler5; +import org.springframework.context.annotation.Bean; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +@Component +public class Router5 { + + @Bean + public RouterFunction routeRequest5(Handler5 handler) { + return RouterFunctions.route(RequestPredicates.GET("/api/endpoint5") + .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest5); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java new file mode 100644 index 0000000000..5220ea2f4c --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/controllers/ResponseHeaderController.java @@ -0,0 +1,35 @@ +package com.baeldung.reactive.responseheaders.controllers; + +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/response-header") +public class ResponseHeaderController { + + @GetMapping("/response-entity") + public Mono> usingResponseEntityBuilder() { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ResponseEntityBuilder"; + String responseBody = "Response with header using ResponseEntity (builder)"; + + return Mono.just(ResponseEntity.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(responseBody)); + } + + @GetMapping("/server-http-response") + public Mono usingServerHttpResponse(ServerHttpResponse response) { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ServerHttpResponse"; + String responseBody = "Response with header using ServerHttpResponse"; + + response.getHeaders().add(responseHeaderKey, responseHeaderValue); + return Mono.just(responseBody); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java new file mode 100644 index 0000000000..8d8484f5cd --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/filter/AddResponseHeaderWebFilter.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.responseheaders.filter; + +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; + +import reactor.core.publisher.Mono; + +@Component +public class AddResponseHeaderWebFilter implements WebFilter { + + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + exchange.getResponse() + .getHeaders() + .add("Baeldung-Example-Filter-Header", "Value-Filter"); + return chain.filter(exchange); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java new file mode 100644 index 0000000000..20f76d3b6e --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/handlers/ResponseHeaderHandler.java @@ -0,0 +1,21 @@ +package com.baeldung.reactive.responseheaders.functional.handlers; + +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import reactor.core.publisher.Mono; + +@Component +public class ResponseHeaderHandler { + + public Mono useHandler(final ServerRequest request) { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-Handler"; + String responseBody = "Response with header using Handler"; + + return ServerResponse.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(Mono.just(responseBody),String.class); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java new file mode 100644 index 0000000000..63f7c7f036 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/responseheaders/functional/routers/ResponseHeadersRouterFunctions.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.responseheaders.functional.routers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.reactive.responseheaders.functional.handlers.ResponseHeaderHandler; + +@Configuration +public class ResponseHeadersRouterFunctions { + + @Bean + public RouterFunction responseHeaderRoute(@Autowired ResponseHeaderHandler handler) { + return RouterFunctions.route(RequestPredicates.GET("/functional-response-header/single-handler"), handler::useHandler); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/consumer/ConsumerSSEApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/consumer/ConsumerSSEApplication.java new file mode 100644 index 0000000000..3997607ef0 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/consumer/ConsumerSSEApplication.java @@ -0,0 +1,19 @@ +package com.baeldung.reactive.serversentevents.consumer; + +import java.util.Collections; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; + +@SpringBootApplication +@EnableAsync +public class ConsumerSSEApplication { + + public static void main(String[] args) { + SpringApplication app = new SpringApplication(ConsumerSSEApplication.class); + app.setDefaultProperties(Collections.singletonMap("server.port", "8082")); + app.run(args); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/consumer/controller/ClientController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/consumer/controller/ClientController.java new file mode 100644 index 0000000000..69a6bc396c --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/consumer/controller/ClientController.java @@ -0,0 +1,83 @@ +package com.baeldung.reactive.serversentevents.consumer.controller; + +import java.time.LocalTime; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.MediaType; +import org.springframework.http.codec.ServerSentEvent; +import org.springframework.scheduling.annotation.Async; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.reactive.function.client.WebClient; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RestController +@RequestMapping("/sse-consumer") +public class ClientController { + + private static Logger logger = LoggerFactory.getLogger(ClientController.class); + private WebClient client = WebClient.create("http://localhost:8081/sse-server"); + + @GetMapping("/launch-sse-client") + public String launchSSEFromSSEWebClient() { + consumeSSE(); + return "LAUNCHED EVENT CLIENT!!! Check the logs..."; + } + + @GetMapping("/launch-flux-client") + public String launchcFluxFromSSEWebClient() { + consumeFlux(); + return "LAUNCHED EVENT CLIENT!!! Check the logs..."; + } + + @GetMapping("/launch-sse-from-flux-endpoint-client") + public String launchFluxFromFluxWebClient() { + consumeSSEFromFluxEndpoint(); + return "LAUNCHED EVENT CLIENT!!! Check the logs..."; + } + + @Async + public void consumeSSE() { + ParameterizedTypeReference> type = new ParameterizedTypeReference>() { + }; + + Flux> eventStream = client.get() + .uri("/stream-sse") + .retrieve() + .bodyToFlux(type); + + eventStream.subscribe(content -> logger.info("Current time: {} - Received SSE: name[{}], id [{}], content[{}] ", LocalTime.now(), content.event(), content.id(), content.data()), error -> logger.error("Error receiving SSE: {}", error), + () -> logger.info("Completed!!!")); + } + + @Async + public void consumeFlux() { + Flux stringStream = client.get() + .uri("/stream-flux") + .accept(MediaType.TEXT_EVENT_STREAM) + .retrieve() + .bodyToFlux(String.class); + + stringStream.subscribe(content -> logger.info("Current time: {} - Received content: {} ", LocalTime.now(), content), error -> logger.error("Error retrieving content: {}", error), () -> logger.info("Completed!!!")); + } + + @Async + public void consumeSSEFromFluxEndpoint() { + ParameterizedTypeReference> type = new ParameterizedTypeReference>() { + }; + + Flux> eventStream = client.get() + .uri("/stream-flux") + .accept(MediaType.TEXT_EVENT_STREAM) + .retrieve() + .bodyToFlux(type); + + eventStream.subscribe(content -> logger.info("Current time: {} - Received SSE: name[{}], id [{}], content[{}] ", LocalTime.now(), content.event(), content.id(), content.data()), error -> logger.error("Error receiving SSE: {}", error), + () -> logger.info("Completed!!!")); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/server/ServerSSEApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/server/ServerSSEApplication.java new file mode 100644 index 0000000000..2750e6616d --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/server/ServerSSEApplication.java @@ -0,0 +1,17 @@ +package com.baeldung.reactive.serversentevents.server; + +import java.util.Collections; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ServerSSEApplication { + + public static void main(String[] args) { + SpringApplication app = new SpringApplication(ServerSSEApplication.class); + app.setDefaultProperties(Collections.singletonMap("server.port", "8081")); + app.run(args); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/server/controllers/ServerController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/server/controllers/ServerController.java new file mode 100644 index 0000000000..1ad8e848cf --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/serversentevents/server/controllers/ServerController.java @@ -0,0 +1,35 @@ +package com.baeldung.reactive.serversentevents.server.controllers; + +import java.time.Duration; +import java.time.LocalTime; + +import org.springframework.http.MediaType; +import org.springframework.http.codec.ServerSentEvent; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Flux; + +@RestController +@RequestMapping("/sse-server") +public class ServerController { + + @GetMapping("/stream-sse") + public Flux> streamEvents() { + return Flux.interval(Duration.ofSeconds(1)) + .map(sequence -> ServerSentEvent. builder() + .id(String.valueOf(sequence)) + .event("periodic-event") + .data("SSE - " + LocalTime.now() + .toString()) + .build()); + } + + @GetMapping(path = "/stream-flux", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux streamFlux() { + return Flux.interval(Duration.ofSeconds(1)) + .map(sequence -> "Flux - " + LocalTime.now() + .toString()); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/urlmatch/ExploreSpring5URLPatternUsingRouterFunctions.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/urlmatch/ExploreSpring5URLPatternUsingRouterFunctions.java index 78f40be57a..115a057915 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/urlmatch/ExploreSpring5URLPatternUsingRouterFunctions.java +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/urlmatch/ExploreSpring5URLPatternUsingRouterFunctions.java @@ -7,6 +7,7 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.t import static org.springframework.web.reactive.function.server.ServerResponse.ok; import org.apache.catalina.Context; +import org.apache.catalina.Wrapper; import org.apache.catalina.startup.Tomcat; import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; import org.springframework.boot.web.server.WebServer; @@ -41,7 +42,8 @@ public class ExploreSpring5URLPatternUsingRouterFunctions { tomcat.setPort(9090); Context rootContext = tomcat.addContext("", System.getProperty("java.io.tmpdir")); ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler); - Tomcat.addServlet(rootContext, "httpHandlerServlet", servlet); + Wrapper servletWrapper = Tomcat.addServlet(rootContext, "httpHandlerServlet", servlet); + servletWrapper.setAsyncSupported(true); rootContext.addServletMappingDecoded("/", "httpHandlerServlet"); TomcatWebServer server = new TomcatWebServer(tomcat); diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/util/CpuUtils.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/util/CpuUtils.java new file mode 100644 index 0000000000..8d16434920 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/util/CpuUtils.java @@ -0,0 +1,15 @@ +package com.baeldung.reactive.util; + +import com.sun.management.OperatingSystemMXBean; + +import java.lang.management.ManagementFactory; + +public class CpuUtils { + + private static OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); + + static Double getUsage() { + return (operatingSystemMXBean.getSystemCpuLoad() / operatingSystemMXBean.getAvailableProcessors()) * 100; + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/FunctionalValidationsApplication.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/FunctionalValidationsApplication.java new file mode 100644 index 0000000000..e548e33c85 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/FunctionalValidationsApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.validations.functional; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class FunctionalValidationsApplication { + + public static void main(String[] args) { + SpringApplication.run(FunctionalValidationsApplication.class, args); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/AbstractValidationHandler.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/AbstractValidationHandler.java new file mode 100644 index 0000000000..f34c1ee8d8 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/AbstractValidationHandler.java @@ -0,0 +1,45 @@ +package com.baeldung.validations.functional.handlers; + +import org.springframework.http.HttpStatus; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.ResponseStatusException; + +import reactor.core.publisher.Mono; + +public abstract class AbstractValidationHandler { + + private final Class validationClass; + + private final U validator; + + protected AbstractValidationHandler(Class clazz, U validator) { + this.validationClass = clazz; + this.validator = validator; + } + + abstract protected Mono processBody(T validBody, final ServerRequest originalRequest); + + public final Mono handleRequest(final ServerRequest request) { + return request.bodyToMono(this.validationClass) + .flatMap(body -> { + Errors errors = new BeanPropertyBindingResult(body, this.validationClass.getName()); + this.validator.validate(body, errors); + + if (errors == null || errors.getAllErrors() + .isEmpty()) { + return processBody(body, request); + } else { + return onValidationErrors(errors, body, request); + } + }); + } + + protected Mono onValidationErrors(Errors errors, T invalidBody, final ServerRequest request) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, errors.getAllErrors() + .toString()); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/FunctionalHandler.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/FunctionalHandler.java new file mode 100644 index 0000000000..d7e3bd0bc0 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/FunctionalHandler.java @@ -0,0 +1,43 @@ +package com.baeldung.validations.functional.handlers; + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.ResponseStatusException; + +import com.baeldung.validations.functional.model.CustomRequestEntity; +import com.baeldung.validations.functional.validators.CustomRequestEntityValidator; + +import reactor.core.publisher.Mono; + +@Component +public class FunctionalHandler { + + public Mono handleRequest(final ServerRequest request) { + Validator validator = new CustomRequestEntityValidator(); + Mono responseBody = request.bodyToMono(CustomRequestEntity.class) + .map(body -> { + Errors errors = new BeanPropertyBindingResult(body, CustomRequestEntity.class.getName()); + validator.validate(body, errors); + + if (errors == null || errors.getAllErrors() + .isEmpty()) { + return String.format("Hi, %s [%s]!", body.getName(), body.getCode()); + + } else { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, errors.getAllErrors() + .toString()); + } + + }); + return ServerResponse.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(responseBody, String.class); + + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/AnnotatedRequestEntityValidationHandler.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/AnnotatedRequestEntityValidationHandler.java new file mode 100644 index 0000000000..2011679741 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/AnnotatedRequestEntityValidationHandler.java @@ -0,0 +1,30 @@ +package com.baeldung.validations.functional.handlers.impl; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.validation.Validator; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.validations.functional.handlers.AbstractValidationHandler; +import com.baeldung.validations.functional.model.AnnotatedRequestEntity; + +import reactor.core.publisher.Mono; + +@Component +public class AnnotatedRequestEntityValidationHandler extends AbstractValidationHandler { + + private AnnotatedRequestEntityValidationHandler(@Autowired Validator validator) { + super(AnnotatedRequestEntity.class, validator); + } + + @Override + protected Mono processBody(AnnotatedRequestEntity validBody, ServerRequest originalRequest) { + String responseBody = String.format("Hi, %s. Password: %s!", validBody.getUser(), validBody.getPassword()); + return ServerResponse.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(responseBody), String.class); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/CustomRequestEntityValidationHandler.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/CustomRequestEntityValidationHandler.java new file mode 100644 index 0000000000..34630c60b2 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/CustomRequestEntityValidationHandler.java @@ -0,0 +1,37 @@ +package com.baeldung.validations.functional.handlers.impl; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.validations.functional.handlers.AbstractValidationHandler; +import com.baeldung.validations.functional.model.CustomRequestEntity; +import com.baeldung.validations.functional.validators.CustomRequestEntityValidator; + +import reactor.core.publisher.Mono; + +@Component +public class CustomRequestEntityValidationHandler extends AbstractValidationHandler { + + private CustomRequestEntityValidationHandler() { + super(CustomRequestEntity.class, new CustomRequestEntityValidator()); + } + + @Override + protected Mono processBody(CustomRequestEntity validBody, ServerRequest originalRequest) { + String responseBody = String.format("Hi, %s [%s]!", validBody.getName(), validBody.getCode()); + return ServerResponse.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(responseBody), String.class); + } + + @Override + protected Mono onValidationErrors(Errors errors, CustomRequestEntity invalidBody, final ServerRequest request) { + return ServerResponse.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(String.format("Custom message showing the errors: %s", errors.getAllErrors() + .toString())), String.class); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/OtherEntityValidationHandler.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/OtherEntityValidationHandler.java new file mode 100644 index 0000000000..0196287d13 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/handlers/impl/OtherEntityValidationHandler.java @@ -0,0 +1,28 @@ +package com.baeldung.validations.functional.handlers.impl; + +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.validations.functional.handlers.AbstractValidationHandler; +import com.baeldung.validations.functional.model.OtherEntity; +import com.baeldung.validations.functional.validators.OtherEntityValidator; + +import reactor.core.publisher.Mono; + +@Component +public class OtherEntityValidationHandler extends AbstractValidationHandler { + + private OtherEntityValidationHandler() { + super(OtherEntity.class, new OtherEntityValidator()); + } + + @Override + protected Mono processBody(OtherEntity validBody, ServerRequest originalRequest) { + String responseBody = String.format("Other object with item %s and quantity %s!", validBody.getItem(), validBody.getQuantity()); + return ServerResponse.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(responseBody), String.class); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/AnnotatedRequestEntity.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/AnnotatedRequestEntity.java new file mode 100644 index 0000000000..992f07481c --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/AnnotatedRequestEntity.java @@ -0,0 +1,23 @@ +package com.baeldung.validations.functional.model; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class AnnotatedRequestEntity { + @NotNull + private String user; + + @NotNull + @Size(min = 4, max = 7) + private String password; + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/CustomRequestEntity.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/CustomRequestEntity.java new file mode 100644 index 0000000000..ed459f121b --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/CustomRequestEntity.java @@ -0,0 +1,17 @@ +package com.baeldung.validations.functional.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class CustomRequestEntity { + + private String name; + private String code; + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/OtherEntity.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/OtherEntity.java new file mode 100644 index 0000000000..78667cb13d --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/model/OtherEntity.java @@ -0,0 +1,17 @@ +package com.baeldung.validations.functional.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +public class OtherEntity { + + private String item; + private Integer quantity; + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/routers/ValidationsRouters.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/routers/ValidationsRouters.java new file mode 100644 index 0000000000..efbdbe3f99 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/routers/ValidationsRouters.java @@ -0,0 +1,29 @@ +package com.baeldung.validations.functional.routers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.function.server.RequestPredicates; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.validations.functional.handlers.FunctionalHandler; +import com.baeldung.validations.functional.handlers.impl.AnnotatedRequestEntityValidationHandler; +import com.baeldung.validations.functional.handlers.impl.CustomRequestEntityValidationHandler; +import com.baeldung.validations.functional.handlers.impl.OtherEntityValidationHandler; + +@Configuration +public class ValidationsRouters { + + @Bean + public RouterFunction responseHeaderRoute(@Autowired CustomRequestEntityValidationHandler dryHandler, + @Autowired FunctionalHandler complexHandler, + @Autowired OtherEntityValidationHandler otherHandler, + @Autowired AnnotatedRequestEntityValidationHandler annotatedEntityHandler) { + return RouterFunctions.route(RequestPredicates.POST("/complex-handler-functional-validation"), complexHandler::handleRequest) + .andRoute(RequestPredicates.POST("/dry-functional-validation"), dryHandler::handleRequest) + .andRoute(RequestPredicates.POST("/other-dry-functional-validation"), otherHandler::handleRequest) + .andRoute(RequestPredicates.POST("/annotated-functional-validation"), annotatedEntityHandler::handleRequest); + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/validators/CustomRequestEntityValidator.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/validators/CustomRequestEntityValidator.java new file mode 100644 index 0000000000..085d477318 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/validators/CustomRequestEntityValidator.java @@ -0,0 +1,29 @@ +package com.baeldung.validations.functional.validators; + +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +import com.baeldung.validations.functional.model.CustomRequestEntity; + +public class CustomRequestEntityValidator implements Validator { + + private static final int MINIMUM_CODE_LENGTH = 6; + + @Override + public boolean supports(Class clazz) { + return CustomRequestEntity.class.isAssignableFrom(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "field.required"); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "code", "field.required"); + CustomRequestEntity request = (CustomRequestEntity) target; + if (request.getCode() != null && request.getCode() + .trim() + .length() < MINIMUM_CODE_LENGTH) { + errors.rejectValue("code", "field.min.length", new Object[] { Integer.valueOf(MINIMUM_CODE_LENGTH) }, "The code must be at least [" + MINIMUM_CODE_LENGTH + "] characters in length."); + } + } +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/validations/functional/validators/OtherEntityValidator.java b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/validators/OtherEntityValidator.java new file mode 100644 index 0000000000..18c2c28cfe --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/validations/functional/validators/OtherEntityValidator.java @@ -0,0 +1,27 @@ +package com.baeldung.validations.functional.validators; + +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +import com.baeldung.validations.functional.model.OtherEntity; + +public class OtherEntityValidator implements Validator { + + private static final int MIN_ITEM_QUANTITY = 1; + + @Override + public boolean supports(Class clazz) { + return OtherEntity.class.isAssignableFrom(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "item", "field.required"); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "quantity", "field.required"); + OtherEntity request = (OtherEntity) target; + if (request.getQuantity() != null && request.getQuantity() < MIN_ITEM_QUANTITY) { + errors.rejectValue("quantity", "field.min.length", new Object[] { Integer.valueOf(MIN_ITEM_QUANTITY) }, "There must be at least one item"); + } + } +} diff --git a/spring-5/src/main/java/com/baeldung/web/reactive/Task.java b/spring-5-reactive/src/main/java/com/baeldung/web/reactive/Task.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/web/reactive/Task.java rename to spring-5-reactive/src/main/java/com/baeldung/web/reactive/Task.java diff --git a/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java b/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientController.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java rename to spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientController.java diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/Event.java b/spring-5-reactive/src/main/java/com/baeldung/websocket/Event.java similarity index 79% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/Event.java rename to spring-5-reactive/src/main/java/com/baeldung/websocket/Event.java index 90f83a566f..5d0260928c 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/Event.java +++ b/spring-5-reactive/src/main/java/com/baeldung/websocket/Event.java @@ -1,4 +1,4 @@ -package com.baeldung.reactive.websocket; +package com.baeldung.websocket; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveJavaClientWebSocket.java b/spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveJavaClientWebSocket.java similarity index 95% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveJavaClientWebSocket.java rename to spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveJavaClientWebSocket.java index c9a333c044..efb4dc238a 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveJavaClientWebSocket.java +++ b/spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveJavaClientWebSocket.java @@ -1,4 +1,4 @@ -package com.baeldung.reactive.websocket; +package com.baeldung.websocket; import java.net.URI; import java.time.Duration; diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketApplication.java b/spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketApplication.java similarity index 88% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketApplication.java rename to spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketApplication.java index 43b5e50387..0e71673df6 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketApplication.java +++ b/spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketApplication.java @@ -1,4 +1,4 @@ -package com.baeldung.reactive.websocket; +package com.baeldung.websocket; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketConfiguration.java b/spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketConfiguration.java similarity index 88% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketConfiguration.java rename to spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketConfiguration.java index 974def5a91..43a98d068d 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketConfiguration.java +++ b/spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketConfiguration.java @@ -1,19 +1,22 @@ -package com.baeldung.reactive.websocket; +package com.baeldung.websocket; + +import java.util.HashMap; +import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; -import java.util.HashMap; -import java.util.Map; @Configuration public class ReactiveWebSocketConfiguration { @Autowired + @Qualifier("ReactiveWebSocketHandler") private WebSocketHandler webSocketHandler; @Bean diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketHandler.java b/spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketHandler.java similarity index 95% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketHandler.java rename to spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketHandler.java index 2e93c0c0dc..f85f2c0424 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketHandler.java +++ b/spring-5-reactive/src/main/java/com/baeldung/websocket/ReactiveWebSocketHandler.java @@ -1,4 +1,4 @@ -package com.baeldung.reactive.websocket; +package com.baeldung.websocket; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -14,7 +14,7 @@ import java.time.Duration; import static java.time.LocalDateTime.now; import static java.util.UUID.randomUUID; -@Component +@Component("ReactiveWebSocketHandler") public class ReactiveWebSocketHandler implements WebSocketHandler { private static final ObjectMapper json = new ObjectMapper(); diff --git a/spring-5-reactive/src/main/resources/application.properties b/spring-5-reactive/src/main/resources/application.properties index 234834b894..92f3116f84 100644 --- a/spring-5-reactive/src/main/resources/application.properties +++ b/spring-5-reactive/src/main/resources/application.properties @@ -1,5 +1,2 @@ logging.level.root=INFO -management.endpoints.web.exposure.include.=* - -info.app.name=Spring Boot 2 actuator Application diff --git a/spring-5-reactive/src/main/resources/logback.xml b/spring-5-reactive/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-5-reactive/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java rename to spring-5-reactive/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java index a7b951b930..4dea2a05cf 100644 --- a/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java +++ b/spring-5-reactive/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java @@ -1,5 +1,8 @@ package com.baeldung.functional; +import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.BodyInserters.fromResource; + import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -12,9 +15,6 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.BodyInserters; -import static org.springframework.web.reactive.function.BodyInserters.fromObject; -import static org.springframework.web.reactive.function.BodyInserters.fromResource; - public class FunctionalWebApplicationIntegrationTest { private static WebTestClient client; diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/Spring5ReactiveServerClientIntegrationTest.java similarity index 99% rename from spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java rename to spring-5-reactive/src/test/java/com/baeldung/reactive/Spring5ReactiveServerClientIntegrationTest.java index bbd852d625..8707c27fb3 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/Spring5ReactiveServerClientIntegrationTest.java @@ -1,6 +1,5 @@ -package com.baeldung.jupiter; +package com.baeldung.reactive; -import com.baeldung.web.reactive.Task; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.springframework.http.server.reactive.HttpHandler; @@ -8,6 +7,9 @@ import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; + +import com.baeldung.web.reactive.Task; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.ipc.netty.NettyContext; diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnAnnotatedElementsLiveTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnAnnotatedElementsLiveTest.java new file mode 100644 index 0000000000..0043d62e5a --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnAnnotatedElementsLiveTest.java @@ -0,0 +1,147 @@ +package com.baeldung.reactive.cors; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CorsOnAnnotatedElementsLiveTest { + + private static final String BASE_URL = "http://localhost:8081"; + private static final String BASE_CORS_ON_METHODS_URL = "/cors-on-methods"; + private static final String BASE_CORS_ON_CONTROLLER_URL = "/cors-on-controller"; + private static final String CONTROLLER_CORS_ALLOWED_ORIGIN = "http://allowed-origin.com"; + private static final String CORS_DEFAULT_ORIGIN = "http://default-origin.com"; + + private static WebTestClient client; + + @BeforeAll + public static void setup() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .defaultHeader("Origin", CORS_DEFAULT_ORIGIN) + .build(); + } + + @Test + public void whenRequestingMethodCorsEnabledEndpoint_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.put() + .uri(BASE_CORS_ON_METHODS_URL + "/cors-enabled-endpoint") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", "*"); + } + + @Test + public void whenPreflightMethodCorsEnabled_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.options() + .uri(BASE_CORS_ON_METHODS_URL + "/cors-enabled-endpoint") + .header("Access-Control-Request-Method", "PUT") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", "*"); + response.expectHeader() + .valueEquals("Access-Control-Allow-Methods", "PUT"); + response.expectHeader() + .exists("Access-Control-Max-Age"); + } + + @Test + public void whenRequestingMethodCorsDisabledEndpoint_thenObtainResponseWithoutCorsHeaders() { + ResponseSpec response = client.put() + .uri(BASE_CORS_ON_METHODS_URL + "/cors-disabled-put-endpoint") + .exchange(); + + response.expectHeader() + .doesNotExist("Access-Control-Allow-Origin"); + } + + @Test + public void whenRequestingMethodCorsRestrictiveOrigin_thenObtainForbiddenResponse() { + ResponseSpec response = client.put() + .uri(BASE_CORS_ON_METHODS_URL + "/cors-enabled-origin-restrictive-endpoint") + .exchange(); + + response.expectStatus() + .isForbidden(); + } + + @Test + public void whenPreflightMethodCorsRestrictiveOrigin_thenObtainForbiddenResponse() { + ResponseSpec response = client.options() + .uri(BASE_CORS_ON_METHODS_URL + "/cors-enabled-origin-restrictive-endpoint") + .header("Access-Control-Request-Method", "PUT") + .exchange(); + + response.expectStatus() + .isForbidden(); + } + + @Test + public void whenPreflightMethodCorsRestrictiveHeader_thenObtainResponseWithAllowedHeaders() { + ResponseSpec response = client.options() + .uri(BASE_CORS_ON_METHODS_URL + "/cors-enabled-header-restrictive-endpoint") + .header("Access-Control-Request-Method", "PUT") + .header("Access-Control-Request-Headers", "Baeldung-Not-Allowed, Baeldung-Allowed") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Headers", "Baeldung-Allowed"); + } + + @Test + public void whenPreflightControllerCorsRegularEndpoint_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.options() + .uri(BASE_CORS_ON_CONTROLLER_URL + "/regular-endpoint") + .header("Origin", CONTROLLER_CORS_ALLOWED_ORIGIN) + .header("Access-Control-Request-Method", "PUT") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", CONTROLLER_CORS_ALLOWED_ORIGIN); + } + + @Test + public void whenPreflightControllerCorsRestrictiveOrigin_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.options() + .uri(BASE_CORS_ON_CONTROLLER_URL + "/cors-enabled-origin-restrictive-endpoint") + .header("Origin", CONTROLLER_CORS_ALLOWED_ORIGIN) + .header("Access-Control-Request-Method", "PUT") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", CONTROLLER_CORS_ALLOWED_ORIGIN); + } + + @Test + public void whenPreflightControllerCorsRestrictiveOriginWithAnotherAllowedOrigin_thenObtainResponseWithCorsHeaders() { + final String anotherAllowedOrigin = "http://another-allowed-origin.com"; + ResponseSpec response = client.options() + .uri(BASE_CORS_ON_CONTROLLER_URL + "/cors-enabled-origin-restrictive-endpoint") + .header("Origin", anotherAllowedOrigin) + .header("Access-Control-Request-Method", "PUT") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", anotherAllowedOrigin); + } + + @Test + public void whenPreflightControllerCorsExposingHeaders_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.options() + .uri(BASE_CORS_ON_CONTROLLER_URL + "/cors-enabled-exposed-header-endpoint") + .header("Origin", CONTROLLER_CORS_ALLOWED_ORIGIN) + .header("Access-Control-Request-Method", "PUT") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Expose-Headers", "Baeldung-Exposed"); + } +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnGlobalConfigLiveTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnGlobalConfigLiveTest.java new file mode 100644 index 0000000000..39927af4c3 --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnGlobalConfigLiveTest.java @@ -0,0 +1,99 @@ +package com.baeldung.reactive.cors; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CorsOnGlobalConfigLiveTest { + + private static final String BASE_URL = "http://localhost:8082"; + private static final String BASE_REGULAR_URL = "/cors-on-global-config"; + private static final String BASE_EXTRA_CORS_CONFIG_URL = "/cors-on-global-config-and-more"; + private static final String BASE_FUNCTIONALS_URL = "/global-config-on-functional"; + private static final String CORS_DEFAULT_ORIGIN = "http://allowed-origin.com"; + + private static WebTestClient client; + + @BeforeAll + public static void setup() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .defaultHeader("Origin", CORS_DEFAULT_ORIGIN) + .build(); + } + + @Test + public void whenRequestingRegularEndpoint_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.put() + .uri(BASE_REGULAR_URL + "/regular-put-endpoint") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", CORS_DEFAULT_ORIGIN); + } + + @Test + public void whenRequestingRegularDeleteEndpoint_thenObtainForbiddenResponse() { + ResponseSpec response = client.delete() + .uri(BASE_REGULAR_URL + "/regular-delete-endpoint") + .exchange(); + + response.expectStatus() + .isForbidden(); + } + + @Test + public void whenPreflightAllowedDeleteEndpoint_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.options() + .uri(BASE_EXTRA_CORS_CONFIG_URL + "/further-mixed-config-endpoint") + .header("Access-Control-Request-Method", "DELETE") + .header("Access-Control-Request-Headers", "Baeldung-Not-Allowed, Baeldung-Allowed, Baeldung-Other-Allowed") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", CORS_DEFAULT_ORIGIN); + response.expectHeader() + .valueEquals("Access-Control-Allow-Methods", "PUT,DELETE"); + response.expectHeader() + .valueEquals("Access-Control-Allow-Headers", "Baeldung-Allowed, Baeldung-Other-Allowed"); + response.expectHeader() + .exists("Access-Control-Max-Age"); + } + + @Test + public void whenRequestAllowedDeleteEndpoint_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.delete() + .uri(BASE_EXTRA_CORS_CONFIG_URL + "/further-mixed-config-endpoint") + .exchange(); + + response.expectStatus() + .isOk(); + } + + @Test + public void whenPreflightFunctionalEndpoint_thenObtain404Response() { + ResponseSpec response = client.options() + .uri(BASE_FUNCTIONALS_URL + "/cors-disabled-functional-endpoint") + .header("Access-Control-Request-Method", "PUT") + .exchange(); + + response.expectStatus() + .isNotFound(); + } + + @Test + public void whenRequestFunctionalEndpoint_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.put() + .uri(BASE_FUNCTIONALS_URL + "/cors-disabled-functional-endpoint") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", CORS_DEFAULT_ORIGIN); + } +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnWebFilterLiveTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnWebFilterLiveTest.java new file mode 100644 index 0000000000..e5a3c8a99a --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/cors/CorsOnWebFilterLiveTest.java @@ -0,0 +1,96 @@ +package com.baeldung.reactive.cors; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CorsOnWebFilterLiveTest { + + private static final String BASE_URL = "http://localhost:8083"; + private static final String BASE_REGULAR_URL = "/web-filter-on-annotated"; + private static final String BASE_EXTRA_CORS_CONFIG_URL = "/web-filter-and-more-on-annotated"; + private static final String BASE_FUNCTIONALS_URL = "/web-filter-on-functional"; + private static final String CORS_DEFAULT_ORIGIN = "http://allowed-origin.com"; + + private static WebTestClient client; + + @BeforeAll + public static void setup() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .defaultHeader("Origin", CORS_DEFAULT_ORIGIN) + .build(); + } + + @Test + public void whenRequestingRegularEndpoint_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.put() + .uri(BASE_REGULAR_URL + "/regular-put-endpoint") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", CORS_DEFAULT_ORIGIN); + } + + @Test + public void whenRequestingRegularDeleteEndpoint_thenObtainForbiddenResponse() { + ResponseSpec response = client.delete() + .uri(BASE_REGULAR_URL + "/regular-delete-endpoint") + .exchange(); + + response.expectStatus() + .isForbidden(); + } + + @Test + public void whenPreflightDeleteEndpointWithExtraConfigs_thenObtainForbiddenResponse() { + ResponseSpec response = client.options() + .uri(BASE_EXTRA_CORS_CONFIG_URL + "/further-mixed-config-endpoint") + .header("Access-Control-Request-Method", "DELETE") + .exchange(); + + response.expectStatus() + .isForbidden(); + } + + @Test + public void whenRequestDeleteEndpointWithExtraConfigs_thenObtainForbiddenResponse() { + ResponseSpec response = client.delete() + .uri(BASE_EXTRA_CORS_CONFIG_URL + "/further-mixed-config-endpoint") + .exchange(); + + response.expectStatus() + .isForbidden(); + } + + @Test + public void whenPreflightFunctionalEndpoint_thenObtain404Response() { + ResponseSpec response = client.options() + .uri(BASE_FUNCTIONALS_URL + "/functional-endpoint") + .header("Access-Control-Request-Method", "PUT") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", CORS_DEFAULT_ORIGIN); + response.expectHeader() + .valueEquals("Access-Control-Allow-Methods", "PUT"); + response.expectHeader() + .valueEquals("Access-Control-Max-Age", "8000"); + } + + @Test + public void whenRequestFunctionalEndpoint_thenObtainResponseWithCorsHeaders() { + ResponseSpec response = client.put() + .uri(BASE_FUNCTIONALS_URL + "/functional-endpoint") + .exchange(); + + response.expectHeader() + .valueEquals("Access-Control-Allow-Origin", CORS_DEFAULT_ORIGIN); + } +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java new file mode 100644 index 0000000000..bea2eaa75f --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java @@ -0,0 +1,168 @@ +package com.baeldung.reactive.errorhandling; + +import java.io.IOException; +import static org.junit.Assert.assertEquals; +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) +public class ErrorHandlingIntegrationTest { + + @Autowired + private WebTestClient webTestClient; + + @Test + public void givenErrorReturn_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint1?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + + } + + @Test + public void givenErrorReturn_whenNoUsername_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint1") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Stranger", s); + } + + @Test + public void givenResumeFallback_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint2?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeFallback_whenNoUsername_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint2") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Stranger", s); + + } + + @Test + public void givenResumeDynamicValue_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint3?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeDynamicValue_whenNoUsername_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint3") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hi, I looked around for your name but found: No value present", s); + } + + @Test + public void givenResumeRethrow_whenUsernamePresent_thenOk() throws IOException { + String s = webTestClient.get() + .uri("/api/endpoint4?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenResumeRethrow_whenNoUsername_thenOk() throws IOException { + + webTestClient.get() + .uri("/api/endpoint4") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isBadRequest() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON_UTF8) + .expectBody() + .jsonPath("$.message") + .isNotEmpty() + .jsonPath("$.message") + .isEqualTo("please provide a name"); + } + + @Test + public void givenGlobalErrorHandling_whenUsernamePresent_thenOk() throws IOException { + + String s = webTestClient.get() + .uri("/api/endpoint5?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .returnResult(String.class) + .getResponseBody() + .blockFirst(); + + assertEquals("Hello, Tony", s); + } + + @Test + public void givenGlobalErrorHandling_whenNoUsername_thenOk() throws IOException { + webTestClient.get() + .uri("/api/endpoint5") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus() + .isBadRequest() + .expectHeader() + .contentType(MediaType.APPLICATION_JSON_UTF8) + .expectBody() + .jsonPath("$.message") + .isNotEmpty() + .jsonPath("$.message") + .isEqualTo("please provide a name"); + + } + +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java new file mode 100644 index 0000000000..db563e27d1 --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/responseheaders/ResponseHeaderLiveTest.java @@ -0,0 +1,63 @@ +package com.baeldung.reactive.responseheaders; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ResponseHeaderLiveTest { + + private static final String BASE_URL = "http://localhost:8080"; + private static final String ANNOTATION_BASE_URL = BASE_URL + "/response-header"; + private static final String FUNCTIONAL_BASE_URL = BASE_URL + "/functional-response-header"; + private static final String SERVICE_SINGLE_RESPONSE_HEADER = "Baeldung-Example-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER = "Baeldung-Example-Filter-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER_VALUE = "Value-Filter"; + + private static WebTestClient client; + + @BeforeAll + public static void setup() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .build(); + } + + @Test + public void whenUsingResponseEntityBuilderRequest_thenObtainResponseWithCorrectHeaders() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .build(); + ResponseSpec response = client.get() + .uri(ANNOTATION_BASE_URL + "/response-entity") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-ResponseEntityBuilder") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } + + @Test + public void whenUsingServerHttpResponseRequest_thenObtainResponseWithCorrectHeaders() { + ResponseSpec response = client.get() + .uri(ANNOTATION_BASE_URL + "/server-http-response") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-ServerHttpResponse") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } + + @Test + public void whenUsingFunctionalHandlerRequest_thenObtainResponseWithCorrectHeaders() { + ResponseSpec response = client.get() + .uri(FUNCTIONAL_BASE_URL + "/single-handler") + .exchange(); + + response.expectHeader().valueEquals(SERVICE_SINGLE_RESPONSE_HEADER, "Value-Handler") + .expectHeader().valueEquals(SERVICE_FILTER_RESPONSE_HEADER, SERVICE_FILTER_RESPONSE_HEADER_VALUE); + } +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/serversentsevents/ServiceSentEventLiveTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/serversentsevents/ServiceSentEventLiveTest.java new file mode 100644 index 0000000000..53f4a3b1bb --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/serversentsevents/ServiceSentEventLiveTest.java @@ -0,0 +1,49 @@ +package com.baeldung.reactive.serversentsevents; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient; + +@RunWith(JUnitPlatform.class) +@SpringBootTest +public class ServiceSentEventLiveTest { + + private WebTestClient client = WebTestClient.bindToServer() + .baseUrl("http://localhost:8081/sse-server") + .build(); + + @Test + public void whenSSEEndpointIsCalled_thenEventStreamingBegins() { + + Executable sseStreamingCall = () -> client.get() + .uri("/stream-sse") + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_EVENT_STREAM) + .expectBody(String.class); + + Assertions.assertThrows(IllegalStateException.class, sseStreamingCall, "Expected test to timeout and throw IllegalStateException, but it didn't"); + } + + @Test + public void whenFluxEndpointIsCalled_thenEventStreamingBegins() { + + Executable sseStreamingCall = () -> client.get() + .uri("/stream-flux") + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentTypeCompatibleWith(MediaType.TEXT_EVENT_STREAM) + .expectBody(String.class); + + Assertions.assertThrows(IllegalStateException.class, sseStreamingCall, "Expected test to timeout and throw IllegalStateException, but it didn't"); + } +} diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/urlmatch/ExploreSpring5URLPatternUsingRouterFunctionsIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/urlmatch/ExploreSpring5URLPatternUsingRouterFunctionsIntegrationTest.java index 21ba11616d..91721d2cef 100644 --- a/spring-5-reactive/src/test/java/com/baeldung/reactive/urlmatch/ExploreSpring5URLPatternUsingRouterFunctionsIntegrationTest.java +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/urlmatch/ExploreSpring5URLPatternUsingRouterFunctionsIntegrationTest.java @@ -6,8 +6,6 @@ import org.junit.Test; import org.springframework.boot.web.server.WebServer; import org.springframework.test.web.reactive.server.WebTestClient; -import com.baeldung.reactive.urlmatch.ExploreSpring5URLPatternUsingRouterFunctions; - public class ExploreSpring5URLPatternUsingRouterFunctionsIntegrationTest { private static WebTestClient client; diff --git a/spring-5-reactive/src/test/java/com/baeldung/validations/functional/FunctionalEndpointValidationsLiveTest.java b/spring-5-reactive/src/test/java/com/baeldung/validations/functional/FunctionalEndpointValidationsLiveTest.java new file mode 100644 index 0000000000..5fe764bf8f --- /dev/null +++ b/spring-5-reactive/src/test/java/com/baeldung/validations/functional/FunctionalEndpointValidationsLiveTest.java @@ -0,0 +1,111 @@ +package com.baeldung.validations.functional; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; + +import com.baeldung.validations.functional.model.AnnotatedRequestEntity; +import com.baeldung.validations.functional.model.CustomRequestEntity; + +import reactor.core.publisher.Mono; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class FunctionalEndpointValidationsLiveTest { + + private static final String BASE_URL = "http://localhost:8080"; + private static final String COMPLEX_EP_URL = BASE_URL + "/complex-handler-functional-validation"; + private static final String DRY_EP_URL = BASE_URL + "/dry-functional-validation"; + private static final String ANNOTATIONS_EP_URL = BASE_URL + "/annotated-functional-validation"; + + private static WebTestClient client; + + @BeforeAll + public static void setup() { + client = WebTestClient.bindToServer() + .baseUrl(BASE_URL) + .build(); + } + + @Test + public void whenRequestingDryEPWithInvalidBody_thenObtainBadRequest() { + CustomRequestEntity body = new CustomRequestEntity("name", "123"); + + ResponseSpec response = client.post() + .uri(DRY_EP_URL) + .body(Mono.just(body), CustomRequestEntity.class) + .exchange(); + + response.expectStatus() + .isBadRequest(); + } + + @Test + public void whenRequestingComplexEPWithInvalidBody_thenObtainBadRequest() { + CustomRequestEntity body = new CustomRequestEntity("name", "123"); + + ResponseSpec response = client.post() + .uri(COMPLEX_EP_URL) + .body(Mono.just(body), CustomRequestEntity.class) + .exchange(); + + response.expectStatus() + .isBadRequest(); + } + + @Test + public void whenRequestingAnnotatedEPWithInvalidBody_thenObtainBadRequest() { + AnnotatedRequestEntity body = new AnnotatedRequestEntity("user", "passwordlongerthan7digits"); + + ResponseSpec response = client.post() + .uri(ANNOTATIONS_EP_URL) + .body(Mono.just(body), AnnotatedRequestEntity.class) + .exchange(); + + response.expectStatus() + .isBadRequest(); + } + + @Test + public void whenRequestingDryEPWithValidBody_thenObtainBadRequest() { + CustomRequestEntity body = new CustomRequestEntity("name", "1234567"); + + ResponseSpec response = client.post() + .uri(DRY_EP_URL) + .body(Mono.just(body), CustomRequestEntity.class) + .exchange(); + + response.expectStatus() + .isOk(); + } + + @Test + public void whenRequestingComplexEPWithValidBody_thenObtainBadRequest() { + CustomRequestEntity body = new CustomRequestEntity("name", "1234567"); + + ResponseSpec response = client.post() + .uri(COMPLEX_EP_URL) + .body(Mono.just(body), CustomRequestEntity.class) + .exchange(); + + response.expectStatus() + .isOk(); + } + + @Test + public void whenRequestingAnnotatedEPWithValidBody_thenObtainBadRequest() { + AnnotatedRequestEntity body = new AnnotatedRequestEntity("user", "12345"); + + ResponseSpec response = client.post() + .uri(ANNOTATIONS_EP_URL) + .body(Mono.just(body), AnnotatedRequestEntity.class) + .exchange(); + + response.expectStatus() + .isOk(); + } +} diff --git a/spring-5/src/test/java/com/baeldung/web/client/WebTestClientIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/web/client/WebTestClientIntegrationTest.java similarity index 85% rename from spring-5/src/test/java/com/baeldung/web/client/WebTestClientIntegrationTest.java rename to spring-5-reactive/src/test/java/com/baeldung/web/client/WebTestClientIntegrationTest.java index f9472452ba..08bd883b0b 100644 --- a/spring-5/src/test/java/com/baeldung/web/client/WebTestClientIntegrationTest.java +++ b/spring-5-reactive/src/test/java/com/baeldung/web/client/WebTestClientIntegrationTest.java @@ -1,11 +1,10 @@ package com.baeldung.web.client; -import com.baeldung.Spring5Application; +import com.baeldung.reactive.Spring5ReactiveApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.web.reactive.function.server.RequestPredicates; @@ -16,8 +15,7 @@ import org.springframework.web.server.WebHandler; import reactor.core.publisher.Mono; @RunWith(SpringRunner.class) -@SpringBootTest(classes = Spring5Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@EnableJpaRepositories("com.baeldung.persistence") +@SpringBootTest(classes = Spring5ReactiveApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class WebTestClientIntegrationTest { @LocalServerPort @@ -55,7 +53,7 @@ public class WebTestClientIntegrationTest { .uri("/resource") .exchange() .expectStatus() - .is3xxRedirection() + .isOk() .expectBody(); } diff --git a/spring-5-reactive/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-5-reactive/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ce4c172960 --- /dev/null +++ b/spring-5-reactive/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.reactive.Spring5ReactiveApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Spring5ReactiveApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-5-reactive/src/test/resources/baeldung-weekly.png b/spring-5-reactive/src/test/resources/baeldung-weekly.png new file mode 100644 index 0000000000..a1b7eebcab Binary files /dev/null and b/spring-5-reactive/src/test/resources/baeldung-weekly.png differ diff --git a/spring-5-security/README.md b/spring-5-security/README.md index 94a8f83281..55fa7ab042 100644 --- a/spring-5-security/README.md +++ b/spring-5-security/README.md @@ -4,4 +4,5 @@ - [Extra Login Fields with Spring Security](http://www.baeldung.com/spring-security-extra-login-fields) - [A Custom Spring SecurityConfigurer](http://www.baeldung.com/spring-security-custom-configurer) - [New Password Storage In Spring Security 5](http://www.baeldung.com/spring-security-5-password-storage) - +- [Default Password Encoder in Spring Security 5](https://www.baeldung.com/spring-security-5-default-password-encoder) +- [Extracting Principal and Authorities using Spring Security OAuth](https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor) diff --git a/spring-5-security/pom.xml b/spring-5-security/pom.xml index f6d0ef8b4a..1435019c24 100644 --- a/spring-5-security/pom.xml +++ b/spring-5-security/pom.xml @@ -1,5 +1,5 @@ + 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 spring-5-security @@ -58,6 +58,12 @@ spring-security-test test + + + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + 2.0.1.RELEASE + @@ -70,49 +76,7 @@ JAR - - - org.apache.maven.plugins - maven-surefire-plugin - - 3 - true - methods - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LiveTest.java - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - UTF-8 - UTF-8 - 1.8 - \ No newline at end of file diff --git a/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthApplication.java b/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthApplication.java new file mode 100644 index 0000000000..6ccfd04553 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.inmemory; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class InMemoryAuthApplication { + + public static void main(String[] args) { + SpringApplication.run(InMemoryAuthApplication.class, args); + } + + +} diff --git a/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthController.java b/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthController.java new file mode 100644 index 0000000000..ff7ae9a131 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthController.java @@ -0,0 +1,21 @@ +package com.baeldung.inmemory; + +import java.util.Arrays; +import java.util.List; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class InMemoryAuthController { + + @GetMapping("/public/hello") + public List publicHello() { + return Arrays.asList("Hello", "World", "from", "Public"); + } + + @GetMapping("/private/hello") + public List privateHello() { + return Arrays.asList("Hello", "World", "from", "Private"); + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java b/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java new file mode 100644 index 0000000000..4b32a1126e --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/inmemory/InMemoryAuthWebSecurityConfigurer.java @@ -0,0 +1,34 @@ +package com.baeldung.inmemory; + +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.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; + +@Configuration +public class InMemoryAuthWebSecurityConfigurer extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); + auth.inMemoryAuthentication() + .passwordEncoder(encoder) + .withUser("spring") + .password(encoder.encode("secret")) + .roles("USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/private/**") + .authenticated() + .antMatchers("/public/**") + .permitAll() + .and() + .httpBasic(); + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/oauth2extractors/ExtractorsApplication.java b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/ExtractorsApplication.java new file mode 100644 index 0000000000..6ab4d525bf --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/ExtractorsApplication.java @@ -0,0 +1,29 @@ +package com.baeldung.oauth2extractors; + +import org.apache.logging.log4j.util.Strings; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.core.env.AbstractEnvironment; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@SpringBootApplication +@Controller +public class ExtractorsApplication { + public static void main(String[] args) { + if (Strings.isEmpty(System.getProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME))) { + /*System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, + "oauth2-extractors-baeldung");*/ + System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, + "oauth2-extractors-github"); + } + + SpringApplication.run(ExtractorsApplication.class, args); + } + + @RequestMapping("/") + public String index() { + return "oauth2_extractors"; + } + +} diff --git a/spring-5-security/src/main/java/com/baeldung/oauth2extractors/configuration/SecurityConfig.java b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/configuration/SecurityConfig.java new file mode 100644 index 0000000000..b2ea19c008 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/configuration/SecurityConfig.java @@ -0,0 +1,55 @@ +package com.baeldung.oauth2extractors.configuration; + +import com.baeldung.oauth2extractors.extractor.custom.BaeldungAuthoritiesExtractor; +import com.baeldung.oauth2extractors.extractor.custom.BaeldungPrincipalExtractor; +import com.baeldung.oauth2extractors.extractor.github.GithubAuthoritiesExtractor; +import com.baeldung.oauth2extractors.extractor.github.GithubPrincipalExtractor; +import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; +import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor; +import org.springframework.boot.autoconfigure.security.oauth2.resource.PrincipalExtractor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableOAuth2Sso +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.antMatcher("/**") + .authorizeRequests() + .antMatchers("/login**") + .permitAll() + .anyRequest() + .authenticated() + .and() + .formLogin().disable(); + } + + @Bean + @Profile("oauth2-extractors-baeldung") + public PrincipalExtractor baeldungPrincipalExtractor() { + return new BaeldungPrincipalExtractor(); + } + + @Bean + @Profile("oauth2-extractors-baeldung") + public AuthoritiesExtractor baeldungAuthoritiesExtractor() { + return new BaeldungAuthoritiesExtractor(); + } + + @Bean + @Profile("oauth2-extractors-github") + public PrincipalExtractor githubPrincipalExtractor() { + return new GithubPrincipalExtractor(); + } + + @Bean + @Profile("oauth2-extractors-github") + public AuthoritiesExtractor githubAuthoritiesExtractor() { + return new GithubAuthoritiesExtractor(); + } +} \ No newline at end of file diff --git a/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/custom/BaeldungAuthoritiesExtractor.java b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/custom/BaeldungAuthoritiesExtractor.java new file mode 100644 index 0000000000..275bcd0d31 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/custom/BaeldungAuthoritiesExtractor.java @@ -0,0 +1,29 @@ +package com.baeldung.oauth2extractors.extractor.custom; + +import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class BaeldungAuthoritiesExtractor implements AuthoritiesExtractor { + + @Override + public List extractAuthorities(Map map) { + return AuthorityUtils + .commaSeparatedStringToAuthorityList(asAuthorities(map)); + } + + private String asAuthorities(Map map) { + List authorities = new ArrayList<>(); + authorities.add("BAELDUNG_USER"); + List> authz = (List>) map.get("authorities"); + for (LinkedHashMap entry : authz) { + authorities.add(entry.get("authority")); + } + return String.join(",", authorities); + } +} diff --git a/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/custom/BaeldungPrincipalExtractor.java b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/custom/BaeldungPrincipalExtractor.java new file mode 100644 index 0000000000..6f1b20df10 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/custom/BaeldungPrincipalExtractor.java @@ -0,0 +1,13 @@ +package com.baeldung.oauth2extractors.extractor.custom; + +import org.springframework.boot.autoconfigure.security.oauth2.resource.PrincipalExtractor; + +import java.util.Map; + +public class BaeldungPrincipalExtractor implements PrincipalExtractor { + + @Override + public Object extractPrincipal(Map map) { + return map.get("name"); + } +} diff --git a/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/github/GithubAuthoritiesExtractor.java b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/github/GithubAuthoritiesExtractor.java new file mode 100644 index 0000000000..5d90164f06 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/github/GithubAuthoritiesExtractor.java @@ -0,0 +1,29 @@ +package com.baeldung.oauth2extractors.extractor.github; + +import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class GithubAuthoritiesExtractor implements AuthoritiesExtractor { + private List GITHUB_FREE_AUTHORITIES = AuthorityUtils + .commaSeparatedStringToAuthorityList("GITHUB_USER,GITHUB_USER_FREE"); + private List GITHUB_SUBSCRIBED_AUTHORITIES = AuthorityUtils + .commaSeparatedStringToAuthorityList("GITHUB_USER,GITHUB_USER_SUBSCRIBED"); + + @Override + public List extractAuthorities(Map map) { + if (Objects.nonNull(map.get("plan"))) { + if (!((LinkedHashMap) map.get("plan")) + .get("name") + .equals("free")) { + return GITHUB_SUBSCRIBED_AUTHORITIES; + } + } + return GITHUB_FREE_AUTHORITIES; + } +} diff --git a/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/github/GithubPrincipalExtractor.java b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/github/GithubPrincipalExtractor.java new file mode 100644 index 0000000000..fdc5c0c9f3 --- /dev/null +++ b/spring-5-security/src/main/java/com/baeldung/oauth2extractors/extractor/github/GithubPrincipalExtractor.java @@ -0,0 +1,13 @@ +package com.baeldung.oauth2extractors.extractor.github; + +import org.springframework.boot.autoconfigure.security.oauth2.resource.PrincipalExtractor; + +import java.util.Map; + +public class GithubPrincipalExtractor implements PrincipalExtractor { + + @Override + public Object extractPrincipal(Map map) { + return map.get("login"); + } +} diff --git a/spring-5-security/src/main/resources/application-oauth2-extractors-baeldung.properties b/spring-5-security/src/main/resources/application-oauth2-extractors-baeldung.properties new file mode 100644 index 0000000000..6ef0f5000b --- /dev/null +++ b/spring-5-security/src/main/resources/application-oauth2-extractors-baeldung.properties @@ -0,0 +1,6 @@ +server.port=8082 +security.oauth2.client.client-id=SampleClientId +security.oauth2.client.client-secret=secret +security.oauth2.client.access-token-uri=http://localhost:8081/auth/oauth/token +security.oauth2.client.user-authorization-uri=http://localhost:8081/auth/oauth/authorize +security.oauth2.resource.user-info-uri=http://localhost:8081/auth/user/me \ No newline at end of file diff --git a/spring-5-security/src/main/resources/application-oauth2-extractors-github.properties b/spring-5-security/src/main/resources/application-oauth2-extractors-github.properties new file mode 100644 index 0000000000..8a151dcb98 --- /dev/null +++ b/spring-5-security/src/main/resources/application-oauth2-extractors-github.properties @@ -0,0 +1,7 @@ +server.port=8082 +security.oauth2.client.client-id=89a7c4facbb3434d599d +security.oauth2.client.client-secret=9b3b08e4a340bd20e866787e4645b54f73d74b6a +security.oauth2.client.access-token-uri=https://github.com/login/oauth/access_token +security.oauth2.client.user-authorization-uri=https://github.com/login/oauth/authorize +security.oauth2.client.scope=read:user,user:email +security.oauth2.resource.user-info-uri=https://api.github.com/user \ No newline at end of file diff --git a/spring-5-security/src/main/resources/logback.xml b/spring-5-security/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-5-security/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-5-security/src/main/resources/templates/oauth2_extractors.html b/spring-5-security/src/main/resources/templates/oauth2_extractors.html new file mode 100644 index 0000000000..414dd54a42 --- /dev/null +++ b/spring-5-security/src/main/resources/templates/oauth2_extractors.html @@ -0,0 +1,21 @@ + + + + + Spring Security Principal and Authorities extractor + + + + +
    +
    +

    Secured Page

    + Authenticated username: +
    + Authorities: +
    +
    +
    + + \ No newline at end of file diff --git a/spring-5-security/src/test/java/com/baeldung/inmemory/InMemoryAuthControllerIntegrationTest.java b/spring-5-security/src/test/java/com/baeldung/inmemory/InMemoryAuthControllerIntegrationTest.java new file mode 100644 index 0000000000..9d08cb7cfa --- /dev/null +++ b/spring-5-security/src/test/java/com/baeldung/inmemory/InMemoryAuthControllerIntegrationTest.java @@ -0,0 +1,48 @@ +package com.baeldung.inmemory; + +import static org.junit.Assert.assertEquals; + +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = InMemoryAuthApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +public class InMemoryAuthControllerIntegrationTest { + + @Autowired + private TestRestTemplate template; + + @Test + public void givenRequestOnPublicService_shouldSucceedWith200() throws Exception { + ResponseEntity result = template.getForEntity("/public/hello", String.class); + assertEquals(HttpStatus.OK, result.getStatusCode()); + } + + @Test + public void givenRequestOnPrivateService_shouldFailWith401() throws Exception { + ResponseEntity result = template.getForEntity("/private/hello", String.class); + assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode()); + } + + @Test + public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception { + ResponseEntity result = template.withBasicAuth("spring", "secret") + .getForEntity("/private/hello", String.class); + assertEquals(HttpStatus.OK, result.getStatusCode()); + } + + @Test + public void givenInvalidAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception { + ResponseEntity result = template.withBasicAuth("spring", "wrong") + .getForEntity("/private/hello", String.class); + assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode()); + } + +} diff --git a/spring-5-security/src/test/java/com/baeldung/oauth2extractors/ExtractorsUnitTest.java b/spring-5-security/src/test/java/com/baeldung/oauth2extractors/ExtractorsUnitTest.java new file mode 100644 index 0000000000..491d618291 --- /dev/null +++ b/spring-5-security/src/test/java/com/baeldung/oauth2extractors/ExtractorsUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.oauth2extractors; + +import com.baeldung.oauth2extractors.configuration.SecurityConfig; +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.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import javax.servlet.Filter; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ExtractorsApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = {SecurityConfig.class}) +@ActiveProfiles("oauth2-extractors-github") +public class ExtractorsUnitTest { + + @Autowired + private WebApplicationContext context; + + @Autowired + private Filter springSecurityFilterChain; + + private MockMvc mvc; + + @Before + public void setup() { + mvc = MockMvcBuilders + .webAppContextSetup(context) + .addFilters(springSecurityFilterChain) + .build(); + } + + @Test + public void contextLoads() throws Exception { + } + + @Test + public void givenValidRequestWithoutAuthentication_shouldFailWith302() throws Exception { + mvc + .perform(get("/")) + .andExpect(status().isFound()) + .andReturn(); + } + +} diff --git a/spring-5-security/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-5-security/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..967f67e760 --- /dev/null +++ b/spring-5-security/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.dsl.CustomConfigurerApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = CustomConfigurerApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-5/README.md b/spring-5/README.md index de42d965f5..d3c1decbc7 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -6,14 +6,11 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles - [Concurrent Test Execution in Spring 5](http://www.baeldung.com/spring-5-concurrent-tests) -- [Introduction to the Functional Web Framework in Spring 5](http://www.baeldung.com/spring-5-functional-web) -- [Exploring the Spring 5 MVC URL Matching Improvements](http://www.baeldung.com/spring-5-mvc-url-matching) -- [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient) - [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans) - [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](http://www.baeldung.com/spring-5-junit-config) -- [Spring Security 5 for Reactive Applications](http://www.baeldung.com/spring-security-5-reactive) - [Spring 5 Testing with @EnabledIf Annotation](http://www.baeldung.com/spring-5-enabledIf) - [Introduction to Spring REST Docs](http://www.baeldung.com/spring-rest-docs) -- [Spring Security 5 – OAuth2 Login](http://www.baeldung.com/spring-security-5-oauth2-login) - [Spring ResponseStatusException](http://www.baeldung.com/spring-response-status-exception) - [Spring Assert Statements](http://www.baeldung.com/spring-assert) +- [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari) + diff --git a/spring-5/pom.xml b/spring-5/pom.xml index 6e66fe1e99..293edb5bda 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -1,8 +1,8 @@ - + 4.0.0 - com.baeldung spring-5 0.0.1-SNAPSHOT @@ -34,35 +34,14 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.boot - spring-boot-starter-webflux - org.springframework.boot spring-boot-starter-hateoas - - org.projectreactor - reactor-spring - ${reactor-spring.version} - javax.json.bind javax.json.bind-api - - - - - - - - - - - - org.apache.geronimo.specs geronimo-json_1.1_spec @@ -95,63 +74,32 @@ org.springframework spring-test - - org.springframework.boot - spring-boot-starter-test - test - org.springframework.security spring-security-test test - org.apache.commons commons-collections4 - 4.1 + ${commons-collections4.version} test - org.junit.jupiter junit-jupiter-api - - org.junit.jupiter - junit-jupiter-engine - test - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - test - - - org.junit.platform - junit-platform-runner - ${junit.platform.version} - test - org.springframework.restdocs spring-restdocs-mockmvc test - - org.springframework.restdocs - spring-restdocs-webtestclient - test - org.springframework.restdocs spring-restdocs-restassured test - - @@ -164,22 +112,6 @@ JAR - - - org.apache.maven.plugins - maven-surefire-plugin - - 3 - true - methods - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LiveTest.java - - - org.asciidoctor asciidoctor-maven-plugin @@ -203,20 +135,35 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + methods + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + - UTF-8 - UTF-8 - 1.8 - 1.0.0 - 2.20 - 5.0.2.RELEASE - 1.0.1.RELEASE 1.0 1.5.6 + 4.1 ${project.build.directory}/generated-snippets + 2.21.0 + diff --git a/spring-5/src/main/java/com/baeldung/Spring5Application.java b/spring-5/src/main/java/com/baeldung/Spring5Application.java index f321871646..41b5c1eed1 100644 --- a/spring-5/src/main/java/com/baeldung/Spring5Application.java +++ b/spring-5/src/main/java/com/baeldung/Spring5Application.java @@ -2,10 +2,8 @@ package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; @SpringBootApplication -@ComponentScan(basePackages = { "com.baeldung.web" }) public class Spring5Application { public static void main(String[] args) { diff --git a/spring-5/src/main/java/com/baeldung/config/PersistenceConfig.java b/spring-5/src/main/java/com/baeldung/config/PersistenceConfig.java new file mode 100644 index 0000000000..547685970a --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/config/PersistenceConfig.java @@ -0,0 +1,12 @@ +package com.baeldung.config; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@Configuration +@EnableJpaRepositories("com.baeldung.persistence") +@EntityScan("com.baeldung.web") +public class PersistenceConfig { + +} diff --git a/spring-5/src/main/java/com/baeldung/execption/ActorController.java b/spring-5/src/main/java/com/baeldung/exception/ActorController.java similarity index 97% rename from spring-5/src/main/java/com/baeldung/execption/ActorController.java rename to spring-5/src/main/java/com/baeldung/exception/ActorController.java index 6c9c46253a..17a5b80b64 100644 --- a/spring-5/src/main/java/com/baeldung/execption/ActorController.java +++ b/spring-5/src/main/java/com/baeldung/exception/ActorController.java @@ -1,4 +1,4 @@ -package com.baeldung.execption; +package com.baeldung.exception; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; diff --git a/spring-5/src/main/java/com/baeldung/execption/ActorNotFoundException.java b/spring-5/src/main/java/com/baeldung/exception/ActorNotFoundException.java similarity index 92% rename from spring-5/src/main/java/com/baeldung/execption/ActorNotFoundException.java rename to spring-5/src/main/java/com/baeldung/exception/ActorNotFoundException.java index 642c075b5d..7439be414d 100644 --- a/spring-5/src/main/java/com/baeldung/execption/ActorNotFoundException.java +++ b/spring-5/src/main/java/com/baeldung/exception/ActorNotFoundException.java @@ -1,4 +1,4 @@ -package com.baeldung.execption; +package com.baeldung.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/spring-5/src/main/java/com/baeldung/execption/ActorService.java b/spring-5/src/main/java/com/baeldung/exception/ActorService.java similarity index 97% rename from spring-5/src/main/java/com/baeldung/execption/ActorService.java rename to spring-5/src/main/java/com/baeldung/exception/ActorService.java index 956fa92015..0f173d78d6 100644 --- a/spring-5/src/main/java/com/baeldung/execption/ActorService.java +++ b/spring-5/src/main/java/com/baeldung/exception/ActorService.java @@ -1,4 +1,4 @@ -package com.baeldung.execption; +package com.baeldung.exception; import java.util.Arrays; import java.util.List; diff --git a/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java b/spring-5/src/main/java/com/baeldung/exception/SpringExceptionApplication.java similarity index 92% rename from spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java rename to spring-5/src/main/java/com/baeldung/exception/SpringExceptionApplication.java index 1670da54c3..ed163f7fa7 100644 --- a/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java +++ b/spring-5/src/main/java/com/baeldung/exception/SpringExceptionApplication.java @@ -1,14 +1,14 @@ -package com.baeldung.execption; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; - -@SpringBootApplication(exclude = SecurityAutoConfiguration.class) -@ComponentScan(basePackages = { "com.baeldung.execption" }) -public class SpringExceptionApplication { - public static void main(String[] args) { - SpringApplication.run(SpringExceptionApplication.class, args); - } +package com.baeldung.exception; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication(exclude = SecurityAutoConfiguration.class) +@ComponentScan(basePackages = { "com.baeldung.execption" }) +public class SpringExceptionApplication { + public static void main(String[] args) { + SpringApplication.run(SpringExceptionApplication.class, args); + } } \ No newline at end of file diff --git a/spring-5/src/main/java/com/baeldung/jupiter/Task.java b/spring-5/src/main/java/com/baeldung/jupiter/Task.java new file mode 100644 index 0000000000..2ea977712c --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/jupiter/Task.java @@ -0,0 +1,28 @@ +package com.baeldung.jupiter; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Task { + + private final String name; + + private final int id; + + public Task(@JsonProperty("name") String name, @JsonProperty("id") int id) { + this.name = name; + this.id = id; + } + + public String getName() { + return this.name; + } + + public int getId() { + return this.id; + } + + @Override + public String toString() { + return "Task{" + "name='" + name + '\'' + ", id=" + id + '}'; + } +} diff --git a/spring-5/src/main/java/com/baeldung/jupiter/TestConfig.java b/spring-5/src/main/java/com/baeldung/jupiter/TestConfig.java index a29f77c5df..ee866007ea 100644 --- a/spring-5/src/main/java/com/baeldung/jupiter/TestConfig.java +++ b/spring-5/src/main/java/com/baeldung/jupiter/TestConfig.java @@ -1,6 +1,5 @@ package com.baeldung.jupiter; -import com.baeldung.web.reactive.Task; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; diff --git a/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java b/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java deleted file mode 100644 index a9e44a2eee..0000000000 --- a/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.baeldung.security; - -import org.springframework.context.annotation.Bean; -import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; -import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; -import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.web.server.SecurityWebFilterChain; - -@EnableWebFluxSecurity -@EnableReactiveMethodSecurity -public class SecurityConfig { - - @Bean - public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) { - return http.authorizeExchange() - .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") - .anyExchange().authenticated() - .and().formLogin() - .and().build(); - } - - @Bean - public MapReactiveUserDetailsService userDetailsService() { - UserDetails user = User.withDefaultPasswordEncoder() - .username("user") - .password("password") - .roles("USER") - .build(); - - UserDetails admin = User.withDefaultPasswordEncoder() - .username("admin") - .password("password") - .roles("ADMIN") - .build(); - - return new MapReactiveUserDetailsService(user, admin); - } - -} diff --git a/spring-5/src/main/resources/logback.xml b/spring-5/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-5/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-5/src/test/java/com/baeldung/connectionpool/ApplicationWithHikariConnectionPool.java b/spring-5/src/test/java/com/baeldung/connectionpool/ApplicationWithHikariConnectionPool.java new file mode 100644 index 0000000000..0bd8637681 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/connectionpool/ApplicationWithHikariConnectionPool.java @@ -0,0 +1,12 @@ +package com.baeldung.connectionpool; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ApplicationWithHikariConnectionPool { + + public static void main(String[] args) { + SpringApplication.run(ApplicationWithHikariConnectionPool.class, args); + } +} diff --git a/spring-5/src/test/java/com/baeldung/connectionpool/HikariIntegrationTest.java b/spring-5/src/test/java/com/baeldung/connectionpool/HikariIntegrationTest.java new file mode 100644 index 0000000000..d91cca85ee --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/connectionpool/HikariIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.connectionpool; + +import static org.junit.Assert.*; + +import javax.sql.DataSource; + +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.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class HikariIntegrationTest { + + @Autowired + private DataSource dataSource; + + @Test + public void hikariConnectionPoolIsConfigured() { + assertEquals("com.zaxxer.hikari.HikariDataSource", dataSource.getClass() + .getName()); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/jdbc/autogenkey/GetAutoGenKeyByJDBC.java b/spring-5/src/test/java/com/baeldung/jdbc/autogenkey/GetAutoGenKeyByJDBCIntTest.java similarity index 95% rename from spring-5/src/test/java/com/baeldung/jdbc/autogenkey/GetAutoGenKeyByJDBC.java rename to spring-5/src/test/java/com/baeldung/jdbc/autogenkey/GetAutoGenKeyByJDBCIntTest.java index 45012a95aa..14d2fb736b 100644 --- a/spring-5/src/test/java/com/baeldung/jdbc/autogenkey/GetAutoGenKeyByJDBC.java +++ b/spring-5/src/test/java/com/baeldung/jdbc/autogenkey/GetAutoGenKeyByJDBCIntTest.java @@ -1,55 +1,55 @@ -package com.baeldung.jdbc.autogenkey; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.test.context.junit4.SpringRunner; - -import com.baeldung.jdbc.autogenkey.repository.MessageRepositoryJDBCTemplate; -import com.baeldung.jdbc.autogenkey.repository.MessageRepositorySimpleJDBCInsert; - -@RunWith(SpringRunner.class) -@Ignore -public class GetAutoGenKeyByJDBC { - - @Configuration - @EnableAutoConfiguration - @PropertySource("classpath:autogenkey-db.properties") - @ComponentScan(basePackages = { "com.baeldung.jdbc.autogenkey.repository" }) - public static class SpringConfig { - - } - - @Autowired - MessageRepositorySimpleJDBCInsert messageRepositorySimpleJDBCInsert; - - @Autowired - MessageRepositoryJDBCTemplate messageRepositoryJDBCTemplate; - - final String MESSAGE_CONTENT = "Test"; - - @Test - public void insertJDBC_whenLoadMessageByKey_thenGetTheSameMessage() { - long key = messageRepositoryJDBCTemplate.insert(MESSAGE_CONTENT); - String loadedMessage = messageRepositoryJDBCTemplate.getMessageById(key); - - assertEquals(MESSAGE_CONTENT, loadedMessage); - - } - - @Test - public void insertSimpleInsert_whenLoadMessageKey_thenGetTheSameMessage() { - long key = messageRepositorySimpleJDBCInsert.insert(MESSAGE_CONTENT); - String loadedMessage = messageRepositoryJDBCTemplate.getMessageById(key); - - assertEquals(MESSAGE_CONTENT, loadedMessage); - } - -} +package com.baeldung.jdbc.autogenkey; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.jdbc.autogenkey.repository.MessageRepositoryJDBCTemplate; +import com.baeldung.jdbc.autogenkey.repository.MessageRepositorySimpleJDBCInsert; + +@RunWith(SpringRunner.class) +@Ignore +public class GetAutoGenKeyByJDBCIntTest { + + @Configuration + @EnableAutoConfiguration + @PropertySource("classpath:autogenkey-db.properties") + @ComponentScan(basePackages = { "com.baeldung.jdbc.autogenkey.repository" }) + public static class SpringConfig { + + } + + @Autowired + MessageRepositorySimpleJDBCInsert messageRepositorySimpleJDBCInsert; + + @Autowired + MessageRepositoryJDBCTemplate messageRepositoryJDBCTemplate; + + final String MESSAGE_CONTENT = "Test"; + + @Test + public void insertJDBC_whenLoadMessageByKey_thenGetTheSameMessage() { + long key = messageRepositoryJDBCTemplate.insert(MESSAGE_CONTENT); + String loadedMessage = messageRepositoryJDBCTemplate.getMessageById(key); + + assertEquals(MESSAGE_CONTENT, loadedMessage); + + } + + @Test + public void insertSimpleInsert_whenLoadMessageKey_thenGetTheSameMessage() { + long key = messageRepositorySimpleJDBCInsert.insert(MESSAGE_CONTENT); + String loadedMessage = messageRepositoryJDBCTemplate.getMessageById(key); + + assertEquals(MESSAGE_CONTENT, loadedMessage); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ComposedAnnotationIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ComposedAnnotationIntegrationTest.java index 42d27b90f4..b9bb470cbd 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ComposedAnnotationIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ComposedAnnotationIntegrationTest.java @@ -1,6 +1,5 @@ package com.baeldung.jupiter; -import com.baeldung.web.reactive.Task; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5IntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5IntegrationTest.java index 0f00a85832..484b366132 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5IntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5IntegrationTest.java @@ -1,6 +1,5 @@ package com.baeldung.jupiter; -import com.baeldung.web.reactive.Task; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-5/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-5/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..75b3df4978 --- /dev/null +++ b/spring-5/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.Spring5Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Spring5Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-5/src/test/resources/logback-test.xml b/spring-5/src/test/resources/logback-test.xml index 84f8e4706a..424ab87f79 100644 --- a/spring-5/src/test/resources/logback-test.xml +++ b/spring-5/src/test/resources/logback-test.xml @@ -1,5 +1,15 @@ - - + + + # Pattern of log message for console appender + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-activiti/pom.xml b/spring-activiti/pom.xml index edabb502dd..0a19f483c1 100644 --- a/spring-activiti/pom.xml +++ b/spring-activiti/pom.xml @@ -1,26 +1,24 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.example spring-activiti - 0.0.1-SNAPSHOT jar spring-activiti Demo project for Spring Boot - org.springframework.boot - spring-boot-starter-parent - 1.5.4.RELEASE - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 org.activiti activiti-spring-boot-starter-basic - 6.0.0 + ${activiti.version} org.activiti @@ -44,33 +42,6 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/JdbcTest.java - **/*LiveTest.java - - - - - - - com.example.activitiwithspring.ActivitiWithSpringApplication UTF-8 diff --git a/spring-activiti/src/main/resources/logback.xml b/spring-activiti/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-activiti/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-activiti/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-activiti/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ae37e77f86 --- /dev/null +++ b/spring-activiti/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.example.activitiwithspring.ActivitiWithSpringApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ActivitiWithSpringApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-akka/pom.xml b/spring-akka/pom.xml index d68e8c211b..92b3f1162d 100644 --- a/spring-akka/pom.xml +++ b/spring-akka/pom.xml @@ -1,6 +1,5 @@ - + 4.0.0 com.baeldung spring-akka diff --git a/spring-akka/src/main/resources/logback.xml b/spring-akka/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-akka/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-all/README.md b/spring-all/README.md index 215f9a64d2..ded5e26285 100644 --- a/spring-all/README.md +++ b/spring-all/README.md @@ -29,3 +29,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Quick Guide to the Spring @Order Annotation](http://www.baeldung.com/spring-order) - [Spring Web Contexts](http://www.baeldung.com/spring-web-contexts) - [Spring Cache – Creating a Custom KeyGenerator](http://www.baeldung.com/spring-cache-custom-keygenerator) +- [Spring @Primary Annotation](http://www.baeldung.com/spring-primary) diff --git a/spring-all/pom.xml b/spring-all/pom.xml index 808d9ef585..bab2e431ec 100644 --- a/spring-all/pom.xml +++ b/spring-all/pom.xml @@ -1,5 +1,5 @@ + 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 spring-all @@ -45,6 +45,15 @@ spring-shell ${org.springframework.shell.version} + + org.springframework + spring-websocket + + + org.springframework + spring-messaging + + org.springframework @@ -190,13 +199,28 @@ - + + + dev + + true + + + dev + + + + prod + + prod + + + + org.baeldung.sample.App 5.0.6.RELEASE - 5.0.6.RELEASE - 1.2.2.RELEASE 1.2.0.RELEASE @@ -209,9 +233,7 @@ 3.6.1 6.6.0 - 2.8.2 3.22.0-GA - diff --git a/spring-all/src/main/java/org/baeldung/primary/Config.java b/spring-all/src/main/java/org/baeldung/primary/Config.java new file mode 100644 index 0000000000..b39f2b9db3 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/primary/Config.java @@ -0,0 +1,22 @@ +package org.baeldung.primary; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +@Configuration +@ComponentScan(basePackages="org.baeldung.primary") +public class Config { + + @Bean + public Employee JohnEmployee(){ + return new Employee("John"); + } + + @Bean + @Primary + public Employee TonyEmployee(){ + return new Employee("Tony"); + } +} diff --git a/spring-all/src/main/java/org/baeldung/primary/DepartmentManager.java b/spring-all/src/main/java/org/baeldung/primary/DepartmentManager.java new file mode 100644 index 0000000000..2603951b4e --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/primary/DepartmentManager.java @@ -0,0 +1,11 @@ +package org.baeldung.primary; + +import org.springframework.stereotype.Component; + +@Component +public class DepartmentManager implements Manager { + @Override + public String getManagerName() { + return "Department manager"; + } +} diff --git a/spring-all/src/main/java/org/baeldung/primary/Employee.java b/spring-all/src/main/java/org/baeldung/primary/Employee.java new file mode 100644 index 0000000000..9168387613 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/primary/Employee.java @@ -0,0 +1,20 @@ +package org.baeldung.primary; + +/** + * Created by Gebruiker on 7/17/2018. + */ +public class Employee { + + private String name; + + public Employee(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Employee{" + + "name='" + name + '\'' + + '}'; + } +} diff --git a/spring-all/src/main/java/org/baeldung/primary/GeneralManager.java b/spring-all/src/main/java/org/baeldung/primary/GeneralManager.java new file mode 100644 index 0000000000..0a94f0f96a --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/primary/GeneralManager.java @@ -0,0 +1,14 @@ +package org.baeldung.primary; + +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +@Component +@Primary +public class GeneralManager implements Manager { + + @Override + public String getManagerName() { + return "General manager"; + } +} diff --git a/spring-all/src/main/java/org/baeldung/primary/Manager.java b/spring-all/src/main/java/org/baeldung/primary/Manager.java new file mode 100644 index 0000000000..4666a1babf --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/primary/Manager.java @@ -0,0 +1,8 @@ +package org.baeldung.primary; + +/** + * Created by Gebruiker on 7/19/2018. + */ +public interface Manager { + String getManagerName(); +} diff --git a/spring-all/src/main/java/org/baeldung/primary/ManagerService.java b/spring-all/src/main/java/org/baeldung/primary/ManagerService.java new file mode 100644 index 0000000000..94ea6785c9 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/primary/ManagerService.java @@ -0,0 +1,17 @@ +package org.baeldung.primary; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * Created by Gebruiker on 7/19/2018. + */@Service +public class ManagerService { + + @Autowired + private Manager manager; + + public Manager getManager() { + return manager; + } +} diff --git a/spring-all/src/main/java/org/baeldung/primary/PrimaryApplication.java b/spring-all/src/main/java/org/baeldung/primary/PrimaryApplication.java new file mode 100644 index 0000000000..ffa2a4028d --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/primary/PrimaryApplication.java @@ -0,0 +1,20 @@ +package org.baeldung.primary; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + + +public class PrimaryApplication { + + public static void main(String[] args) { + AnnotationConfigApplicationContext context + = new AnnotationConfigApplicationContext(Config.class); + + Employee employee = context.getBean(Employee.class); + System.out.println(employee); + + ManagerService service = context.getBean(ManagerService.class); + Manager manager = service.getManager(); + System.out.println(manager.getManagerName()); + } + +} diff --git a/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java b/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java index eb5543e3db..2d1905ee9c 100644 --- a/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java +++ b/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java @@ -2,9 +2,11 @@ package org.baeldung.profiles; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; @Configuration @ComponentScan("org.baeldung.profiles") +@PropertySource(value = "classpath:application.properties") public class SpringProfilesConfig { } diff --git a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java index 73df386aff..9257a3aa3a 100644 --- a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java +++ b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java @@ -13,21 +13,36 @@ import org.springframework.web.bind.annotation.RequestMapping; public class ScopesController { public static final Logger LOG = LoggerFactory.getLogger(ScopesController.class); - @Resource(name = "requestMessage") - HelloMessageGenerator requestMessage; + @Resource(name = "requestScopedBean") + HelloMessageGenerator requestScopedBean; - @Resource(name = "sessionMessage") - HelloMessageGenerator sessionMessage; + @Resource(name = "sessionScopedBean") + HelloMessageGenerator sessionScopedBean; - @RequestMapping("/scopes") - public String getScopes(final Model model) { - LOG.info("Request Message:" + requestMessage.getMessage()); - LOG.info("Session Message" + sessionMessage.getMessage()); - requestMessage.setMessage("Good morning!"); - sessionMessage.setMessage("Good afternoon!"); - model.addAttribute("requestMessage", requestMessage.getMessage()); - model.addAttribute("sessionMessage", sessionMessage.getMessage()); + @Resource(name = "applicationScopedBean") + HelloMessageGenerator applicationScopedBean; + + @RequestMapping("/scopes/request") + public String getRequestScopeMessage(final Model model) { + model.addAttribute("previousMessage", requestScopedBean.getMessage()); + requestScopedBean.setMessage("Request Scope Message!"); + model.addAttribute("currentMessage", requestScopedBean.getMessage()); return "scopesExample"; } + @RequestMapping("/scopes/session") + public String getSessionScopeMessage(final Model model) { + model.addAttribute("previousMessage", sessionScopedBean.getMessage()); + sessionScopedBean.setMessage("Session Scope Message!"); + model.addAttribute("currentMessage", sessionScopedBean.getMessage()); + return "scopesExample"; + } + + @RequestMapping("/scopes/application") + public String getApplicationScopeMessage(final Model model) { + model.addAttribute("previousMessage", applicationScopedBean.getMessage()); + applicationScopedBean.setMessage("Application Scope Message!"); + model.addAttribute("currentMessage", applicationScopedBean.getMessage()); + return "scopesExample"; + } } diff --git a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java index fb34725508..b5fe494ee2 100644 --- a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java +++ b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java @@ -27,19 +27,25 @@ public class ScopesConfig { @Bean @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator requestMessage() { + public HelloMessageGenerator requestScopedBean() { return new HelloMessageGenerator(); } @Bean @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator sessionMessage() { + public HelloMessageGenerator sessionScopedBean() { return new HelloMessageGenerator(); } @Bean @Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator globalSessionMessage() { + public HelloMessageGenerator applicationScopedBean() { + return new HelloMessageGenerator(); + } + + @Bean + @Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS) + public HelloMessageGenerator websocketScopedBean() { return new HelloMessageGenerator(); } diff --git a/spring-all/src/main/resources/application.properties b/spring-all/src/main/resources/application.properties new file mode 100644 index 0000000000..cbfe3f2df2 --- /dev/null +++ b/spring-all/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.profiles.active=@spring.profiles.active@ \ No newline at end of file diff --git a/spring-all/src/main/resources/logback.xml b/spring-all/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-all/src/main/resources/logback.xml +++ b/spring-all/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp b/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp index 7974cf0220..0946f1b5ef 100644 --- a/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp +++ b/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp @@ -2,9 +2,9 @@ -

    Bean Scopes Examples

    -
    - Request Message: ${requestMessage }
    - Session Message: ${sessionMessage } +

    Bean Scopes Examples

    +
    Previous Message: ${previousMessage } +
    Current Message: ${currentMessage } +
    \ No newline at end of file diff --git a/spring-all/src/test/java/org/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java b/spring-all/src/test/java/org/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java new file mode 100644 index 0000000000..929d088a14 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java @@ -0,0 +1,22 @@ +package org.baeldung.profiles; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { SpringProfilesConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringProfilesWithMavenPropertiesIntegrationTest { + + @Autowired + DatasourceConfig datasourceConfig; + + @Test + public void testSpringProfiles() { + Assert.assertTrue(datasourceConfig instanceof DevDatasourceConfig); + } +} \ No newline at end of file diff --git a/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsIntegrationTest.java b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsIntegrationTest.java index 986932dafe..fa72ed6d43 100644 --- a/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsIntegrationTest.java +++ b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsIntegrationTest.java @@ -25,7 +25,7 @@ public class CacheRefinementsIntegrationTest extends AbstractJUnit4SpringContext executorService.execute(() -> service.getFoo("test").printInstanceNumber()); } executorService.awaitTermination(1, TimeUnit.SECONDS); - assertEquals(Foo.getInstanceCount(), 1); + assertEquals(1, Foo.getInstanceCount()); } } diff --git a/spring-amqp-simple/pom.xml b/spring-amqp-simple/pom.xml index eb0f25d1a7..3d9ea55cfa 100644 --- a/spring-amqp-simple/pom.xml +++ b/spring-amqp-simple/pom.xml @@ -1,6 +1,6 @@ + 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 spring-amqp-simple diff --git a/spring-amqp-simple/src/main/resources/logback.xml b/spring-amqp-simple/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-amqp-simple/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-amqp-simple/src/test/java/broadcast/BroadcastMessageControllerIntegrationTest.java b/spring-amqp-simple/src/test/java/broadcast/BroadcastMessageControllerIntegrationTest.java deleted file mode 100644 index c3be7f1ede..0000000000 --- a/spring-amqp-simple/src/test/java/broadcast/BroadcastMessageControllerIntegrationTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package broadcast; - -import com.baeldung.springamqpsimple.broadcast.BroadcastConfig; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@ActiveProfiles("test") -@SpringBootTest(webEnvironment = RANDOM_PORT) -public class BroadcastMessageControllerIntegrationTest { - - @Autowired - private TestRestTemplate restTemplate; - - @MockBean - private RabbitTemplate rabbitTemplate; - - @Test - public void whenPostingMessage_thenMessageIsCreated() { - final String message = "Hello World!"; - ResponseEntity responseEntity = restTemplate.postForEntity("/broadcast", message, Void.class); - - assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); - } - - @Test - public void whenPostingMessage_thenMessageIsSentToBroker() { - final String message = "Hello World!"; - restTemplate.postForEntity("/broadcast", message, Void.class); - - verify(rabbitTemplate).convertAndSend(BroadcastConfig.fanoutExchangeName, "", message); - verify(rabbitTemplate).convertAndSend(BroadcastConfig.topicExchangeName, "user.not-important.info", message); - verify(rabbitTemplate).convertAndSend(BroadcastConfig.topicExchangeName, "user.important.error", message); - } -} \ No newline at end of file diff --git a/spring-amqp-simple/src/test/java/com/baeldung/springamqpsimple/MessageControllerIntegrationTest.java b/spring-amqp-simple/src/test/java/com/baeldung/springamqpsimple/MessageControllerIntegrationTest.java deleted file mode 100644 index a053edaa0e..0000000000 --- a/spring-amqp-simple/src/test/java/com/baeldung/springamqpsimple/MessageControllerIntegrationTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.baeldung.springamqpsimple; - - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.verify; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -@RunWith(SpringRunner.class) -@ActiveProfiles("test") -@SpringBootTest(webEnvironment = RANDOM_PORT) -public class MessageControllerIntegrationTest { - - @Autowired - private TestRestTemplate restTemplate; - - @MockBean - private RabbitTemplate rabbitTemplate; - - @Test - public void whenPostingMessage_thenMessageIsCreated() { - final String message = "Hello World!"; - ResponseEntity responseEntity = restTemplate.postForEntity("/messages", message, Void.class); - - assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); - } - - @Test - public void whenPostingMessage_thenMessageIsSentToBroker() { - final String message = "Hello World!"; - restTemplate.postForEntity("/messages", message, Void.class); - - verify(rabbitTemplate).convertAndSend(SpringAmqpConfig.queueName, message); - } -} \ No newline at end of file diff --git a/spring-amqp-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-amqp-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..f134074cf8 --- /dev/null +++ b/spring-amqp-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springamqpsimple.SpringAmqpApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringAmqpApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-amqp/pom.xml b/spring-amqp/pom.xml index a11261084a..e08a4243b3 100755 --- a/spring-amqp/pom.xml +++ b/spring-amqp/pom.xml @@ -1,11 +1,11 @@ + 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 - springamqp + spring-amqp 0.1-SNAPSHOT jar - springamqp + spring-amqp Introduction to Spring-AMQP @@ -18,7 +18,7 @@ org.springframework.amqp spring-rabbit - 1.6.6.RELEASE + ${spring-rabbit} commons-logging @@ -29,11 +29,11 @@ - springamqp + spring-amqp - UTF-8 + 1.6.6.RELEASE diff --git a/spring-amqp/src/main/resources/logback.xml b/spring-amqp/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-amqp/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-aop/pom.xml b/spring-aop/pom.xml index 0f4e08baa3..b9b97eb076 100644 --- a/spring-aop/pom.xml +++ b/spring-aop/pom.xml @@ -1,5 +1,5 @@ + 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 spring-aop diff --git a/spring-aop/src/main/resources/logback.xml b/spring-aop/src/main/resources/logback.xml index 3245e94f08..7c15f603a0 100644 --- a/spring-aop/src/main/resources/logback.xml +++ b/spring-aop/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-aop/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-aop/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..cf1ac7de89 --- /dev/null +++ b/spring-aop/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-apache-camel/pom.xml b/spring-apache-camel/pom.xml index 4c963fc32c..662b3f899c 100644 --- a/spring-apache-camel/pom.xml +++ b/spring-apache-camel/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.apache.camel spring-apache-camel @@ -52,7 +52,6 @@ 2.18.1 4.3.4.RELEASE - 1.8 diff --git a/spring-apache-camel/src/main/resources/logback.xml b/spring-apache-camel/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-apache-camel/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-apache-camel/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-apache-camel/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..efd0603c76 --- /dev/null +++ b/spring-apache-camel/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,13 @@ +package org.baeldung; + +import org.junit.Test; + +import com.baeldung.camel.main.App; + +public class SpringContextIntegrationTest { + + @Test + public final void testMain() throws Exception { + App.main(null); + } +} diff --git a/spring-batch/README.md b/spring-batch/README.md index 754fc5f980..737e7e13f5 100644 --- a/spring-batch/README.md +++ b/spring-batch/README.md @@ -7,3 +7,4 @@ - [Introduction to Spring Batch](http://www.baeldung.com/introduction-to-spring-batch) - [Spring Batch using Partitioner](http://www.baeldung.com/spring-batch-partitioner) - [Spring Batch Tasklets vs Chunks Approach](http://www.baeldung.com/spring-batch-tasklet-chunk) +- [How to Trigger and Stop a Scheduled Spring Batch Job](http://www.baeldung.com/spring-batch-start-stop-job) diff --git a/spring-batch/pom.xml b/spring-batch/pom.xml index d274c046e2..cfd725b2bd 100644 --- a/spring-batch/pom.xml +++ b/spring-batch/pom.xml @@ -1,5 +1,5 @@ + 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 spring-batch @@ -52,15 +52,21 @@ opencsv ${opencsv.version} + + + org.awaitility + awaitility + ${awaitility.version} + test + - - UTF-8 5.0.3.RELEASE 4.0.0.RELEASE 3.15.1 4.1 + 3.1.1 diff --git a/spring-batch/repository.sqlite b/spring-batch/repository.sqlite new file mode 100644 index 0000000000..4456ef63cc Binary files /dev/null and b/spring-batch/repository.sqlite differ diff --git a/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java b/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java new file mode 100644 index 0000000000..1beeb6b2bf --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/batchscheduler/SpringBatchScheduler.java @@ -0,0 +1,172 @@ +package org.baeldung.batchscheduler; + +import java.util.Date; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import org.baeldung.batchscheduler.model.Book; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecution; +import org.springframework.batch.core.JobParametersBuilder; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.support.SimpleJobLauncher; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.file.FlatFileItemReader; +import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder; +import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.ScheduledMethodRunnable; + +@Configuration +@EnableBatchProcessing +@EnableScheduling +public class SpringBatchScheduler { + + private final Logger logger = LoggerFactory.getLogger(SpringBatchScheduler.class); + + private AtomicBoolean enabled = new AtomicBoolean(true); + + private AtomicInteger batchRunCounter = new AtomicInteger(0); + + private final Map> scheduledTasks = new IdentityHashMap<>(); + + @Autowired + private JobBuilderFactory jobBuilderFactory; + + @Autowired + private StepBuilderFactory stepBuilderFactory; + + @Scheduled(fixedRate = 2000) + public void launchJob() throws Exception { + Date date = new Date(); + logger.debug("scheduler starts at " + date); + if (enabled.get()) { + JobExecution jobExecution = jobLauncher().run(job(), new JobParametersBuilder().addDate("launchDate", date) + .toJobParameters()); + batchRunCounter.incrementAndGet(); + logger.debug("Batch job ends with status as " + jobExecution.getStatus()); + } + logger.debug("scheduler ends "); + } + + public void stop() { + enabled.set(false); + } + + public void start() { + enabled.set(true); + } + + @Bean + public TaskScheduler poolScheduler() { + return new CustomTaskScheduler(); + } + + private class CustomTaskScheduler extends ThreadPoolTaskScheduler { + + private static final long serialVersionUID = -7142624085505040603L; + + @Override + public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { + ScheduledFuture future = super.scheduleAtFixedRate(task, period); + + ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task; + scheduledTasks.put(runnable.getTarget(), future); + + return future; + } + + } + + public void cancelFutureSchedulerTasks() { + scheduledTasks.forEach((k, v) -> { + if (k instanceof SpringBatchScheduler) { + v.cancel(false); + } + }); + } + + @Bean + public Job job() { + return jobBuilderFactory.get("job") + .start(readBooks()) + .build(); + } + + @Bean + public JobLauncher jobLauncher() throws Exception { + SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); + jobLauncher.setJobRepository(jobRepository()); + jobLauncher.afterPropertiesSet(); + return jobLauncher; + } + + @Bean + public JobRepository jobRepository() throws Exception { + MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(); + factory.setTransactionManager(new ResourcelessTransactionManager()); + return (JobRepository) factory.getObject(); + } + + @Bean + protected Step readBooks() { + return stepBuilderFactory.get("readBooks") + . chunk(2) + .reader(reader()) + .writer(writer()) + .build(); + } + + @Bean + public FlatFileItemReader reader() { + return new FlatFileItemReaderBuilder().name("bookItemReader") + .resource(new ClassPathResource("books.csv")) + .delimited() + .names(new String[] { "id", "name" }) + .fieldSetMapper(new BeanWrapperFieldSetMapper() { + { + setTargetType(Book.class); + } + }) + .build(); + } + + @Bean + public ItemWriter writer() { + return new ItemWriter() { + + @Override + public void write(List items) throws Exception { + logger.debug("writer..." + items.size()); + for (Book item : items) { + logger.debug(item.toString()); + } + + } + }; + } + + public AtomicInteger getBatchRunCounter() { + return batchRunCounter; + } + +} diff --git a/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java b/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java new file mode 100644 index 0000000000..f992bde20e --- /dev/null +++ b/spring-batch/src/main/java/org/baeldung/batchscheduler/model/Book.java @@ -0,0 +1,35 @@ +package org.baeldung.batchscheduler.model; + +public class Book { + private int id; + private String name; + + public Book() {} + + public Book(int id, String name) { + super(); + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String toString() { + return "Book [id=" + id + ", name=" + name + "]"; + } + +} diff --git a/spring-batch/src/main/resources/books.csv b/spring-batch/src/main/resources/books.csv new file mode 100644 index 0000000000..af68e986a2 --- /dev/null +++ b/spring-batch/src/main/resources/books.csv @@ -0,0 +1,4 @@ +1,SHARP OBJECTS (MOVIE TIE-IN): A NOVEL +2,ARTEMIS: A NOVEL +3,HER PRETTY FACE +4,ALL WE EVER WANTED \ No newline at end of file diff --git a/spring-batch/src/main/resources/logback.xml b/spring-batch/src/main/resources/logback.xml index b110d1c226..91d4292b8e 100644 --- a/spring-batch/src/main/resources/logback.xml +++ b/spring-batch/src/main/resources/logback.xml @@ -3,7 +3,7 @@ - %d{yyyy-MM-dd HH:mm:ss} [%thread] %level %logger{35} - %msg%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n @@ -12,6 +12,10 @@ additivity="false"> + + + + diff --git a/spring-batch/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-batch/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..c3a9f74759 --- /dev/null +++ b/spring-batch/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,12 @@ +package org.baeldung; + +import org.baeldung.batch.App; +import org.junit.Test; + +public class SpringContextIntegrationTest { + + @Test + public final void testMain() throws Exception { + App.main(null); + } +} diff --git a/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java b/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java new file mode 100644 index 0000000000..8927421ac5 --- /dev/null +++ b/spring-batch/src/test/java/org/baeldung/batchscheduler/SpringBatchSchedulerIntegrationTest.java @@ -0,0 +1,60 @@ +package org.baeldung.batchscheduler; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.awaitility.Awaitility.await; +import static java.util.concurrent.TimeUnit.*; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = SpringBatchScheduler.class) +public class SpringBatchSchedulerIntegrationTest { + + @Autowired + private ApplicationContext context; + + @Test + public void stopJobsWhenSchedulerDisabled() throws Exception { + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + .get())); + schedulerBean.stop(); + await().atLeast(3, SECONDS); + + Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + .get()); + } + + @Test + public void stopJobSchedulerWhenSchedulerDestroyed() throws Exception { + ScheduledAnnotationBeanPostProcessor bean = context.getBean(ScheduledAnnotationBeanPostProcessor.class); + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + .get())); + bean.postProcessBeforeDestruction(schedulerBean, "SpringBatchScheduler"); + await().atLeast(3, SECONDS); + + Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + .get()); + } + + @Test + public void stopJobSchedulerWhenFutureTasksCancelled() throws Exception { + SpringBatchScheduler schedulerBean = context.getBean(SpringBatchScheduler.class); + await().untilAsserted(() -> Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + .get())); + schedulerBean.cancelFutureSchedulerTasks(); + await().atLeast(3, SECONDS); + + Assert.assertEquals(2, schedulerBean.getBatchRunCounter() + .get()); + } + + +} diff --git a/spring-bom/pom.xml b/spring-bom/pom.xml index ddecb9dc0d..f974eb2334 100644 --- a/spring-bom/pom.xml +++ b/spring-bom/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung spring-bom @@ -38,7 +37,6 @@ - UTF-8 4.3.8.RELEASE diff --git a/spring-bom/src/main/resources/logback.xml b/spring-bom/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-bom/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-bom/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-bom/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6dee4b808e --- /dev/null +++ b/spring-bom/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,13 @@ +package org.baeldung; + +import org.junit.Test; + +import com.baeldung.spring.bom.HelloWorldApp; + +public class SpringContextIntegrationTest { + + @Test + public final void testMain() throws Exception { + HelloWorldApp.main(null); + } +} diff --git a/spring-boot-admin/pom.xml b/spring-boot-admin/pom.xml index d285a01ec5..58cea728cc 100644 --- a/spring-boot-admin/pom.xml +++ b/spring-boot-admin/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-admin 0.0.1-SNAPSHOT @@ -29,7 +29,6 @@ - UTF-8 1.5.8.RELEASE diff --git a/spring-boot-admin/spring-boot-admin-client/pom.xml b/spring-boot-admin/spring-boot-admin-client/pom.xml index d119450e0b..ea03d6ef6d 100644 --- a/spring-boot-admin/spring-boot-admin-client/pom.xml +++ b/spring-boot-admin/spring-boot-admin-client/pom.xml @@ -1,12 +1,10 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - spring-boot-admin-client 0.0.1-SNAPSHOT jar - spring-boot-admin-client Spring Boot Admin Client @@ -17,13 +15,6 @@ ../../spring-boot-admin - - UTF-8 - UTF-8 - 1.8 - 1.5.4 - - org.springframework.boot @@ -55,6 +46,7 @@ org.springframework.boot spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} @@ -66,5 +58,9 @@ + + 1.5.4 + 2.0.4.RELEASE + diff --git a/spring-boot-admin/spring-boot-admin-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-admin/spring-boot-admin-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..1f1fae17bc --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springbootadminclient.SpringBootAdminClientApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootAdminClientApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/pom.xml b/spring-boot-admin/spring-boot-admin-server/pom.xml index d5c2e19f37..d8e7bb5574 100644 --- a/spring-boot-admin/spring-boot-admin-server/pom.xml +++ b/spring-boot-admin/spring-boot-admin-server/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-admin-server 0.0.1-SNAPSHOT @@ -15,14 +15,6 @@ ../../spring-boot-admin - - UTF-8 - UTF-8 - 1.8 - 1.5.4 - 1.5.4 - - org.springframework.boot @@ -84,9 +76,15 @@ org.springframework.boot spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + 1.5.4 + 1.5.4 + 2.0.4.RELEASE + diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..4c151d97df --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springbootadminserver.SpringBootAdminServerApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootAdminServerApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-angular-ecommerce/README.md b/spring-boot-angular-ecommerce/README.md new file mode 100644 index 0000000000..c6564643e2 --- /dev/null +++ b/spring-boot-angular-ecommerce/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [A Simple E-Commerce Implementation with Spring](https://www.baeldung.com/spring-angular-ecommerce) diff --git a/spring-boot-angular-ecommerce/pom.xml b/spring-boot-angular-ecommerce/pom.xml new file mode 100644 index 0000000000..dc92a91d02 --- /dev/null +++ b/spring-boot-angular-ecommerce/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + spring-boot-angular-ecommerce + 0.0.1-SNAPSHOT + jar + + spring-boot-angular-ecommerce + Spring Boot Angular E-commerce Appliciation + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + ${spring.boot.version} + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.version} + + + org.springframework.boot + spring-boot-devtools + ${spring.boot.version} + runtime + + + com.h2database + h2 + 1.4.197 + runtime + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.9.6 + + + org.springframework.boot + spring-boot-starter-test + ${spring.boot.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + + + + UTF-8 + UTF-8 + 1.8 + 2.0.3.RELEASE + 2.0.4.RELEASE + + diff --git a/spring-boot-angular-ecommerce/src/main/frontend/.editorconfig b/spring-boot-angular-ecommerce/src/main/frontend/.editorconfig new file mode 100644 index 0000000000..9b7352176a --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/spring-boot-angular-ecommerce/src/main/frontend/README.md b/spring-boot-angular-ecommerce/src/main/frontend/README.md new file mode 100644 index 0000000000..4217895796 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/README.md @@ -0,0 +1,27 @@ +# Frontend + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.8. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). diff --git a/spring-boot-angular-ecommerce/src/main/frontend/angular.json b/spring-boot-angular-ecommerce/src/main/frontend/angular.json new file mode 100644 index 0000000000..815c461f30 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/angular.json @@ -0,0 +1,128 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "frontend": { + "root": "", + "sourceRoot": "src", + "projectType": "application", + "prefix": "app", + "schematics": {}, + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/frontend", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.app.json", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "node_modules/bootstrap/dist/css/bootstrap.min.css", + "src/styles.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "frontend:build" + }, + "configurations": { + "production": { + "browserTarget": "frontend:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "frontend:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.spec.json", + "karmaConfig": "src/karma.conf.js", + "styles": [ + "src/styles.css" + ], + "scripts": [], + "assets": [ + "src/favicon.ico", + "src/assets" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "src/tsconfig.app.json", + "src/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "frontend-e2e": { + "root": "e2e/", + "projectType": "application", + "architect": { + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "frontend:serve" + }, + "configurations": { + "production": { + "devServerTarget": "frontend:serve:production" + } + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": "e2e/tsconfig.e2e.json", + "exclude": [ + "**/node_modules/**" + ] + } + } + } + } + }, + "defaultProject": "frontend" +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/e2e/protractor.conf.js b/spring-boot-angular-ecommerce/src/main/frontend/e2e/protractor.conf.js new file mode 100644 index 0000000000..86776a391a --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/e2e/protractor.conf.js @@ -0,0 +1,28 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './src/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + onPrepare() { + require('ts-node').register({ + project: require('path').join(__dirname, './tsconfig.e2e.json') + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; \ No newline at end of file diff --git a/spring-boot-angular-ecommerce/src/main/frontend/e2e/src/app.e2e-spec.ts b/spring-boot-angular-ecommerce/src/main/frontend/e2e/src/app.e2e-spec.ts new file mode 100644 index 0000000000..87525cf2c7 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/e2e/src/app.e2e-spec.ts @@ -0,0 +1,14 @@ +import { AppPage } from './app.po'; + +describe('workspace-project App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + it('should display welcome message', () => { + page.navigateTo(); + expect(page.getParagraphText()).toEqual('Welcome to frontend!'); + }); +}); diff --git a/spring-boot-angular-ecommerce/src/main/frontend/e2e/src/app.po.ts b/spring-boot-angular-ecommerce/src/main/frontend/e2e/src/app.po.ts new file mode 100644 index 0000000000..82ea75ba50 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/e2e/src/app.po.ts @@ -0,0 +1,11 @@ +import { browser, by, element } from 'protractor'; + +export class AppPage { + navigateTo() { + return browser.get('/'); + } + + getParagraphText() { + return element(by.css('app-root h1')).getText(); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/e2e/tsconfig.e2e.json b/spring-boot-angular-ecommerce/src/main/frontend/e2e/tsconfig.e2e.json new file mode 100644 index 0000000000..a6dd622028 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/e2e/tsconfig.e2e.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "module": "commonjs", + "target": "es5", + "types": [ + "jasmine", + "jasminewd2", + "node" + ] + } +} \ No newline at end of file diff --git a/spring-boot-angular-ecommerce/src/main/frontend/package-lock.json b/spring-boot-angular-ecommerce/src/main/frontend/package-lock.json new file mode 100644 index 0000000000..d87b39cad5 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/package-lock.json @@ -0,0 +1,10591 @@ +{ + "name": "frontend", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@angular-devkit/architect": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.6.8.tgz", + "integrity": "sha512-ZKTm/zC61iY9IBHOEAKoMSzZpvhkmv+1O/HHzpHEuR551jCzu6vSyCmMY9Z7GBcccscCV+hjeSMwgFrFRcqlkw==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.6.8", + "rxjs": "^6.0.0" + } + }, + "@angular-devkit/build-angular": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.6.8.tgz", + "integrity": "sha512-VGqYAk8jpISraz2UHfsDre270NOUmV0CTSZw2p9sm5g/XIr5m+IHetFZz3gpoAr9+If2aFTs8Rt3sGdCRzwBqA==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.6.8", + "@angular-devkit/build-optimizer": "0.6.8", + "@angular-devkit/core": "0.6.8", + "@ngtools/webpack": "6.0.8", + "ajv": "~6.4.0", + "autoprefixer": "^8.4.1", + "cache-loader": "^1.2.2", + "chalk": "~2.2.2", + "circular-dependency-plugin": "^5.0.2", + "clean-css": "^4.1.11", + "copy-webpack-plugin": "^4.5.1", + "file-loader": "^1.1.11", + "glob": "^7.0.3", + "html-webpack-plugin": "^3.0.6", + "istanbul": "^0.4.5", + "istanbul-instrumenter-loader": "^3.0.1", + "karma-source-map-support": "^1.2.0", + "less": "^3.0.4", + "less-loader": "^4.1.0", + "license-webpack-plugin": "^1.3.1", + "lodash": "^4.17.4", + "memory-fs": "^0.4.1", + "mini-css-extract-plugin": "~0.4.0", + "minimatch": "^3.0.4", + "node-sass": "^4.9.0", + "opn": "^5.1.0", + "parse5": "^4.0.0", + "portfinder": "^1.0.13", + "postcss": "^6.0.22", + "postcss-import": "^11.1.0", + "postcss-loader": "^2.1.5", + "postcss-url": "^7.3.2", + "raw-loader": "^0.5.1", + "resolve": "^1.5.0", + "rxjs": "^6.0.0", + "sass-loader": "^7.0.1", + "silent-error": "^1.1.0", + "source-map-support": "^0.5.0", + "stats-webpack-plugin": "^0.6.2", + "style-loader": "^0.21.0", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.2", + "tree-kill": "^1.2.0", + "uglifyjs-webpack-plugin": "^1.2.5", + "url-loader": "^1.0.1", + "webpack": "~4.8.1", + "webpack-dev-middleware": "^3.1.3", + "webpack-dev-server": "^3.1.4", + "webpack-merge": "^4.1.2", + "webpack-sources": "^1.1.0", + "webpack-subresource-integrity": "^1.1.0-rc.4" + } + }, + "@angular-devkit/build-optimizer": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.6.8.tgz", + "integrity": "sha512-of5syQbv3uNPp4AQkfRecfnp8AE8kvffbfYi+FFPZ6OGr7e59T1fGwk6+Zgb2qQFQg8HO2tzWI/uygtLIqmbmw==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "source-map": "^0.5.6", + "typescript": "~2.9.1", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "typescript": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", + "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "dev": true + } + } + }, + "@angular-devkit/core": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.6.8.tgz", + "integrity": "sha512-rkIa1OSVWTt4g9leLSK/PsqOj3HZbDKHbZjqlslyfVa3AyCeiumFoOgViOVXlYgPX3HHDbE5uH24nyUWSD8uww==", + "dev": true, + "requires": { + "ajv": "~6.4.0", + "chokidar": "^2.0.3", + "rxjs": "^6.0.0", + "source-map": "^0.5.6" + } + }, + "@angular-devkit/schematics": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.6.8.tgz", + "integrity": "sha512-R4YqAUdo62wtrhX/5HSRGSKXNTWqfQb66ZE6m8jj6GEJNFKdNXMdxOchxr07LCiKTxfh1w6G3nGzxIsu/+D4KA==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.6.8", + "rxjs": "^6.0.0" + } + }, + "@angular/animations": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-6.0.9.tgz", + "integrity": "sha512-UJTHlxVGZLefCDxTS7T0qZxrAIaQ8gGghHwDI7F3QXpXZTsAk4nHiGSt2EvneW5o6io83i6Hpr/9Fde+YvzWNg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/cli": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-6.0.8.tgz", + "integrity": "sha512-DhH1Zq5Yonthw6zh6W07fhf+9XrAZbD1fcQ0MrmbxlieCfLlTAdBqyK2LavFCKwSZkUMLF6UHM3+jiNRVZSSIg==", + "dev": true, + "requires": { + "@angular-devkit/architect": "0.6.8", + "@angular-devkit/core": "0.6.8", + "@angular-devkit/schematics": "0.6.8", + "@schematics/angular": "0.6.8", + "@schematics/update": "0.6.8", + "opn": "~5.3.0", + "resolve": "^1.1.7", + "rxjs": "^6.0.0", + "semver": "^5.1.0", + "silent-error": "^1.0.0", + "symbol-observable": "^1.2.0", + "yargs-parser": "^10.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "@angular/common": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-6.0.9.tgz", + "integrity": "sha512-zjJ9WDW9787sTRiNeUvQaCvGZJu1dI8A3fYtSL8BKrGhxLsf24cSa3ljbrSmtIsCGImNxTToHzPFXo4sx2dvYg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/compiler": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-6.0.9.tgz", + "integrity": "sha512-/A6U/W0settfkh3tmX9p3t7+OyZ0c2sIJMlQjhfF36do0ylnIl4wuqJtHF0BWr/wmmbQzg+qAsQyWrx8vp+2Iw==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/compiler-cli": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-6.0.9.tgz", + "integrity": "sha512-v3C5RyJLKoDcQocDt/U195t9v8UpBH+mwVaBkEM+nLkZAGC1Uvg9nPuUXisOwljuMm9VtOWG3A8hKQ5ZYieNBg==", + "dev": true, + "requires": { + "chokidar": "^1.4.2", + "minimist": "^1.2.0", + "reflect-metadata": "^0.1.2", + "tsickle": "^0.29.0" + }, + "dependencies": { + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "@angular/core": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-6.0.9.tgz", + "integrity": "sha512-NeEUgymsR/tLvWeEAA4mGEX/S4hHbIo/2uwPGGAQAvzlk+pL7xqPoFSMKeqQahdTnWSmYa/2+X33OdJgXKKXyg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/forms": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-6.0.9.tgz", + "integrity": "sha512-hZxzoO/QAd9EetNUdGpb5Wiw4Lb7R+iOCjdV8sh+C8q6Ow5G35/dfiAlNanGXVqSi8e6Qqm1aO/r4cTUWFm6vw==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/http": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/http/-/http-6.0.9.tgz", + "integrity": "sha512-JaYvBQQ+hJ7SKqZ+zw4C20lc7b6U5kK50nSkams10tzhITke6L/+wK8g3kiNu4XcqE5nqcIN8S95UkMGPMsa7Q==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/language-service": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-6.0.9.tgz", + "integrity": "sha512-a9/Ee1DfRlj4duhDW17xl+52mO6zKlBLm3JOIyANrmJqoHCf/Nfvw3OmEhjMJ1A8O6xLCXyPF/Fq0WD9BfVSrg==", + "dev": true + }, + "@angular/platform-browser": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-6.0.9.tgz", + "integrity": "sha512-q/1UGlbWBwZ6c63p8SDmBsgjYgMQUxyByY9GGt0hd5XhOfVFzvBSzybKSRc3FBhmxQJMCtVhEbI0kIzqrDxcWg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/platform-browser-dynamic": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-6.0.9.tgz", + "integrity": "sha512-HsmLafy0hpMIZlwHz1XRicXczZWCKb0H6oCY+TepFV4u3SLZgJEO7/HZrhO0kEviipXuXrgZSpafV3IYP6eWPQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@angular/router": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-6.0.9.tgz", + "integrity": "sha512-kS489FFpGWD4GEDDozfVb+eD5qf1E9cLYgsE7RO914uNMh/sJuRZt9PVu0bcX12fOOO7mTcOiWtlkefzUAJbkA==", + "requires": { + "tslib": "^1.9.0" + } + }, + "@ngtools/webpack": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-6.0.8.tgz", + "integrity": "sha512-jorGpTd82ILbyUwg4JQekovHFaYwSMlZan4f7x+sd3+2WgyL3Z1+ZbVSGKvXZWKS/mAVx7eLkRikzJkuC4FgHw==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.6.8", + "tree-kill": "^1.0.0", + "webpack-sources": "^1.1.0" + } + }, + "@schematics/angular": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.6.8.tgz", + "integrity": "sha512-9kRphqTYG5Df/I8fvnT1zMsw0YNDPO9tl18tQZXj4am4raT7l9UCr+WkwJdlBoA5pwG6baWE9sL0iGWV/bzF/g==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.6.8", + "@angular-devkit/schematics": "0.6.8", + "typescript": ">=2.6.2 <2.8" + } + }, + "@schematics/update": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.6.8.tgz", + "integrity": "sha512-1Uq7LYnwL2wBwGVCgNz76QAR13ghAk+2vDDHOi+VX5+usHManxydrpoMGeX66OBPd+y5D3D2MFb+8mYHE7mygg==", + "dev": true, + "requires": { + "@angular-devkit/core": "0.6.8", + "@angular-devkit/schematics": "0.6.8", + "npm-registry-client": "^8.5.1", + "rxjs": "^6.0.0", + "semver": "^5.3.0", + "semver-intersect": "^1.1.2" + } + }, + "@types/jasmine": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.8.tgz", + "integrity": "sha512-OJSUxLaxXsjjhob2DBzqzgrkLmukM3+JMpRp0r0E4HTdT1nwDCWhaswjYxazPij6uOdzHCJfNbDjmQ1/rnNbCg==", + "dev": true + }, + "@types/jasminewd2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.3.tgz", + "integrity": "sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==", + "dev": true, + "requires": { + "@types/jasmine": "*" + } + }, + "@types/node": { + "version": "8.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.9.5.tgz", + "integrity": "sha512-jRHfWsvyMtXdbhnz5CVHxaBgnV6duZnPlQuRSo/dm/GnmikNcmZhxIES4E9OZjUmQ8C+HCl4KJux+cXN/ErGDQ==", + "dev": true + }, + "@types/q": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", + "dev": true + }, + "@types/selenium-webdriver": { + "version": "2.53.43", + "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz", + "integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.4.3.tgz", + "integrity": "sha512-S6npYhPcTHDYe9nlsKa9CyWByFi8Vj8HovcAgtmMAQZUOczOZbQ8CnwMYKYC5HEZzxEE+oY0jfQk4cVlI3J59Q==", + "dev": true, + "requires": { + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "debug": "^3.1.0", + "webassemblyjs": "1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.4.3.tgz", + "integrity": "sha512-3zTkSFswwZOPNHnzkP9ONq4bjJSeKVMcuahGXubrlLmZP8fmTIJ58dW7h/zOVWiFSuG2em3/HH3BlCN7wyu9Rw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.4.3.tgz", + "integrity": "sha512-e8+KZHh+RV8MUvoSRtuT1sFXskFnWG9vbDy47Oa166xX+l0dD5sERJ21g5/tcH8Yo95e9IN3u7Jc3NbhnUcSkw==", + "dev": true, + "requires": { + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.4.3.tgz", + "integrity": "sha512-9FgHEtNsZQYaKrGCtsjswBil48Qp1agrzRcPzCbQloCoaTbOXLJ9IRmqT+uEZbenpULLRNFugz3I4uw18hJM8w==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.4.3" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.4.3.tgz", + "integrity": "sha512-JINY76U+702IRf7ePukOt037RwmtH59JHvcdWbTTyHi18ixmQ+uOuNhcdCcQHTquDAH35/QgFlp3Y9KqtyJsCQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.4.3.tgz", + "integrity": "sha512-I7bS+HaO0K07Io89qhJv+z1QipTpuramGwUSDkwEaficbSvCcL92CUZEtgykfNtk5wb0CoLQwWlmXTwGbNZUeQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.4.3.tgz", + "integrity": "sha512-p0yeeO/h2r30PyjnJX9xXSR6EDcvJd/jC6xa/Pxg4lpfcNi7JUswOpqDToZQ55HMMVhXDih/yqkaywHWGLxqyQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/leb128": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.4.3.tgz", + "integrity": "sha512-4u0LJLSPzuRDWHwdqsrThYn+WqMFVqbI2ltNrHvZZkzFPO8XOZ0HFQ5eVc4jY/TNHgXcnwrHjONhPGYuuf//KQ==", + "dev": true, + "requires": { + "leb": "^0.3.0" + } + }, + "@webassemblyjs/validation": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/validation/-/validation-1.4.3.tgz", + "integrity": "sha512-R+rRMKfhd9mq0rj2mhU9A9NKI2l/Rw65vIYzz4lui7eTKPcCu1l7iZNi4b9Gen8D42Sqh/KGiaQNk/x5Tn/iBQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3" + } + }, + "@webassemblyjs/wasm-edit": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.4.3.tgz", + "integrity": "sha512-qzuwUn771PV6/LilqkXcS0ozJYAeY/OKbXIWU3a8gexuqb6De2p4ya/baBeH5JQ2WJdfhWhSvSbu86Vienttpw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/helper-wasm-section": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "@webassemblyjs/wasm-opt": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "@webassemblyjs/wast-printer": "1.4.3", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.4.3.tgz", + "integrity": "sha512-eR394T8dHZfpLJ7U/Z5pFSvxl1L63JdREebpv9gYc55zLhzzdJPAuxjBYT4XqevUdW67qU2s0nNA3kBuNJHbaQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/leb128": "1.4.3" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.4.3.tgz", + "integrity": "sha512-7Gp+nschuKiDuAL1xmp4Xz0rgEbxioFXw4nCFYEmy+ytynhBnTeGc9W9cB1XRu1w8pqRU2lbj2VBBA4cL5Z2Kw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.4.3.tgz", + "integrity": "sha512-KXBjtlwA3BVukR/yWHC9GF+SCzBcgj0a7lm92kTOaa4cbjaTaa47bCjXw6cX4SGQpkncB9PU2hHGYVyyI7wFRg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/leb128": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "webassemblyjs": "1.4.3" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.4.3.tgz", + "integrity": "sha512-QhCsQzqV0CpsEkRYyTzQDilCNUZ+5j92f+g35bHHNqS22FppNTywNFfHPq8ZWZfYCgbectc+PoghD+xfzVFh1Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/floating-point-hex-parser": "1.4.3", + "@webassemblyjs/helper-code-frame": "1.4.3", + "@webassemblyjs/helper-fsm": "1.4.3", + "long": "^3.2.0", + "webassemblyjs": "1.4.3" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.4.3.tgz", + "integrity": "sha512-EgXk4anf8jKmuZJsqD8qy5bz2frEQhBvZruv+bqwNoLWUItjNSFygk8ywL3JTEz9KtxTlAmqTXNrdD1d9gNDtg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "long": "^3.2.0" + } + }, + "@webpack-contrib/schema-utils": { + "version": "1.0.0-beta.0", + "resolved": "https://registry.npmjs.org/@webpack-contrib/schema-utils/-/schema-utils-1.0.0-beta.0.tgz", + "integrity": "sha512-LonryJP+FxQQHsjGBi6W786TQB1Oym+agTpY0c+Kj8alnIw+DLUJb6SI8Y1GHGhLCH1yPRrucjObUmxNICQ1pg==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chalk": "^2.3.2", + "strip-ansi": "^4.0.0", + "text-table": "^0.2.0", + "webpack-log": "^1.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "dev": true, + "requires": { + "acorn": "^5.0.0" + } + }, + "adm-zip": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz", + "integrity": "sha1-ph7VrmkFw66lizplfSUDMJEFJzY=", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ajv": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz", + "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=", + "dev": true, + "requires": { + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0", + "uri-js": "^3.0.2" + } + }, + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "app-root-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.1.0.tgz", + "integrity": "sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo=", + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", + "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", + "dev": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", + "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true, + "optional": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", + "dev": true + }, + "autoprefixer": { + "version": "8.6.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz", + "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==", + "dev": true, + "requires": { + "browserslist": "^3.2.8", + "caniuse-lite": "^1.0.30000864", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.23", + "postcss-value-parser": "^3.2.3" + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "dev": true + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "optional": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "blocking-proxy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", + "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "http-errors": "~1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "~2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + }, + "dependencies": { + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.x.x" + } + }, + "bootstrap": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.2.tgz", + "integrity": "sha512-3bP609EdMc/8EwgGp8KgpN8HwnR4V4lZ9CTi5pImMrXNxpkw7dK1B05aMwQWpG1ZWmTLlBSN/uzkuz5GsmQNFA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cacache": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", + "dev": true, + "requires": { + "bluebird": "^3.5.1", + "chownr": "^1.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.1", + "mississippi": "^2.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^5.2.4", + "unique-filename": "^1.1.0", + "y18n": "^4.0.0" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cache-loader": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-1.2.2.tgz", + "integrity": "sha512-rsGh4SIYyB9glU+d0OcHwiXHXBoUgDhHZaQ1KAbiXqfz1CDPxtTboh1gPbJ0q2qdO8a9lfcjgC5CJ2Ms32y5bw==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "mkdirp": "^0.5.1", + "neo-async": "^2.5.0", + "schema-utils": "^0.4.2" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "optional": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "caniuse-lite": { + "version": "1.0.30000865", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000865.tgz", + "integrity": "sha512-vs79o1mOSKRGv/1pSkp4EXgl4ZviWeYReXw60XfacPU64uQWZwJT6vZNmxRF9O+6zu71sJwMxLK5JXxbzuVrLw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "optional": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", + "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", + "dev": true, + "requires": { + "ansi-styles": "^3.1.0", + "escape-string-regexp": "^1.0.5", + "supports-color": "^4.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + } + } + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + } + }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "dev": true + }, + "chrome-trace-event": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz", + "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-dependency-plugin": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.0.2.tgz", + "integrity": "sha512-oC7/DVAyfcY3UWKm0sN/oVoDedQDQiw/vIiAnuTWTpE5s0zWf7l3WY417Xw/Fbi/QbAjctAkxgMiS9P0s3zkmA==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-css": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz", + "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=", + "dev": true, + "requires": { + "source-map": "0.5.x" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "optional": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + } + } + }, + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "clone-deep": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", + "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.0", + "shallow-clone": "^1.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "codelyzer": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.2.1.tgz", + "integrity": "sha512-CKwfgpfkqi9dyzy4s6ELaxJ54QgJ6A8iTSsM4bzHbLuTpbKncvNc3DUlCvpnkHBhK47gEf4qFsWoYqLrJPhy6g==", + "dev": true, + "requires": { + "app-root-path": "^2.0.1", + "css-selector-tokenizer": "^0.7.0", + "cssauron": "^1.4.0", + "semver-dsl": "^1.0.1", + "source-map": "^0.5.6", + "sprintf-js": "^1.0.3" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "dev": true, + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combine-lists": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", + "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", + "dev": true, + "requires": { + "lodash": "^4.5.0" + } + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", + "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "compare-versions": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.3.0.tgz", + "integrity": "sha512-MAAAIOdi2s4Gl6rZ76PNcUa9IOYB+5ICdT41o5uMRf09aEu/F9RK+qhe8RjXNPwcTjGV7KU7h2P/fljThFVqyQ==", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "compressible": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.14.tgz", + "integrity": "sha1-MmxfUH+7BV9UEWeCuWmoG2einac=", + "dev": true, + "requires": { + "mime-db": ">= 1.34.0 < 2" + } + }, + "compression": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", + "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.14", + "debug": "2.6.9", + "on-headers": "~1.0.1", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" + }, + "dependencies": { + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + } + } + }, + "connect-history-api-fallback": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", + "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-webpack-plugin": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.2.tgz", + "integrity": "sha512-zmC33E8FFSq3AbflTvqvPvBo621H36Afsxlui91d+QyZxPIuXghfnTsa1CuqiAaCPgJoSUWfTFbKJnadZpKEbQ==", + "dev": true, + "requires": { + "cacache": "^10.0.4", + "find-cache-dir": "^1.0.0", + "globby": "^7.1.1", + "is-glob": "^4.0.0", + "loader-utils": "^1.1.0", + "minimatch": "^3.0.4", + "p-limit": "^1.0.0", + "serialize-javascript": "^1.4.0" + } + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "dev": true, + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0", + "require-from-string": "^2.0.1" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "optional": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "optional": true, + "requires": { + "boom": "2.x.x" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css-parse": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", + "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", + "dev": true + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "dev": true, + "requires": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" + } + }, + "css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", + "dev": true + }, + "cssauron": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", + "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", + "dev": true, + "requires": { + "through": "X.X.X" + } + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true + }, + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "dev": true + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "detect-node": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz", + "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=", + "dev": true + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "path-type": "^3.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "dom-converter": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", + "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", + "dev": true, + "requires": { + "utila": "~0.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", + "dev": true + } + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", + "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "ejs": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz", + "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.52", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.52.tgz", + "integrity": "sha1-0tnxJwuko7lnuDHEDvcftNmrXOA=", + "dev": true + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", + "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", + "dev": true, + "requires": { + "accepts": "1.3.3", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "2.3.3", + "engine.io-parser": "1.3.2", + "ws": "1.1.2" + }, + "dependencies": { + "accepts": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", + "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "dev": true, + "requires": { + "mime-types": "~2.1.11", + "negotiator": "0.6.1" + } + }, + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "engine.io-client": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", + "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "2.3.3", + "engine.io-parser": "1.3.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parsejson": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "1.1.2", + "xmlhttprequest-ssl": "1.5.3", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "engine.io-parser": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", + "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "0.0.6", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary": "0.1.7", + "wtf-8": "1.0.0" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + }, + "dependencies": { + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + } + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + }, + "dependencies": { + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + } + } + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "eventsource": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", + "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", + "dev": true, + "requires": { + "original": ">=0.0.5" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-braces": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", + "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", + "dev": true, + "requires": { + "array-slice": "^0.2.3", + "array-unique": "^0.2.1", + "braces": "^0.1.2" + }, + "dependencies": { + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", + "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", + "dev": true, + "requires": { + "expand-range": "^0.1.0" + } + }, + "expand-range": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", + "dev": true, + "requires": { + "is-number": "^0.1.1", + "repeat-string": "^0.2.2" + } + }, + "is-number": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", + "dev": true + }, + "repeat-string": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", + "dev": true + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "^2.1.0" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "express": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.3", + "qs": "6.5.1", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastparse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "file-loader": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", + "dev": true, + "requires": { + "loader-utils": "^1.0.2", + "schema-utils": "^0.4.5" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + } + }, + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flush-write-stream": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", + "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, + "follow-redirects": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.1.tgz", + "integrity": "sha512-v9GI1hpaqq1ZZR6pBD1+kI7O24PhDvNGNodjS3MdcEqyrahCp8zbtpv+2B/krUnSmUH80lbAS7MrdeK5IylgKg==", + "dev": true, + "requires": { + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "optional": true, + "requires": { + "globule": "^1.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "globule": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", + "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", + "dev": true, + "optional": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "handle-thing": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", + "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", + "dev": true + }, + "handlebars": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "dev": true, + "requires": { + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "optional": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "optional": true + } + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", + "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", + "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "optional": true, + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true + }, + "html-minifier": { + "version": "3.5.19", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.19.tgz", + "integrity": "sha512-Qr2JC9nsjK8oCrEmuB430ZIA8YWbF3D5LSjywD75FTuXmeqacwHgIM8wp3vHYzzPbklSjp53RdmDuzR4ub2HzA==", + "dev": true, + "requires": { + "camel-case": "3.0.x", + "clean-css": "4.1.x", + "commander": "2.16.x", + "he": "1.1.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + } + }, + "html-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", + "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", + "dev": true, + "requires": { + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" + }, + "dependencies": { + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + } + } + }, + "htmlparser2": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", + "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", + "dev": true, + "requires": { + "domelementtype": "1", + "domhandler": "2.1", + "domutils": "1.1", + "readable-stream": "1.0" + }, + "dependencies": { + "domutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", + "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-parser-js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz", + "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", + "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", + "dev": true, + "requires": { + "http-proxy": "^1.16.2", + "is-glob": "^4.0.0", + "lodash": "^4.17.5", + "micromatch": "^3.1.9" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "dev": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "requires": { + "import-from": "^2.1.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "import-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", + "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "dev": true, + "requires": { + "pkg-dir": "^2.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "dev": true, + "optional": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "internal-ip": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", + "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=", + "dev": true, + "requires": { + "meow": "^3.3.0" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ipaddr.js": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", + "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isbinaryfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", + "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "istanbul-api": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz", + "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==", + "dev": true, + "requires": { + "async": "^2.1.4", + "compare-versions": "^3.1.0", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-hook": "^1.2.0", + "istanbul-lib-instrument": "^1.10.1", + "istanbul-lib-report": "^1.1.4", + "istanbul-lib-source-maps": "^1.2.4", + "istanbul-reports": "^1.3.0", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + } + } + }, + "istanbul-instrumenter-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz", + "integrity": "sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w==", + "dev": true, + "requires": { + "convert-source-map": "^1.5.0", + "istanbul-lib-instrument": "^1.7.3", + "loader-utils": "^1.1.0", + "schema-utils": "^0.3.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "requires": { + "ajv": "^5.0.0" + } + } + } + }, + "istanbul-lib-coverage": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", + "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.1.tgz", + "integrity": "sha512-eLAMkPG9FU0v5L02lIkcj/2/Zlz9OuluaXikdr5iStk8FDbSwAixTK9TkYxbF0eNnzAJTwM2fkV2A1tpsIp4Jg==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz", + "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==", + "dev": true, + "requires": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.0", + "semver": "^5.3.0" + } + }, + "istanbul-lib-report": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz", + "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^1.2.0", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz", + "integrity": "sha512-8O2T/3VhrQHn0XcJbP1/GN7kXMiRAlPi+fj3uEHrjBD8Oz7Py0prSC25C09NuAZS6bgW1NNKAvCSHZXB0irSGA==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.0", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "istanbul-reports": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz", + "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==", + "dev": true, + "requires": { + "handlebars": "^4.0.3" + } + }, + "jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "dev": true, + "requires": { + "exit": "^0.1.2", + "glob": "^7.0.6", + "jasmine-core": "~2.8.0" + }, + "dependencies": { + "jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", + "dev": true + } + } + }, + "jasmine-core": { + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", + "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=", + "dev": true + }, + "jasmine-spec-reporter": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", + "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==", + "dev": true, + "requires": { + "colors": "1.1.2" + } + }, + "jasminewd2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", + "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", + "dev": true + }, + "js-base64": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.8.tgz", + "integrity": "sha512-hm2nYpDrwoO/OzBhdcqs/XGT6XjSuSSCVEpia+Kl2J6x4CYt5hISlVL/AYU1khoDXv0AQVgxtdJySb9gjAn56Q==", + "dev": true, + "optional": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "optional": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jszip": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", + "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", + "dev": true, + "requires": { + "core-js": "~2.3.0", + "es6-promise": "~3.0.2", + "lie": "~3.1.0", + "pako": "~1.0.2", + "readable-stream": "~2.0.6" + }, + "dependencies": { + "core-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", + "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=", + "dev": true + }, + "es6-promise": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", + "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "karma": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz", + "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==", + "dev": true, + "requires": { + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "chokidar": "^1.4.1", + "colors": "^1.1.0", + "combine-lists": "^1.0.0", + "connect": "^3.6.0", + "core-js": "^2.2.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "expand-braces": "^0.1.1", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^3.8.0", + "log4js": "^0.6.31", + "mime": "^1.3.4", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", + "socket.io": "1.7.3", + "source-map": "^0.5.3", + "tmp": "0.0.31", + "useragent": "^2.1.12" + }, + "dependencies": { + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + } + } + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "^1.0.0", + "which": "^1.2.1" + } + }, + "karma-coverage-istanbul-reporter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.0.1.tgz", + "integrity": "sha512-UcgrHkFehI5+ivMouD8NH/UOHiX4oCAtwaANylzPFdcAuD52fnCUuelacq2gh8tZ4ydhU3+xiXofSq7j5Ehygw==", + "dev": true, + "requires": { + "istanbul-api": "^1.3.1", + "minimatch": "^3.0.4" + } + }, + "karma-jasmine": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.2.tgz", + "integrity": "sha1-OU8rJf+0pkS5rabyLUQ+L9CIhsM=", + "dev": true + }, + "karma-jasmine-html-reporter": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", + "integrity": "sha1-SKjl7xiAdhfuK14zwRlMNbQ5Ukw=", + "dev": true, + "requires": { + "karma-jasmine": "^1.0.2" + } + }, + "karma-source-map-support": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.3.0.tgz", + "integrity": "sha512-HcPqdAusNez/ywa+biN4EphGz62MmQyPggUsDfsHqa7tSe4jdsxgvTKuDfIazjL+IOxpVWyT7Pr4dhAV+sxX5Q==", + "dev": true, + "requires": { + "source-map-support": "^0.5.5" + } + }, + "killable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz", + "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leb": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/leb/-/leb-0.3.0.tgz", + "integrity": "sha1-Mr7p+tFoMo1q6oUi2DP0GA7tHaM=", + "dev": true + }, + "less": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/less/-/less-3.7.1.tgz", + "integrity": "sha512-Cmf5XJlzNklkBC8eAa+Ef16AHUBAkApHNAw3x9Vmn84h2BvGrri5Id7kf6H1n6SN74Fc0WdHIRPlFMxsl0eJkA==", + "dev": true, + "requires": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "mime": "^1.4.1", + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "^2.83.0", + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } + } + }, + "less-loader": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.1.0.tgz", + "integrity": "sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "loader-utils": "^1.1.0", + "pify": "^3.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "license-webpack-plugin": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.3.1.tgz", + "integrity": "sha512-NqAFodJdpBUuf1iD+Ij8hQvF0rCFKlO2KaieoQzAPhFgzLCtJnC7Z7x5gQbGNjoe++wOKAtAmwVEIBLqq2Yp1A==", + "dev": true, + "requires": { + "ejs": "^2.5.7" + } + }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "dev": true, + "requires": { + "immediate": "~3.0.5" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true, + "optional": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true, + "optional": true + }, + "lodash.tail": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", + "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "log4js": { + "version": "0.6.38", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", + "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", + "dev": true, + "requires": { + "readable-stream": "~1.0.2", + "semver": "~4.3.3" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "loglevel": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", + "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", + "dev": true + }, + "loglevelnext": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", + "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", + "dev": true, + "requires": { + "es6-symbol": "^3.1.1", + "object.assign": "^4.1.0" + } + }, + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "make-error": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", + "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", + "dev": true + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", + "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "dev": true, + "requires": { + "mime-db": "~1.35.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "mini-css-extract-plugin": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.1.tgz", + "integrity": "sha512-XWuB3G61Rtasq/gLe7cp5cuozehE6hN+E4sxCamRR/WDiHTg+f7ZIAS024r8UJQffY+e2gGELXQZgQoFDfNDCg==", + "dev": true, + "requires": { + "@webpack-contrib/schema-utils": "^1.0.0-beta.0", + "loader-utils": "^1.1.0", + "webpack-sources": "^1.1.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mississippi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", + "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^2.0.1", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mixin-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", + "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", + "dev": true, + "requires": { + "for-in": "^0.1.3", + "is-extendable": "^0.1.1" + }, + "dependencies": { + "for-in": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", + "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "neo-async": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", + "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-forge": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", + "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", + "dev": true + }, + "node-gyp": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.7.0.tgz", + "integrity": "sha512-qDQE/Ft9xXP6zphwx4sD0t+VhwV7yFaloMpfbL2QnnDZcyaiakWlLdtFGGQfTAwpFHdpbRhRxVhIHN1OKAjgbg==", + "dev": true, + "optional": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": ">=2.9.0 <2.82.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "optional": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "optional": true, + "requires": { + "ajv": "^4.9.1", + "har-schema": "^1.0.5" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true, + "optional": true + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true, + "optional": true + } + } + }, + "node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.0", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-sass": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.2.tgz", + "integrity": "sha512-LdxoJLZutx0aQXHtWIYwJKMj+9pTjneTcLWJgzf2XbGu0q5pRNqW5QvFCEdm3mc5rJOdru/mzln5d0EZLacf6g==", + "dev": true, + "optional": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash.assign": "^4.2.0", + "lodash.clonedeep": "^4.3.2", + "lodash.mergewith": "^4.6.0", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.10.0", + "node-gyp": "^3.3.1", + "npmlog": "^4.0.0", + "request": "2.87.0", + "sass-graph": "^2.2.4", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "optional": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "optional": true + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "npm-package-arg": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", + "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.6.0", + "osenv": "^0.1.5", + "semver": "^5.5.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-registry-client": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-8.6.0.tgz", + "integrity": "sha512-Qs6P6nnopig+Y8gbzpeN/dkt+n7IyVd8f45NTMotGk6Qo7GfBmzwYx6jRLoOOgKiMnaQfYxsuyQlD8Mc3guBhg==", + "dev": true, + "requires": { + "concat-stream": "^1.5.2", + "graceful-fs": "^4.1.6", + "normalize-package-data": "~1.0.1 || ^2.0.0", + "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", + "npmlog": "2 || ^3.1.0 || ^4.0.0", + "once": "^1.3.3", + "request": "^2.74.0", + "retry": "^0.10.0", + "safe-buffer": "^5.1.1", + "semver": "2 >=2.2.1 || 3.x || 4 || 5", + "slide": "^1.1.3", + "ssri": "^5.2.4" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + } + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", + "dev": true + }, + "original": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz", + "integrity": "sha512-IEvtB5vM5ULvwnqMxWBLxkS13JIEXbakizMSo3yoPNPCIWzg8TG3Usn/UhXoZFM/m+FuEA20KdzPSFq/0rS+UA==", + "dev": true, + "requires": { + "url-parse": "~1.4.0" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "optional": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "dev": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, + "parse-asn1": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "parsejson": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", + "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pbkdf2": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", + "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "portfinder": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", + "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-import": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz", + "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==", + "dev": true, + "requires": { + "postcss": "^6.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-load-config": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", + "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", + "dev": true, + "requires": { + "cosmiconfig": "^4.0.0", + "import-cwd": "^2.0.0" + } + }, + "postcss-loader": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.6.tgz", + "integrity": "sha512-hgiWSc13xVQAq25cVw80CH0l49ZKlAnU1hKPOdRrNj89bokRr/bZF2nT+hebPPF9c9xs8c3gw3Fr2nxtmXYnNg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^6.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^0.4.0" + } + }, + "postcss-url": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.2.tgz", + "integrity": "sha512-QMV5mA+pCYZQcUEPQkmor9vcPQ2MT+Ipuu8qdi1gVxbNiIiErEGft+eny1ak19qALoBkccS5AHaCaCDzh7b9MA==", + "dev": true, + "requires": { + "mime": "^1.4.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.0", + "postcss": "^6.0.1", + "xxhashjs": "^0.2.1" + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "dev": true, + "requires": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "optional": true, + "requires": { + "asap": "~2.0.3" + } + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "protractor": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.3.2.tgz", + "integrity": "sha512-pw4uwwiy5lHZjIguxNpkEwJJa7hVz+bJsvaTI+IbXlfn2qXwzbF8eghW/RmrZwE2sGx82I8etb8lVjQ+JrjejA==", + "dev": true, + "requires": { + "@types/node": "^6.0.46", + "@types/q": "^0.0.32", + "@types/selenium-webdriver": "~2.53.39", + "blocking-proxy": "^1.0.0", + "chalk": "^1.1.3", + "glob": "^7.0.3", + "jasmine": "2.8.0", + "jasminewd2": "^2.1.0", + "optimist": "~0.6.0", + "q": "1.4.1", + "saucelabs": "^1.5.0", + "selenium-webdriver": "3.6.0", + "source-map-support": "~0.4.0", + "webdriver-js-extender": "^1.0.0", + "webdriver-manager": "^12.0.6" + }, + "dependencies": { + "@types/node": { + "version": "6.0.114", + "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.114.tgz", + "integrity": "sha512-5ViC9dwf1VIAtrOFTvOuN04lJgw28eKjuy0Vg2Bd/fSlxKP2feCSkIw04ZgOENL2ywdWrtbkthp1XVLEjJmouw==", + "dev": true + }, + "adm-zip": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz", + "integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "webdriver-manager": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.0.tgz", + "integrity": "sha512-oEc5fmkpz6Yh6udhwir5m0eN5mgRPq9P/NU5YWuT3Up5slt6Zz+znhLU7q4+8rwCZz/Qq3Fgpr/4oao7NPCm2A==", + "dev": true, + "requires": { + "adm-zip": "^0.4.9", + "chalk": "^1.1.1", + "del": "^2.2.0", + "glob": "^7.0.3", + "ini": "^1.3.4", + "minimist": "^1.2.0", + "q": "^1.4.1", + "request": "^2.87.0", + "rimraf": "^2.5.2", + "semver": "^5.3.0", + "xml2js": "^0.4.17" + } + } + } + }, + "proxy-addr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", + "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.6.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", + "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==", + "dev": true + }, + "randomatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", + "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", + "dev": true, + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } + } + }, + "raw-loader": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", + "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", + "dev": true + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "requires": { + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "dependencies": { + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "reflect-metadata": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.12.tgz", + "integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==", + "dev": true + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "renderkid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", + "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", + "dev": true, + "requires": { + "css-select": "^1.1.0", + "dom-converter": "~0.1", + "htmlparser2": "~3.3.0", + "strip-ansi": "^3.0.0", + "utila": "~0.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", + "dev": true + } + } + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "optional": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "rxjs": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.2.tgz", + "integrity": "sha512-0MI8+mkKAXZUF9vMrEoPnaoHkfzBPP4IGwUYRJhIRJF6/w3uByO1e91bEHn8zd43RdkTMKiooYKmwz7RH6zfOQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass-graph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true, + "optional": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true, + "optional": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + } + } + } + }, + "sass-loader": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.0.3.tgz", + "integrity": "sha512-iaSFtQcGo4SSgDw5Aes5p4VTrA5jCGSA7sGmhPIcOloBlgI1VktM2MUrk2IHHjbNagckXlPz+HWq1vAAPrcYxA==", + "dev": true, + "requires": { + "clone-deep": "^2.0.1", + "loader-utils": "^1.0.1", + "lodash.tail": "^4.1.1", + "neo-async": "^2.5.0", + "pify": "^3.0.0" + } + }, + "saucelabs": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", + "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", + "dev": true, + "requires": { + "https-proxy-agent": "^2.2.1" + } + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", + "dev": true + }, + "schema-utils": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", + "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "optional": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selenium-webdriver": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", + "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", + "dev": true, + "requires": { + "jszip": "^3.1.3", + "rimraf": "^2.5.4", + "tmp": "0.0.30", + "xml2js": "^0.4.17" + }, + "dependencies": { + "tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + } + } + }, + "selfsigned": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.3.tgz", + "integrity": "sha512-vmZenZ+8Al3NLHkWnhBQ0x6BkML1eCP2xEi3JE+f3D9wW9fipD9NNJHYtE9XJM4TsPaHGZJIamrSI6MTg1dU2Q==", + "dev": true, + "requires": { + "node-forge": "0.7.5" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "semver-dsl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", + "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "semver-intersect": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.3.1.tgz", + "integrity": "sha1-j6hKnhAovSOeRTDRo+GB5pjYhLo=", + "dev": true, + "requires": { + "semver": "^5.0.0" + } + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", + "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==", + "dev": true + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", + "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", + "dev": true, + "requires": { + "is-extendable": "^0.1.1", + "kind-of": "^5.0.0", + "mixin-object": "^2.0.1" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "silent-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/silent-error/-/silent-error-1.1.0.tgz", + "integrity": "sha1-IglwbxyFCp8dENDYQJGLRvJuG8k=", + "dev": true, + "requires": { + "debug": "^2.2.0" + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "optional": true, + "requires": { + "hoek": "2.x.x" + } + }, + "socket.io": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", + "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", + "dev": true, + "requires": { + "debug": "2.3.3", + "engine.io": "1.8.3", + "has-binary": "0.1.7", + "object-assign": "4.1.0", + "socket.io-adapter": "0.5.0", + "socket.io-client": "1.7.3", + "socket.io-parser": "2.3.1" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + }, + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "dev": true + } + } + }, + "socket.io-adapter": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", + "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", + "dev": true, + "requires": { + "debug": "2.3.3", + "socket.io-parser": "2.3.1" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "socket.io-client": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", + "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", + "dev": true, + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "2.3.3", + "engine.io-client": "1.8.3", + "has-binary": "0.1.7", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseuri": "0.0.5", + "socket.io-parser": "2.3.1", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", + "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", + "dev": true, + "requires": { + "ms": "0.7.2" + } + }, + "ms": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", + "dev": true + } + } + }, + "socket.io-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", + "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", + "dev": true, + "requires": { + "component-emitter": "1.1.2", + "debug": "2.2.0", + "isarray": "0.0.1", + "json3": "3.3.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", + "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", + "dev": true + }, + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "requires": { + "ms": "0.7.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + } + }, + "sockjs-client": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.5.tgz", + "integrity": "sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM=", + "dev": true, + "requires": { + "debug": "^2.6.6", + "eventsource": "0.1.6", + "faye-websocket": "~0.11.0", + "inherits": "^2.0.1", + "json3": "^3.3.2", + "url-parse": "^1.1.8" + }, + "dependencies": { + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + } + } + }, + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "dev": true + }, + "spdy": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", + "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", + "dev": true, + "requires": { + "debug": "^2.6.8", + "handle-thing": "^1.2.5", + "http-deceiver": "^1.2.7", + "safe-buffer": "^5.0.1", + "select-hose": "^2.0.0", + "spdy-transport": "^2.0.18" + } + }, + "spdy-transport": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", + "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "detect-node": "^2.0.3", + "hpack.js": "^2.1.6", + "obuf": "^1.1.1", + "readable-stream": "^2.2.9", + "safe-buffer": "^5.0.1", + "wbuf": "^1.7.2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", + "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stats-webpack-plugin": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/stats-webpack-plugin/-/stats-webpack-plugin-0.6.2.tgz", + "integrity": "sha1-LFlJtTHgf4eojm6k3PrFOqjHWis=", + "dev": true, + "requires": { + "lodash": "^4.17.4" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + }, + "stdout-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", + "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "dev": true, + "optional": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz", + "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "style-loader": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", + "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^0.4.5" + } + }, + "stylus": { + "version": "0.54.5", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", + "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "dev": true, + "requires": { + "css-parse": "1.7.x", + "debug": "*", + "glob": "7.0.x", + "mkdirp": "0.5.x", + "sax": "0.5.x", + "source-map": "0.1.x" + }, + "dependencies": { + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "stylus-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", + "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", + "dev": true, + "requires": { + "loader-utils": "^1.0.2", + "lodash.clonedeep": "^4.5.0", + "when": "~3.6.x" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "tapable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", + "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", + "dev": true + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "optional": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz", + "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", + "dev": true + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "requires": { + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "tree-kill": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", + "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==", + "dev": true + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "true-case-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", + "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=", + "dev": true, + "optional": true, + "requires": { + "glob": "^6.0.4" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "ts-node": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-5.0.1.tgz", + "integrity": "sha512-XK7QmDcNHVmZkVtkiwNDWiERRHPyU8nBqZB1+iv2UhOG0q3RQ9HsZ2CMqISlFbxjrYFGfG2mX7bW4dAyxBVzUw==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "chalk": "^2.3.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.3", + "yn": "^2.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tsickle": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.29.0.tgz", + "integrity": "sha512-JpID0Lv8/irRtPmqJJxb5fCwfZhjZeKmav9Zna7UjqVuJoSbI49Wue/c2PPybX1SbRrjl7bbI/JsCl0dSUJygA==", + "dev": true, + "requires": { + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map": "^0.6.0", + "source-map-support": "^0.5.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, + "tslint": { + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz", + "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.12.1" + }, + "dependencies": { + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "tsutils": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", + "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz", + "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==", + "dev": true + }, + "uglify-js": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.5.tgz", + "integrity": "sha512-Fm52gLqJqFBnT+Sn411NPDnsgaWiYeRLw42x7Va/mS8TKgaepwoGY7JLXHSEef3d3PmdFXSz1Zx7KMLL89E2QA==", + "dev": true, + "requires": { + "commander": "~2.16.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz", + "integrity": "sha512-1VicfKhCYHLS8m1DCApqBhoulnASsEoJ/BvpUpP4zoNAPpKzdH+ghk0olGJMmwX2/jprK2j3hAHdUbczBSy2FA==", + "dev": true, + "requires": { + "cacache": "^10.0.4", + "find-cache-dir": "^1.0.0", + "schema-utils": "^0.4.5", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "uglify-es": "^3.3.4", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + } + } + } + }, + "ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz", + "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", + "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "uri-js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz", + "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-join": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz", + "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=", + "dev": true + }, + "url-loader": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.0.1.tgz", + "integrity": "sha512-rAonpHy7231fmweBKUFe0bYnlGDty77E+fm53NZdij7j/YOpyGzc7ttqG1nAXl3aRs0k41o0PC3TvGXQiw2Zvw==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^0.4.3" + }, + "dependencies": { + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "dev": true + } + } + }, + "url-parse": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.1.tgz", + "integrity": "sha512-x95Td74QcvICAA0+qERaVkRpTGKyBHHYdwL2LXZm5t/gBtCB9KQSO/0zQgSTYEV1p0WcvSg79TLNPSvd5IDJMQ==", + "dev": true, + "requires": { + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "useragent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", + "dev": true, + "requires": { + "lru-cache": "4.1.x", + "tmp": "0.0.x" + } + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webassemblyjs": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webassemblyjs/-/webassemblyjs-1.4.3.tgz", + "integrity": "sha512-4lOV1Lv6olz0PJkDGQEp82HempAn147e6BXijWDzz9g7/2nSebVP9GVg62Fz5ZAs55mxq13GA0XLyvY8XkyDjg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/validation": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "long": "^3.2.0" + } + }, + "webdriver-js-extender": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz", + "integrity": "sha1-gcUzqeM9W/tZe05j4s2yW1R3dRU=", + "dev": true, + "requires": { + "@types/selenium-webdriver": "^2.53.35", + "selenium-webdriver": "^2.53.2" + }, + "dependencies": { + "sax": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.6.1.tgz", + "integrity": "sha1-VjsZx8HeiS4Jv8Ty/DDjwn8JUrk=", + "dev": true + }, + "selenium-webdriver": { + "version": "2.53.3", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz", + "integrity": "sha1-0p/1qVff8aG0ncRXdW5OS/vc4IU=", + "dev": true, + "requires": { + "adm-zip": "0.4.4", + "rimraf": "^2.2.8", + "tmp": "0.0.24", + "ws": "^1.0.1", + "xml2js": "0.4.4" + } + }, + "tmp": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz", + "integrity": "sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=", + "dev": true + }, + "xml2js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", + "integrity": "sha1-MREBAAMAiuGSQOuhdJe1fHKcVV0=", + "dev": true, + "requires": { + "sax": "0.6.x", + "xmlbuilder": ">=1.0.0" + } + } + } + }, + "webpack": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.8.3.tgz", + "integrity": "sha512-/hfAjBISycdK597lxONjKEFX7dSIU1PsYwC3XlXUXoykWBlv9QV5HnO+ql3HvrrgfBJ7WXdnjO9iGPR2aAc5sw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/wasm-edit": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "acorn": "^5.0.0", + "acorn-dynamic-import": "^3.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chrome-trace-event": "^0.1.1", + "enhanced-resolve": "^4.0.0", + "eslint-scope": "^3.7.1", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", + "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", + "node-libs-browser": "^2.0.0", + "schema-utils": "^0.4.4", + "tapable": "^1.0.0", + "uglifyjs-webpack-plugin": "^1.2.4", + "watchpack": "^1.5.0", + "webpack-sources": "^1.0.1" + } + }, + "webpack-core": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", + "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", + "dev": true, + "requires": { + "source-list-map": "~0.1.7", + "source-map": "~0.4.1" + }, + "dependencies": { + "source-list-map": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", + "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", + "dev": true + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "webpack-dev-middleware": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.1.3.tgz", + "integrity": "sha512-I6Mmy/QjWU/kXwCSFGaiOoL5YEQIVmbb0o45xMoCyQAg/mClqZVTcsX327sPfekDyJWpCxb+04whNyLOIxpJdQ==", + "dev": true, + "requires": { + "loud-rejection": "^1.6.0", + "memory-fs": "~0.4.1", + "mime": "^2.1.0", + "path-is-absolute": "^1.0.0", + "range-parser": "^1.0.3", + "url-join": "^4.0.0", + "webpack-log": "^1.0.1" + }, + "dependencies": { + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "dev": true + } + } + }, + "webpack-dev-server": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.5.tgz", + "integrity": "sha512-LVHg+EPwZLHIlfvokSTgtJqO/vI5CQi89fASb5JEDtVMDjY0yuIEqPPdMiKaBJIB/Ab7v/UN/sYZ7WsZvntQKw==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "array-includes": "^3.0.3", + "bonjour": "^3.5.0", + "chokidar": "^2.0.0", + "compression": "^1.5.2", + "connect-history-api-fallback": "^1.3.0", + "debug": "^3.1.0", + "del": "^3.0.0", + "express": "^4.16.2", + "html-entities": "^1.2.0", + "http-proxy-middleware": "~0.18.0", + "import-local": "^1.0.0", + "internal-ip": "1.2.0", + "ip": "^1.1.5", + "killable": "^1.0.0", + "loglevel": "^1.4.1", + "opn": "^5.1.0", + "portfinder": "^1.0.9", + "selfsigned": "^1.9.1", + "serve-index": "^1.7.2", + "sockjs": "0.3.19", + "sockjs-client": "1.1.5", + "spdy": "^3.4.1", + "strip-ansi": "^3.0.0", + "supports-color": "^5.1.0", + "webpack-dev-middleware": "3.1.3", + "webpack-log": "^1.1.2", + "yargs": "11.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "webpack-log": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", + "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", + "dev": true, + "requires": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "loglevelnext": "^1.0.1", + "uuid": "^3.1.0" + } + }, + "webpack-merge": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.3.tgz", + "integrity": "sha512-zxwAIGK7nKdu5CIZL0BjTQoq3elV0t0MfB7rUC1zj668geid52abs6hN/ACwZdK6LeMS8dC9B6WmtF978zH5mg==", + "dev": true, + "requires": { + "lodash": "^4.17.5" + } + }, + "webpack-sources": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "webpack-subresource-integrity": { + "version": "1.1.0-rc.4", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.4.tgz", + "integrity": "sha1-xcTj1pD50vZKlVDgeodn+Xlqpdg=", + "dev": true, + "requires": { + "webpack-core": "^0.6.8" + } + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "dev": true, + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true + }, + "when": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", + "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "worker-farm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", + "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", + "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", + "dev": true, + "requires": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + }, + "wtf-8": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", + "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + }, + "dependencies": { + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + } + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + }, + "xmlhttprequest-ssl": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", + "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "dev": true, + "requires": { + "cuint": "^0.2.2" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "^3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true, + "optional": true + } + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true + }, + "zone.js": { + "version": "0.8.26", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.26.tgz", + "integrity": "sha512-W9Nj+UmBJG251wkCacIkETgra4QgBo/vgoEkb4a2uoLzpQG7qF9nzwoLXWU5xj3Fg2mxGvEDh47mg24vXccYjA==" + } + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/package.json b/spring-boot-angular-ecommerce/src/main/frontend/package.json new file mode 100644 index 0000000000..958e9f1023 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/package.json @@ -0,0 +1,52 @@ +{ + "name": "frontend", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve --proxy-config proxy-conf.json", + "build": "ng build", + "postbuild": "npm run deploy", + "predeploy": "rimraf ../resources/static/ && mkdirp ../resources/static", + "deploy": "copyfiles -f dist/** ../resources/static", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" + }, + "private": true, + "dependencies": { + "@angular/animations": "^6.0.3", + "@angular/common": "^6.0.3", + "@angular/compiler": "^6.0.3", + "@angular/core": "^6.0.3", + "@angular/forms": "^6.0.3", + "@angular/http": "^6.0.3", + "@angular/platform-browser": "^6.0.3", + "@angular/platform-browser-dynamic": "^6.0.3", + "@angular/router": "^6.0.3", + "bootstrap": "^4.1.2", + "core-js": "^2.5.4", + "rxjs": "^6.0.0", + "zone.js": "^0.8.26" + }, + "devDependencies": { + "@angular/compiler-cli": "^6.0.3", + "@angular-devkit/build-angular": "~0.6.8", + "typescript": "~2.7.2", + "@angular/cli": "~6.0.8", + "@angular/language-service": "^6.0.3", + "@types/jasmine": "~2.8.6", + "@types/jasminewd2": "~2.0.3", + "@types/node": "~8.9.4", + "codelyzer": "~4.2.1", + "jasmine-core": "~2.99.1", + "jasmine-spec-reporter": "~4.2.1", + "karma": "~1.7.1", + "karma-chrome-launcher": "~2.2.0", + "karma-coverage-istanbul-reporter": "~2.0.0", + "karma-jasmine": "~1.1.1", + "karma-jasmine-html-reporter": "^0.2.2", + "protractor": "~5.3.0", + "ts-node": "~5.0.1", + "tslint": "~5.9.1" + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/proxy-conf.json b/spring-boot-angular-ecommerce/src/main/frontend/proxy-conf.json new file mode 100644 index 0000000000..534224beb5 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/proxy-conf.json @@ -0,0 +1,6 @@ +{ + "/api": { + "target": "http://localhost:8080", + "secure": false + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.css b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.css new file mode 100644 index 0000000000..f8fb0a460e --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.css @@ -0,0 +1,3 @@ +.container { + padding-top: 65px; +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.html b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.html new file mode 100644 index 0000000000..1b0ca2464f --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.html @@ -0,0 +1,3 @@ +
    + +
    diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.spec.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.spec.ts new file mode 100644 index 0000000000..decc558568 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.spec.ts @@ -0,0 +1,27 @@ +import { TestBed, async } from '@angular/core/testing'; +import { AppComponent } from './app.component'; +describe('AppComponent', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + AppComponent + ], + }).compileComponents(); + })); + it('should create the app', async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + })); + it(`should have as title 'app'`, async(() => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('app'); + })); + it('should render title in a h1 tag', async(() => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to frontend!'); + })); +}); diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.ts new file mode 100644 index 0000000000..6840b14af1 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.component.ts @@ -0,0 +1,12 @@ +import {Component} from '@angular/core'; +import {EcommerceService} from "./ecommerce/services/EcommerceService"; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], + providers: [EcommerceService] +}) +export class AppComponent { + +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.module.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.module.ts new file mode 100644 index 0000000000..279d2eb2d5 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/app.module.ts @@ -0,0 +1,31 @@ +import {BrowserModule} from '@angular/platform-browser'; +import {NgModule} from '@angular/core'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {HttpClientModule} from '@angular/common/http'; + +import {AppComponent} from './app.component'; +import {EcommerceComponent} from './ecommerce/ecommerce.component'; +import {ProductsComponent} from './ecommerce/products/products.component'; +import {ShoppingCartComponent} from './ecommerce/shopping-cart/shopping-cart.component'; +import {OrdersComponent} from './ecommerce/orders/orders.component'; +import {EcommerceService} from "./ecommerce/services/EcommerceService"; + +@NgModule({ + declarations: [ + AppComponent, + EcommerceComponent, + ProductsComponent, + ShoppingCartComponent, + OrdersComponent + ], + imports: [ + BrowserModule, + HttpClientModule, + FormsModule, + ReactiveFormsModule + ], + providers: [EcommerceService], + bootstrap: [AppComponent] +}) +export class AppModule { +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.css b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.html b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.html new file mode 100644 index 0000000000..682f0374b5 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.html @@ -0,0 +1,31 @@ + +
    +
    + +
    +
    + +
    +
    + +
    +
    diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.spec.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.spec.ts new file mode 100644 index 0000000000..90ac7d9b58 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EcommerceComponent } from './ecommerce.component'; + +describe('EcommerceComponent', () => { + let component: EcommerceComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EcommerceComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EcommerceComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.ts new file mode 100644 index 0000000000..901fdef6e6 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/ecommerce.component.ts @@ -0,0 +1,44 @@ +import {Component, OnInit, ViewChild} from '@angular/core'; +import {ProductsComponent} from "./products/products.component"; +import {ShoppingCartComponent} from "./shopping-cart/shopping-cart.component"; +import {OrdersComponent} from "./orders/orders.component"; + +@Component({ + selector: 'app-ecommerce', + templateUrl: './ecommerce.component.html', + styleUrls: ['./ecommerce.component.css'] +}) +export class EcommerceComponent implements OnInit { + private collapsed = true; + orderFinished = false; + + @ViewChild('productsC') + productsC: ProductsComponent; + + @ViewChild('shoppingCartC') + shoppingCartC: ShoppingCartComponent; + + @ViewChild('ordersC') + ordersC: OrdersComponent; + + constructor() { + } + + ngOnInit() { + } + + toggleCollapsed(): void { + this.collapsed = !this.collapsed; + } + + finishOrder(orderFinished: boolean) { + this.orderFinished = orderFinished; + } + + reset() { + this.orderFinished = false; + this.productsC.reset(); + this.shoppingCartC.reset(); + this.ordersC.paid = false; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product-order.model.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product-order.model.ts new file mode 100644 index 0000000000..0e1d9b03c8 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product-order.model.ts @@ -0,0 +1,11 @@ +import {Product} from "./product.model"; + +export class ProductOrder { + product: Product; + quantity: number; + + constructor(product: Product, quantity: number) { + this.product = product; + this.quantity = quantity; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product-orders.model.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product-orders.model.ts new file mode 100644 index 0000000000..d6b1f321a9 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product-orders.model.ts @@ -0,0 +1,5 @@ +import {ProductOrder} from "./product-order.model"; + +export class ProductOrders { + productOrders: ProductOrder[] = []; +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product.model.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product.model.ts new file mode 100644 index 0000000000..258753f62e --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/models/product.model.ts @@ -0,0 +1,13 @@ +export class Product { + id: number; + name: string; + price: number; + pictureUrl: string; + + constructor(id: number, name: string, price: number, pictureUrl: string) { + this.id = id; + this.name = name; + this.price = price; + this.pictureUrl = pictureUrl; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.css b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.html b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.html new file mode 100644 index 0000000000..e4a8b50c63 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.html @@ -0,0 +1,13 @@ +

    ORDER

    +
      +
    • + {{ order.product.name }} - ${{ order.product.price }} x {{ order.quantity}} pcs. +
    • +
    +

    Total amount: ${{ total }}

    + + + + diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.spec.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.spec.ts new file mode 100644 index 0000000000..b8efbb0f4e --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OrdersComponent } from './orders.component'; + +describe('OrdersComponent', () => { + let component: OrdersComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ OrdersComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(OrdersComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.ts new file mode 100644 index 0000000000..c3348ed396 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/orders/orders.component.ts @@ -0,0 +1,39 @@ +import {Component, OnInit} from '@angular/core'; +import {ProductOrders} from "../models/product-orders.model"; +import {Subscription} from "rxjs/internal/Subscription"; +import {EcommerceService} from "../services/EcommerceService"; + +@Component({ + selector: 'app-orders', + templateUrl: './orders.component.html', + styleUrls: ['./orders.component.css'] +}) +export class OrdersComponent implements OnInit { + orders: ProductOrders; + total: number; + paid: boolean; + sub: Subscription; + + constructor(private ecommerceService: EcommerceService) { + this.orders = this.ecommerceService.ProductOrders; + } + + ngOnInit() { + this.paid = false; + this.sub = this.ecommerceService.OrdersChanged.subscribe(() => { + this.orders = this.ecommerceService.ProductOrders; + }); + this.loadTotal(); + } + + pay() { + this.paid = true; + this.ecommerceService.saveOrder(this.orders).subscribe(); + } + + loadTotal() { + this.sub = this.ecommerceService.TotalChanged.subscribe(() => { + this.total = this.ecommerceService.Total; + }); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.css b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.css new file mode 100644 index 0000000000..dce4e4caf2 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.css @@ -0,0 +1,4 @@ +.padding-0 { + padding-right: 0; + padding-left: 1; +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.html b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.html new file mode 100644 index 0000000000..f9d422b024 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.html @@ -0,0 +1,28 @@ +
    +
    +
    +
    +

    {{order.product.name}}

    +
    +
    + +
    ${{order.product.price}}
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.spec.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.spec.ts new file mode 100644 index 0000000000..563ae953e1 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProductsComponent } from './products.component'; + +describe('ProductsComponent', () => { + let component: ProductsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ProductsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ProductsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.ts new file mode 100644 index 0000000000..520d0b106a --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/products/products.component.ts @@ -0,0 +1,82 @@ +import {Component, OnInit} from '@angular/core'; +import {ProductOrder} from "../models/product-order.model"; +import {EcommerceService} from "../services/EcommerceService"; +import {Subscription} from "rxjs/internal/Subscription"; +import {ProductOrders} from "../models/product-orders.model"; +import {Product} from "../models/product.model"; + +@Component({ + selector: 'app-products', + templateUrl: './products.component.html', + styleUrls: ['./products.component.css'] +}) +export class ProductsComponent implements OnInit { + productOrders: ProductOrder[] = []; + products: Product[] = []; + selectedProductOrder: ProductOrder; + private shoppingCartOrders: ProductOrders; + sub: Subscription; + productSelected: boolean = false; + + constructor(private ecommerceService: EcommerceService) { + } + + ngOnInit() { + this.productOrders = []; + this.loadProducts(); + this.loadOrders(); + } + + addToCart(order: ProductOrder) { + this.ecommerceService.SelectedProductOrder = order; + this.selectedProductOrder = this.ecommerceService.SelectedProductOrder; + this.productSelected = true; + } + + removeFromCart(productOrder: ProductOrder) { + let index = this.getProductIndex(productOrder.product); + if (index > -1) { + this.shoppingCartOrders.productOrders.splice( + this.getProductIndex(productOrder.product), 1); + } + this.ecommerceService.ProductOrders = this.shoppingCartOrders; + this.shoppingCartOrders = this.ecommerceService.ProductOrders; + this.productSelected = false; + } + + getProductIndex(product: Product): number { + return this.ecommerceService.ProductOrders.productOrders.findIndex( + value => value.product === product); + } + + isProductSelected(product: Product): boolean { + return this.getProductIndex(product) > -1; + } + + loadProducts() { + this.ecommerceService.getAllProducts() + .subscribe( + (products: any[]) => { + this.products = products; + this.products.forEach(product => { + this.productOrders.push(new ProductOrder(product, 0)); + }) + }, + (error) => console.log(error) + ); + } + + loadOrders() { + this.sub = this.ecommerceService.OrdersChanged.subscribe(() => { + this.shoppingCartOrders = this.ecommerceService.ProductOrders; + }); + } + + reset() { + this.productOrders = []; + this.loadProducts(); + this.ecommerceService.ProductOrders.productOrders = []; + this.loadOrders(); + this.productSelected = false; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/services/EcommerceService.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/services/EcommerceService.ts new file mode 100644 index 0000000000..d22b740c41 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/services/EcommerceService.ts @@ -0,0 +1,62 @@ +import {ProductOrder} from "../models/product-order.model"; +import {Subject} from "rxjs/internal/Subject"; +import {ProductOrders} from "../models/product-orders.model"; +import {HttpClient} from '@angular/common/http'; +import {Injectable} from "@angular/core"; + +@Injectable() +export class EcommerceService { + private productsUrl = "/api/products"; + private ordersUrl = "/api/orders"; + + private productOrder: ProductOrder; + private orders: ProductOrders = new ProductOrders(); + + private productOrderSubject = new Subject(); + private ordersSubject = new Subject(); + private totalSubject = new Subject(); + + private total: number; + + ProductOrderChanged = this.productOrderSubject.asObservable(); + OrdersChanged = this.ordersSubject.asObservable(); + TotalChanged = this.totalSubject.asObservable(); + + constructor(private http: HttpClient) { + } + + getAllProducts() { + return this.http.get(this.productsUrl); + } + + saveOrder(order: ProductOrders) { + return this.http.post(this.ordersUrl, order); + } + + set SelectedProductOrder(value: ProductOrder) { + this.productOrder = value; + this.productOrderSubject.next(); + } + + get SelectedProductOrder() { + return this.productOrder; + } + + set ProductOrders(value: ProductOrders) { + this.orders = value; + this.ordersSubject.next(); + } + + get ProductOrders() { + return this.orders; + } + + get Total() { + return this.total; + } + + set Total(value: number) { + this.total = value; + this.totalSubject.next(); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.css b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.html b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.html new file mode 100644 index 0000000000..b18a02b93c --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.html @@ -0,0 +1,18 @@ +
    +
    Shopping Cart
    +
    +
    Total: ${{total}}
    +
    +
    Items bought:
    + +
      +
    • + {{ order.product.name }} - {{ order.quantity}} pcs. +
    • +
    + + +
    +
    diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.spec.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.spec.ts new file mode 100644 index 0000000000..5d7735477c --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ShoppingCartComponent } from './shopping-cart.component'; + +describe('ShoppingCartComponent', () => { + let component: ShoppingCartComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ShoppingCartComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ShoppingCartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.ts new file mode 100644 index 0000000000..81a6514eb7 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/app/ecommerce/shopping-cart/shopping-cart.component.ts @@ -0,0 +1,76 @@ +import {Component, EventEmitter, OnDestroy, OnInit, Output} from '@angular/core'; +import {ProductOrders} from "../models/product-orders.model"; +import {ProductOrder} from "../models/product-order.model"; +import {EcommerceService} from "../services/EcommerceService"; +import {Subscription} from "rxjs/internal/Subscription"; + +@Component({ + selector: 'app-shopping-cart', + templateUrl: './shopping-cart.component.html', + styleUrls: ['./shopping-cart.component.css'] +}) +export class ShoppingCartComponent implements OnInit, OnDestroy { + orderFinished: boolean; + orders: ProductOrders; + total: number; + sub: Subscription; + + @Output() onOrderFinished: EventEmitter; + + constructor(private ecommerceService: EcommerceService) { + this.total = 0; + this.orderFinished = false; + this.onOrderFinished = new EventEmitter(); + } + + ngOnInit() { + this.orders = new ProductOrders(); + this.loadCart(); + this.loadTotal(); + } + + private calculateTotal(products: ProductOrder[]): number { + let sum = 0; + products.forEach(value => { + sum += (value.product.price * value.quantity); + }); + return sum; + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + finishOrder() { + this.orderFinished = true; + this.ecommerceService.Total = this.total; + this.onOrderFinished.emit(this.orderFinished); + } + + loadTotal() { + this.sub = this.ecommerceService.OrdersChanged.subscribe(() => { + this.total = this.calculateTotal(this.orders.productOrders); + }); + } + + loadCart() { + this.sub = this.ecommerceService.ProductOrderChanged.subscribe(() => { + let productOrder = this.ecommerceService.SelectedProductOrder; + if (productOrder) { + this.orders.productOrders.push(new ProductOrder( + productOrder.product, productOrder.quantity)); + } + this.ecommerceService.ProductOrders = this.orders; + this.orders = this.ecommerceService.ProductOrders; + this.total = this.calculateTotal(this.orders.productOrders); + }); + } + + reset() { + this.orderFinished = false; + this.orders = new ProductOrders(); + this.orders.productOrders = [] + this.loadTotal(); + this.total = 0; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/assets/.gitkeep b/spring-boot-angular-ecommerce/src/main/frontend/src/assets/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/browserslist b/spring-boot-angular-ecommerce/src/main/frontend/src/browserslist new file mode 100644 index 0000000000..8e09ab492e --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/browserslist @@ -0,0 +1,9 @@ +# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries +# For IE 9-11 support, please uncomment the last line of the file and adjust as needed +> 0.5% +last 2 versions +Firefox ESR +not dead +# IE 9-11 \ No newline at end of file diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/environments/environment.prod.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/environments/environment.prod.ts new file mode 100644 index 0000000000..3612073bc3 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true +}; diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/environments/environment.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/environments/environment.ts new file mode 100644 index 0000000000..012182efa3 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/environments/environment.ts @@ -0,0 +1,15 @@ +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false +}; + +/* + * In development mode, to ignore zone related error stack frames such as + * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can + * import the following file, but please comment it out in production mode + * because it will have performance impact when throw error + */ +// import 'zone.js/dist/zone-error'; // Included with Angular CLI. diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/favicon.ico b/spring-boot-angular-ecommerce/src/main/frontend/src/favicon.ico new file mode 100644 index 0000000000..8081c7ceaf Binary files /dev/null and b/spring-boot-angular-ecommerce/src/main/frontend/src/favicon.ico differ diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/index.html b/spring-boot-angular-ecommerce/src/main/frontend/src/index.html new file mode 100644 index 0000000000..3faefb6e8c --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/index.html @@ -0,0 +1,14 @@ + + + + + Frontend + + + + + + + + + diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/karma.conf.js b/spring-boot-angular-ecommerce/src/main/frontend/src/karma.conf.js new file mode 100644 index 0000000000..b6e00421c9 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/karma.conf.js @@ -0,0 +1,31 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join(__dirname, '../coverage'), + reports: ['html', 'lcovonly'], + fixWebpackSourcePaths: true + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }); +}; \ No newline at end of file diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/main.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/main.ts new file mode 100644 index 0000000000..91ec6da5f0 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/main.ts @@ -0,0 +1,12 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.log(err)); diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/polyfills.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/polyfills.ts new file mode 100644 index 0000000000..d310405a68 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/polyfills.ts @@ -0,0 +1,80 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; + + +/** Evergreen browsers require these. **/ +// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. +import 'core-js/es7/reflect'; + + +/** + * Web Animations `@angular/platform-browser/animations` + * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. + * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + */ + + // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + + /* + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + */ +// (window as any).__Zone_enable_cross_context_check = true; + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/styles.css b/spring-boot-angular-ecommerce/src/main/frontend/src/styles.css new file mode 100644 index 0000000000..90d4ee0072 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/test.ts b/spring-boot-angular-ecommerce/src/main/frontend/src/test.ts new file mode 100644 index 0000000000..16317897b1 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/test.ts @@ -0,0 +1,20 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/tsconfig.app.json b/spring-boot-angular-ecommerce/src/main/frontend/src/tsconfig.app.json new file mode 100644 index 0000000000..722c370d58 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "module": "es2015", + "types": [] + }, + "exclude": [ + "src/test.ts", + "**/*.spec.ts" + ] +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/tsconfig.spec.json b/spring-boot-angular-ecommerce/src/main/frontend/src/tsconfig.spec.json new file mode 100644 index 0000000000..8f7cedecab --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/tsconfig.spec.json @@ -0,0 +1,19 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "module": "commonjs", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts", + "polyfills.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/src/tslint.json b/spring-boot-angular-ecommerce/src/main/frontend/src/tslint.json new file mode 100644 index 0000000000..52e2c1a5a7 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/src/tslint.json @@ -0,0 +1,17 @@ +{ + "extends": "../tslint.json", + "rules": { + "directive-selector": [ + true, + "attribute", + "app", + "camelCase" + ], + "component-selector": [ + true, + "element", + "app", + "kebab-case" + ] + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/tsconfig.json b/spring-boot-angular-ecommerce/src/main/frontend/tsconfig.json new file mode 100644 index 0000000000..ef44e2862b --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "dom" + ] + } +} diff --git a/spring-boot-angular-ecommerce/src/main/frontend/tslint.json b/spring-boot-angular-ecommerce/src/main/frontend/tslint.json new file mode 100644 index 0000000000..3ea984c776 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/frontend/tslint.json @@ -0,0 +1,130 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "deprecation": { + "severity": "warn" + }, + "eofline": true, + "forin": true, + "import-blacklist": [ + true, + "rxjs/Rx" + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "no-output-on-prefix": true, + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/EcommerceApplication.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/EcommerceApplication.java new file mode 100644 index 0000000000..b1fa14e9a9 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/EcommerceApplication.java @@ -0,0 +1,29 @@ +package com.baeldung.ecommerce; + +import com.baeldung.ecommerce.model.Product; +import com.baeldung.ecommerce.service.ProductService; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class EcommerceApplication { + + public static void main(String[] args) { + SpringApplication.run(EcommerceApplication.class, args); + } + + @Bean + CommandLineRunner runner(ProductService productService) { + return args -> { + productService.save(new Product(1L, "TV Set", 300.00, "http://placehold.it/200x100")); + productService.save(new Product(2L, "Game Console", 200.00, "http://placehold.it/200x100")); + productService.save(new Product(3L, "Sofa", 100.00, "http://placehold.it/200x100")); + productService.save(new Product(4L, "Icecream", 5.00, "http://placehold.it/200x100")); + productService.save(new Product(5L, "Beer", 3.00, "http://placehold.it/200x100")); + productService.save(new Product(6L, "Phone", 500.00, "http://placehold.it/200x100")); + productService.save(new Product(7L, "Watch", 30.00, "http://placehold.it/200x100")); + }; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/controller/OrderController.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/controller/OrderController.java new file mode 100644 index 0000000000..c239496708 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/controller/OrderController.java @@ -0,0 +1,99 @@ +package com.baeldung.ecommerce.controller; + +import com.baeldung.ecommerce.dto.OrderProductDto; +import com.baeldung.ecommerce.exception.ResourceNotFoundException; +import com.baeldung.ecommerce.model.Order; +import com.baeldung.ecommerce.model.OrderProduct; +import com.baeldung.ecommerce.model.OrderStatus; +import com.baeldung.ecommerce.service.OrderProductService; +import com.baeldung.ecommerce.service.OrderService; +import com.baeldung.ecommerce.service.ProductService; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/api/orders") +public class OrderController { + + ProductService productService; + OrderService orderService; + OrderProductService orderProductService; + + public OrderController(ProductService productService, OrderService orderService, OrderProductService orderProductService) { + this.productService = productService; + this.orderService = orderService; + this.orderProductService = orderProductService; + } + + @GetMapping + @ResponseStatus(HttpStatus.OK) + public @NotNull Iterable list() { + return this.orderService.getAllOrders(); + } + + @PostMapping + public ResponseEntity create(@RequestBody OrderForm form) { + List formDtos = form.getProductOrders(); + validateProductsExistence(formDtos); + Order order = new Order(); + order.setStatus(OrderStatus.PAID.name()); + order = this.orderService.create(order); + + List orderProducts = new ArrayList<>(); + for (OrderProductDto dto : formDtos) { + orderProducts.add(orderProductService.create(new OrderProduct(order, productService.getProduct(dto + .getProduct() + .getId()), dto.getQuantity()))); + } + + order.setOrderProducts(orderProducts); + + this.orderService.update(order); + + String uri = ServletUriComponentsBuilder + .fromCurrentServletMapping() + .path("/orders/{id}") + .buildAndExpand(order.getId()) + .toString(); + HttpHeaders headers = new HttpHeaders(); + headers.add("Location", uri); + + return new ResponseEntity<>(order, headers, HttpStatus.CREATED); + } + + private void validateProductsExistence(List orderProducts) { + List list = orderProducts + .stream() + .filter(op -> Objects.isNull(productService.getProduct(op + .getProduct() + .getId()))) + .collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(list)) { + new ResourceNotFoundException("Product not found"); + } + } + + public static class OrderForm { + + private List productOrders; + + public List getProductOrders() { + return productOrders; + } + + public void setProductOrders(List productOrders) { + this.productOrders = productOrders; + } + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/controller/ProductController.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/controller/ProductController.java new file mode 100644 index 0000000000..0f5af0af4b --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/controller/ProductController.java @@ -0,0 +1,25 @@ +package com.baeldung.ecommerce.controller; + +import com.baeldung.ecommerce.model.Product; +import com.baeldung.ecommerce.service.ProductService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.constraints.NotNull; + +@RestController +@RequestMapping("/api/products") +public class ProductController { + + private ProductService productService; + + public ProductController(ProductService productService) { + this.productService = productService; + } + + @GetMapping(value = { "", "/" }) + public @NotNull Iterable getProducts() { + return productService.getAllProducts(); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/dto/OrderProductDto.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/dto/OrderProductDto.java new file mode 100644 index 0000000000..f4c92ee28e --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/dto/OrderProductDto.java @@ -0,0 +1,25 @@ +package com.baeldung.ecommerce.dto; + +import com.baeldung.ecommerce.model.Product; + +public class OrderProductDto { + + private Product product; + private Integer quantity; + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/exception/ApiExceptionHandler.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/exception/ApiExceptionHandler.java new file mode 100644 index 0000000000..aae7e39ffc --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/exception/ApiExceptionHandler.java @@ -0,0 +1,81 @@ +package com.baeldung.ecommerce.exception; + +import com.fasterxml.jackson.annotation.JsonInclude; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import java.util.ArrayList; +import java.util.List; + +@RestControllerAdvice +public class ApiExceptionHandler { + + @SuppressWarnings("rawtypes") + @ExceptionHandler(ConstraintViolationException.class) + public ResponseEntity handle(ConstraintViolationException e) { + ErrorResponse errors = new ErrorResponse(); + for (ConstraintViolation violation : e.getConstraintViolations()) { + ErrorItem error = new ErrorItem(); + error.setCode(violation.getMessageTemplate()); + error.setMessage(violation.getMessage()); + errors.addError(error); + } + + return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); + } + + @SuppressWarnings("rawtypes") + @ExceptionHandler(ResourceNotFoundException.class) + public ResponseEntity handle(ResourceNotFoundException e) { + ErrorItem error = new ErrorItem(); + error.setMessage(e.getMessage()); + + return new ResponseEntity<>(error, HttpStatus.NOT_FOUND); + } + + public static class ErrorItem { + + @JsonInclude(JsonInclude.Include.NON_NULL) private String code; + + private String message; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + } + + public static class ErrorResponse { + + private List errors = new ArrayList<>(); + + public List getErrors() { + return errors; + } + + public void setErrors(List errors) { + this.errors = errors; + } + + public void addError(ErrorItem error) { + this.errors.add(error); + } + + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/exception/ResourceNotFoundException.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/exception/ResourceNotFoundException.java new file mode 100644 index 0000000000..3d8e47326c --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/exception/ResourceNotFoundException.java @@ -0,0 +1,22 @@ +package com.baeldung.ecommerce.exception; + +public class ResourceNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 5861310537366287163L; + + public ResourceNotFoundException() { + super(); + } + + public ResourceNotFoundException(final String message, final Throwable cause) { + super(message, cause); + } + + public ResourceNotFoundException(final String message) { + super(message); + } + + public ResourceNotFoundException(final Throwable cause) { + super(cause); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/Order.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/Order.java new file mode 100644 index 0000000000..5b91bc0956 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/Order.java @@ -0,0 +1,78 @@ +package com.baeldung.ecommerce.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonManagedReference; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +import javax.persistence.*; +import javax.validation.Valid; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "orders") +@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="orderProducts") +public class Order { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @JsonFormat(pattern = "dd/MM/yyyy") private LocalDate dateCreated; + + private String status; + + @OneToMany(mappedBy = "pk.order") + @Valid + private List orderProducts = new ArrayList<>(); + + @Transient + public Double getTotalOrderPrice() { + double sum = 0D; + List orderProducts = getOrderProducts(); + for (OrderProduct op : orderProducts) { + sum += op.getTotalPrice(); + } + + return sum; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public LocalDate getDateCreated() { + return dateCreated; + } + + public void setDateCreated(LocalDate dateCreated) { + this.dateCreated = dateCreated; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public List getOrderProducts() { + return orderProducts; + } + + public void setOrderProducts(List orderProducts) { + this.orderProducts = orderProducts; + } + + @Transient + public int getNumberOfProducts() { + return this.orderProducts.size(); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderProduct.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderProduct.java new file mode 100644 index 0000000000..eb1b9876c3 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderProduct.java @@ -0,0 +1,87 @@ +package com.baeldung.ecommerce.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Transient; + +@Entity +public class OrderProduct { + + @EmbeddedId + @JsonIgnore + private OrderProductPK pk; + + @Column(nullable = false) private Integer quantity; + + public OrderProduct() { + super(); + } + + public OrderProduct(Order order, Product product, Integer quantity) { + pk = new OrderProductPK(); + pk.setOrder(order); + pk.setProduct(product); + this.quantity = quantity; + } + + @Transient + public Product getProduct() { + return this.pk.getProduct(); + } + + @Transient + public Double getTotalPrice() { + return getProduct().getPrice() * getQuantity(); + } + + public OrderProductPK getPk() { + return pk; + } + + public void setPk(OrderProductPK pk) { + this.pk = pk; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((pk == null) ? 0 : pk.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; + } + OrderProduct other = (OrderProduct) obj; + if (pk == null) { + if (other.pk != null) { + return false; + } + } else if (!pk.equals(other.pk)) { + return false; + } + + return true; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderProductPK.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderProductPK.java new file mode 100644 index 0000000000..8440a363c1 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderProductPK.java @@ -0,0 +1,91 @@ +package com.baeldung.ecommerce.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; + +import javax.persistence.Embeddable; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import java.io.Serializable; + +@Embeddable +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "order") +public class OrderProductPK implements Serializable { + + private static final long serialVersionUID = 476151177562655457L; + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "order_id") + private Order order; + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "product_id") + private Product product; + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + + result = prime * result + ((order.getId() == null) + ? 0 + : order + .getId() + .hashCode()); + result = prime * result + ((product.getId() == null) + ? 0 + : product + .getId() + .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; + } + OrderProductPK other = (OrderProductPK) obj; + if (order == null) { + if (other.order != null) { + return false; + } + } else if (!order.equals(other.order)) { + return false; + } + + if (product == null) { + if (other.product != null) { + return false; + } + } else if (!product.equals(other.product)) { + return false; + } + + return true; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderStatus.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderStatus.java new file mode 100644 index 0000000000..36bcd5e30d --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/OrderStatus.java @@ -0,0 +1,5 @@ +package com.baeldung.ecommerce.model; + +public enum OrderStatus { + PAID +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/Product.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/Product.java new file mode 100644 index 0000000000..fe2061fab5 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/model/Product.java @@ -0,0 +1,62 @@ +package com.baeldung.ecommerce.model; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; + +@Entity +public class Product { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull(message = "Product name is required.") + @Basic(optional = false) + private String name; + + private Double price; + + private String pictureUrl; + + public Product(Long id, @NotNull(message = "Product name is required.") String name, Double price, String pictureUrl) { + this.id = id; + this.name = name; + this.price = price; + this.pictureUrl = pictureUrl; + } + + public Product() { + } + + 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 Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public String getPictureUrl() { + return pictureUrl; + } + + public void setPictureUrl(String pictureUrl) { + this.pictureUrl = pictureUrl; + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/OrderProductRepository.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/OrderProductRepository.java new file mode 100644 index 0000000000..f596ef8520 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/OrderProductRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.ecommerce.repository; + +import com.baeldung.ecommerce.model.OrderProduct; +import com.baeldung.ecommerce.model.OrderProductPK; +import org.springframework.data.repository.CrudRepository; + +public interface OrderProductRepository extends CrudRepository { +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/OrderRepository.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/OrderRepository.java new file mode 100644 index 0000000000..c6ed21707a --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/OrderRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.ecommerce.repository; + +import com.baeldung.ecommerce.model.Order; +import org.springframework.data.repository.CrudRepository; + +public interface OrderRepository extends CrudRepository { +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/ProductRepository.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/ProductRepository.java new file mode 100644 index 0000000000..ff56b54527 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/repository/ProductRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.ecommerce.repository; + +import com.baeldung.ecommerce.model.Product; +import org.springframework.data.repository.CrudRepository; + +public interface ProductRepository extends CrudRepository { +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderProductService.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderProductService.java new file mode 100644 index 0000000000..575cd68e88 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderProductService.java @@ -0,0 +1,13 @@ +package com.baeldung.ecommerce.service; + +import com.baeldung.ecommerce.model.OrderProduct; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Validated +public interface OrderProductService { + + OrderProduct create(@NotNull(message = "The products for order cannot be null.") @Valid OrderProduct orderProduct); +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderProductServiceImpl.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderProductServiceImpl.java new file mode 100644 index 0000000000..239201d929 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderProductServiceImpl.java @@ -0,0 +1,22 @@ +package com.baeldung.ecommerce.service; + +import com.baeldung.ecommerce.model.OrderProduct; +import com.baeldung.ecommerce.repository.OrderProductRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class OrderProductServiceImpl implements OrderProductService { + + private OrderProductRepository orderProductRepository; + + public OrderProductServiceImpl(OrderProductRepository orderProductRepository) { + this.orderProductRepository = orderProductRepository; + } + + @Override + public OrderProduct create(OrderProduct orderProduct) { + return this.orderProductRepository.save(orderProduct); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderService.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderService.java new file mode 100644 index 0000000000..babc5f88c6 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderService.java @@ -0,0 +1,17 @@ +package com.baeldung.ecommerce.service; + +import com.baeldung.ecommerce.model.Order; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +@Validated +public interface OrderService { + + @NotNull Iterable getAllOrders(); + + Order create(@NotNull(message = "The order cannot be null.") @Valid Order order); + + void update(@NotNull(message = "The order cannot be null.") @Valid Order order); +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderServiceImpl.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderServiceImpl.java new file mode 100644 index 0000000000..2833cfcfb6 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/OrderServiceImpl.java @@ -0,0 +1,36 @@ +package com.baeldung.ecommerce.service; + +import com.baeldung.ecommerce.model.Order; +import com.baeldung.ecommerce.repository.OrderRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; + +@Service +@Transactional +public class OrderServiceImpl implements OrderService { + + private OrderRepository orderRepository; + + public OrderServiceImpl(OrderRepository orderRepository) { + this.orderRepository = orderRepository; + } + + @Override + public Iterable getAllOrders() { + return this.orderRepository.findAll(); + } + + @Override + public Order create(Order order) { + order.setDateCreated(LocalDate.now()); + + return this.orderRepository.save(order); + } + + @Override + public void update(Order order) { + this.orderRepository.save(order); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/ProductService.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/ProductService.java new file mode 100644 index 0000000000..0887f326cb --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/ProductService.java @@ -0,0 +1,17 @@ +package com.baeldung.ecommerce.service; + +import com.baeldung.ecommerce.model.Product; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +@Validated +public interface ProductService { + + @NotNull Iterable getAllProducts(); + + Product getProduct(@Min(value = 1L, message = "Invalid product ID.") long id); + + Product save(Product product); +} diff --git a/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/ProductServiceImpl.java b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/ProductServiceImpl.java new file mode 100644 index 0000000000..af0cc1aaa8 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/java/com/baeldung/ecommerce/service/ProductServiceImpl.java @@ -0,0 +1,35 @@ +package com.baeldung.ecommerce.service; + +import com.baeldung.ecommerce.exception.ResourceNotFoundException; +import com.baeldung.ecommerce.model.Product; +import com.baeldung.ecommerce.repository.ProductRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class ProductServiceImpl implements ProductService { + + private ProductRepository productRepository; + + public ProductServiceImpl(ProductRepository productRepository) { + this.productRepository = productRepository; + } + + @Override + public Iterable getAllProducts() { + return productRepository.findAll(); + } + + @Override + public Product getProduct(long id) { + return productRepository + .findById(id) + .orElseThrow(() -> new ResourceNotFoundException("Product not found")); + } + + @Override + public Product save(Product product) { + return productRepository.save(product); + } +} diff --git a/spring-boot-angular-ecommerce/src/main/resources/application.properties b/spring-boot-angular-ecommerce/src/main/resources/application.properties new file mode 100644 index 0000000000..63a81576af --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/resources/application.properties @@ -0,0 +1,8 @@ +management.security.enabled=false + +spring.datasource.name=ecommercedb +spring.jpa.show-sql=false + +#H2 settings +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console diff --git a/spring-boot-angular-ecommerce/src/main/resources/logback.xml b/spring-boot-angular-ecommerce/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-angular-ecommerce/src/test/java/com/baeldung/ecommerce/EcommerceApplicationIntegrationTest.java b/spring-boot-angular-ecommerce/src/test/java/com/baeldung/ecommerce/EcommerceApplicationIntegrationTest.java new file mode 100644 index 0000000000..03450ea7b2 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/test/java/com/baeldung/ecommerce/EcommerceApplicationIntegrationTest.java @@ -0,0 +1,100 @@ +package com.baeldung.ecommerce; + +import com.baeldung.ecommerce.controller.OrderController; +import com.baeldung.ecommerce.controller.ProductController; +import com.baeldung.ecommerce.dto.OrderProductDto; +import com.baeldung.ecommerce.model.Order; +import com.baeldung.ecommerce.model.Product; +import org.assertj.core.api.Assertions; +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.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Collections; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasProperty; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { EcommerceApplication.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class EcommerceApplicationIntegrationTest { + + @Autowired private TestRestTemplate restTemplate; + + @LocalServerPort private int port; + + @Autowired private ProductController productController; + + @Autowired private OrderController orderController; + + @Test + public void contextLoads() { + Assertions + .assertThat(productController) + .isNotNull(); + Assertions + .assertThat(orderController) + .isNotNull(); + } + + @Test + public void givenGetProductsApiCall_whenProductListRetrieved_thenSizeMatchAndListContainsProductNames() { + ResponseEntity> responseEntity = restTemplate.exchange("http://localhost:" + port + "/api/products", HttpMethod.GET, null, new ParameterizedTypeReference>() { + }); + Iterable products = responseEntity.getBody(); + Assertions + .assertThat(products) + .hasSize(7); + + assertThat(products, hasItem(hasProperty("name", is("TV Set")))); + assertThat(products, hasItem(hasProperty("name", is("Game Console")))); + assertThat(products, hasItem(hasProperty("name", is("Sofa")))); + assertThat(products, hasItem(hasProperty("name", is("Icecream")))); + assertThat(products, hasItem(hasProperty("name", is("Beer")))); + assertThat(products, hasItem(hasProperty("name", is("Phone")))); + assertThat(products, hasItem(hasProperty("name", is("Watch")))); + } + + @Test + public void givenGetOrdersApiCall_whenProductListRetrieved_thenSizeMatchAndListContainsProductNames() { + ResponseEntity> responseEntity = restTemplate.exchange("http://localhost:" + port + "/api/orders", HttpMethod.GET, null, new ParameterizedTypeReference>() { + }); + + Iterable orders = responseEntity.getBody(); + Assertions + .assertThat(orders) + .hasSize(0); + } + + @Test + public void givenPostOrder_whenBodyRequestMatcherJson_thenResponseContainsEqualObjectProperties() { + final ResponseEntity postResponse = restTemplate.postForEntity("http://localhost:" + port + "/api/orders", prepareOrderForm(), Order.class); + Order order = postResponse.getBody(); + Assertions + .assertThat(postResponse.getStatusCode()) + .isEqualByComparingTo(HttpStatus.CREATED); + + assertThat(order, hasProperty("status", is("PAID"))); + assertThat(order.getOrderProducts(), hasItem(hasProperty("quantity", is(2)))); + } + + private OrderController.OrderForm prepareOrderForm() { + OrderController.OrderForm orderForm = new OrderController.OrderForm(); + OrderProductDto productDto = new OrderProductDto(); + productDto.setProduct(new Product(1L, "TV Set", 300.00, "http://placehold.it/200x100")); + productDto.setQuantity(2); + orderForm.setProductOrders(Collections.singletonList(productDto)); + + return orderForm; + } +} diff --git a/spring-boot-angular-ecommerce/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-angular-ecommerce/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..4f595916f7 --- /dev/null +++ b/spring-boot-angular-ecommerce/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.ecommerce.EcommerceApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = EcommerceApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-autoconfiguration/pom.xml b/spring-boot-autoconfiguration/pom.xml index 2a61b89b5d..b88587f731 100644 --- a/spring-boot-autoconfiguration/pom.xml +++ b/spring-boot-autoconfiguration/pom.xml @@ -1,5 +1,5 @@ + 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 spring-boot-autoconfiguration @@ -37,9 +37,8 @@ mysql mysql-connector-java - 8.0.11 - + spring-boot @@ -98,7 +97,6 @@
    - 3.1.1 3.3.7-1 diff --git a/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/MySQLAutoconfiguration.java b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/MySQLAutoconfiguration.java index 4f4f6fb6af..d6fc1836c7 100644 --- a/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/MySQLAutoconfiguration.java +++ b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/MySQLAutoconfiguration.java @@ -1,10 +1,27 @@ package com.baeldung.autoconfiguration; +import java.util.Arrays; +import java.util.Properties; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureOrder; -import org.springframework.boot.autoconfigure.condition.*; +import org.springframework.boot.autoconfigure.condition.ConditionMessage; import org.springframework.boot.autoconfigure.condition.ConditionMessage.Style; -import org.springframework.context.annotation.*; +import org.springframework.boot.autoconfigure.condition.ConditionOutcome; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnResource; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; import org.springframework.core.Ordered; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; @@ -14,11 +31,6 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.util.ClassUtils; -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; -import java.util.Arrays; -import java.util.Properties; - @Configuration @ConditionalOnClass(DataSource.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) diff --git a/spring-boot-autoconfiguration/src/main/resources/logback.xml b/spring-boot-autoconfiguration/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-autoconfiguration/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-autoconfiguration/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-autoconfiguration/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..136ea2481f --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.autoconfiguration.example.AutoconfigurationApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AutoconfigurationApplication.class) +@EnableJpaRepositories(basePackages = { "com.baeldung.autoconfiguration.example" }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-bootstrap/README.md b/spring-boot-bootstrap/README.md index ec6905bf6a..08fdb1bdc9 100644 --- a/spring-boot-bootstrap/README.md +++ b/spring-boot-bootstrap/README.md @@ -1,3 +1,6 @@ ### Relevant Articles: - [Bootstrap a Simple Application using Spring Boot](http://www.baeldung.com/spring-boot-start) - [Spring Boot Dependency Management with a Custom Parent](http://www.baeldung.com/spring-boot-dependency-management-custom-parent) +- [Thin JARs with Spring Boot](http://www.baeldung.com/spring-boot-thin-jar) +- [Deploying a Spring Boot Application to Cloud Foundry](https://www.baeldung.com/spring-boot-app-deploy-to-cloud-foundry) +- [Deploy a Spring Boot Application to Google App Engine](https://www.baeldung.com/spring-boot-google-app-engine) diff --git a/spring-boot-bootstrap/cloudfoundry/manifest.yml b/spring-boot-bootstrap/cloudfoundry/manifest.yml new file mode 100755 index 0000000000..80fce8ff4b --- /dev/null +++ b/spring-boot-bootstrap/cloudfoundry/manifest.yml @@ -0,0 +1,10 @@ +--- +applications: +- name: spring-boot-bootstrap + memory: 768M + random-route: true + path: ../target/spring-boot-bootstrap-cf.jar + env: + SPRING_PROFILES_ACTIVE: cloud,mysql + services: + - spring-bootstrap-db diff --git a/spring-boot-bootstrap/pom.xml b/spring-boot-bootstrap/pom.xml index 9ba4d9a5eb..b5bcc587b1 100644 --- a/spring-boot-bootstrap/pom.xml +++ b/spring-boot-bootstrap/pom.xml @@ -14,6 +14,17 @@ 0.0.1-SNAPSHOT ../parent-boot-2 + + + + org.springframework.cloud + spring-cloud-dependencies + Finchley.SR1 + pom + import + + + @@ -28,10 +39,22 @@ org.springframework.boot spring-boot-starter-data-jpa + + org.springframework.cloud + spring-cloud-starter + + + org.springframework.boot + spring-boot-starter-cloud-connectors + com.h2database h2 + + mysql + mysql-connector-java + org.springframework.boot spring-boot-starter-security @@ -44,17 +67,93 @@ io.rest-assured rest-assured - 3.0.3 + ${rest-assured.version} test javax.servlet javax.servlet-api - 4.0.0 + ${servlet.version} + + cloud-gcp + + + org.springframework.cloud + spring-cloud-gcp-starter + 1.0.0.RELEASE + + + org.springframework.cloud + spring-cloud-gcp-starter-sql-mysql + 1.0.0.RELEASE + + + + ${project.name}-gcp + + + src/main/resources + + **/logback.xml + + + + + + com.google.cloud.tools + appengine-maven-plugin + 1.3.2 + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + cloudfoundry + + + org.springframework.cloud + spring-cloud-starter + + + org.springframework.boot + spring-boot-starter-cloud-connectors + + + + ${project.name}-cf + + + src/main/resources + + **/logback.xml + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + **/cloud/config/*.java + + + + + + autoconfiguration @@ -72,7 +171,7 @@ **/*LiveTest.java **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/AutoconfigurationTest.java @@ -112,11 +211,21 @@ - + + + + org.apache.maven.plugins + maven-compiler-plugin + + + **/cloud/*.java + + + + + - UTF-8 - UTF-8 - 1.8 + 4.0.0 diff --git a/spring-boot-bootstrap/src/main/appengine/app.yaml b/spring-boot-bootstrap/src/main/appengine/app.yaml new file mode 100644 index 0000000000..a65ec6533a --- /dev/null +++ b/spring-boot-bootstrap/src/main/appengine/app.yaml @@ -0,0 +1,19 @@ +runtime: java +env: flex +runtime_config: + jdk: openjdk8 +env_variables: + SPRING_PROFILES_ACTIVE: "gcp,mysql" +handlers: +- url: /.* + script: this field is required, but ignored +resources: + cpu: 2 + memory_gb: 2 + disk_size_gb: 10 + volumes: + - name: ramdisk1 + volume_type: tmpfs + size_gb: 0.5 +manual_scaling: + instances: 1 diff --git a/spring-boot-bootstrap/src/main/java/org/baeldung/cloud/config/CloudDataSourceConfig.java b/spring-boot-bootstrap/src/main/java/org/baeldung/cloud/config/CloudDataSourceConfig.java new file mode 100755 index 0000000000..b9f9598ca3 --- /dev/null +++ b/spring-boot-bootstrap/src/main/java/org/baeldung/cloud/config/CloudDataSourceConfig.java @@ -0,0 +1,19 @@ +package org.baeldung.cloud.config; + +import org.springframework.cloud.config.java.AbstractCloudConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +import javax.sql.DataSource; + +@Configuration +@Profile("cloud") +public class CloudDataSourceConfig extends AbstractCloudConfig { + + @Bean + public DataSource dataSource() { + return connectionFactory().dataSource(); + } + +} diff --git a/spring-boot-bootstrap/src/main/resources/application-gcp.properties b/spring-boot-bootstrap/src/main/resources/application-gcp.properties new file mode 100644 index 0000000000..3dd11eeb8c --- /dev/null +++ b/spring-boot-bootstrap/src/main/resources/application-gcp.properties @@ -0,0 +1,3 @@ +spring.cloud.gcp.sql.instance-connection-name=baeldung-spring-boot-bootstrap:europe-west2:baeldung-spring-boot-bootstrap-db +spring.cloud.gcp.sql.database-name=baeldung_bootstrap_db +spring.cloud.gcp.logging.enabled=true \ No newline at end of file diff --git a/spring-boot-bootstrap/src/main/resources/application-local.properties b/spring-boot-bootstrap/src/main/resources/application-local.properties new file mode 100644 index 0000000000..8c1c677988 --- /dev/null +++ b/spring-boot-bootstrap/src/main/resources/application-local.properties @@ -0,0 +1,20 @@ +server.port = 8081 + +spring.application.name = Bootstrap Spring Boot + +spring.thymeleaf.cache = false +spring.thymeleaf.enabled=true +spring.thymeleaf.prefix=classpath:/templates/ +spring.thymeleaf.suffix=.html + +spring.security.user.name=john +spring.security.user.password=123 + +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:bootapp;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password= +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect + +server.error.path=/error +server.error.whitelabel.enabled=false \ No newline at end of file diff --git a/spring-boot-bootstrap/src/main/resources/application-mysql.properties b/spring-boot-bootstrap/src/main/resources/application-mysql.properties new file mode 100644 index 0000000000..a1823b5d7f --- /dev/null +++ b/spring-boot-bootstrap/src/main/resources/application-mysql.properties @@ -0,0 +1 @@ +spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect \ No newline at end of file diff --git a/spring-boot-bootstrap/src/main/resources/application.properties b/spring-boot-bootstrap/src/main/resources/application.properties index e50268d32c..d83166d843 100644 --- a/spring-boot-bootstrap/src/main/resources/application.properties +++ b/spring-boot-bootstrap/src/main/resources/application.properties @@ -1,19 +1,12 @@ -server.port = 8081 - -spring.application.name = Bootstrap Spring Boot - +server.port=${port:8080} +spring.application.name = Bootstrap Spring Cloud spring.thymeleaf.cache = false spring.thymeleaf.enabled=true spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html -spring.security.user.name=john -spring.security.user.password=123 - -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:bootapp;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.username=sa -spring.datasource.password= - server.error.path=/error -server.error.whitelabel.enabled=false \ No newline at end of file +server.error.whitelabel.enabled=false + +spring.jpa.generate-ddl=true +spring.jpa.hibernate.ddl-auto=update \ No newline at end of file diff --git a/spring-boot-bootstrap/src/main/resources/logback-gcp.xml b/spring-boot-bootstrap/src/main/resources/logback-gcp.xml new file mode 100644 index 0000000000..9a9c1c633d --- /dev/null +++ b/spring-boot-bootstrap/src/main/resources/logback-gcp.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-bootstrap/src/main/resources/logback.xml b/spring-boot-bootstrap/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-bootstrap/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-bootstrap/src/main/resources/spring-cloud-bootstrap.properties b/spring-boot-bootstrap/src/main/resources/spring-cloud-bootstrap.properties new file mode 100644 index 0000000000..6ba0b5ffcc --- /dev/null +++ b/spring-boot-bootstrap/src/main/resources/spring-cloud-bootstrap.properties @@ -0,0 +1 @@ +spring.cloud.appId=baeldung-spring-boot-bootstrap diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringCloudRestConfigIntegrationTest.java b/spring-boot-bootstrap/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 85% rename from spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringCloudRestConfigIntegrationTest.java rename to spring-boot-bootstrap/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 8cc30a32ab..9ae417a546 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringCloudRestConfigIntegrationTest.java +++ b/spring-boot-bootstrap/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -7,9 +7,9 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class SpringCloudRestConfigIntegrationTest { +public class SpringContextIntegrationTest { + @Test public void contextLoads() { } - } diff --git a/camel-api/README.md b/spring-boot-camel/README.md similarity index 100% rename from camel-api/README.md rename to spring-boot-camel/README.md diff --git a/camel-api/pom.xml b/spring-boot-camel/pom.xml similarity index 86% rename from camel-api/pom.xml rename to spring-boot-camel/pom.xml index 4e50828b96..19a0bec809 100644 --- a/camel-api/pom.xml +++ b/spring-boot-camel/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.example spring-boot-camel @@ -38,6 +38,12 @@ spring-boot-starter-web ${spring-boot-starter.version} + + org.springframework.boot + spring-boot-starter-test + ${spring-boot-starter.version} + test + @@ -60,8 +66,6 @@ - UTF-8 - 3.7.0 2.19.1 1.5.4.RELEASE diff --git a/camel-api/src/main/java/com/baeldung/camel/Application.java b/spring-boot-camel/src/main/java/com/baeldung/camel/Application.java similarity index 100% rename from camel-api/src/main/java/com/baeldung/camel/Application.java rename to spring-boot-camel/src/main/java/com/baeldung/camel/Application.java diff --git a/camel-api/src/main/java/com/baeldung/camel/ExampleServices.java b/spring-boot-camel/src/main/java/com/baeldung/camel/ExampleServices.java similarity index 100% rename from camel-api/src/main/java/com/baeldung/camel/ExampleServices.java rename to spring-boot-camel/src/main/java/com/baeldung/camel/ExampleServices.java diff --git a/camel-api/src/main/java/com/baeldung/camel/MyBean.java b/spring-boot-camel/src/main/java/com/baeldung/camel/MyBean.java similarity index 100% rename from camel-api/src/main/java/com/baeldung/camel/MyBean.java rename to spring-boot-camel/src/main/java/com/baeldung/camel/MyBean.java diff --git a/camel-api/src/main/resources/application.properties b/spring-boot-camel/src/main/resources/application.properties similarity index 100% rename from camel-api/src/main/resources/application.properties rename to spring-boot-camel/src/main/resources/application.properties diff --git a/camel-api/src/main/resources/application.yml b/spring-boot-camel/src/main/resources/application.yml similarity index 100% rename from camel-api/src/main/resources/application.yml rename to spring-boot-camel/src/main/resources/application.yml diff --git a/camel-api/src/main/resources/logback.xml b/spring-boot-camel/src/main/resources/logback.xml similarity index 100% rename from camel-api/src/main/resources/logback.xml rename to spring-boot-camel/src/main/resources/logback.xml diff --git a/spring-boot-camel/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-camel/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6eee0abf1e --- /dev/null +++ b/spring-boot-camel/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.camel.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/javaxval/bin/.gitignore b/spring-boot-client/.gitignore similarity index 78% rename from javaxval/bin/.gitignore rename to spring-boot-client/.gitignore index 55a6bcf596..da7c2c5c0a 100644 --- a/javaxval/bin/.gitignore +++ b/spring-boot-client/.gitignore @@ -1,6 +1,5 @@ +/target/ +.settings/ .classpath .project -.settings/ -target/ - diff --git a/spring-boot-client/README.MD b/spring-boot-client/README.MD new file mode 100644 index 0000000000..8db48089a5 --- /dev/null +++ b/spring-boot-client/README.MD @@ -0,0 +1,7 @@ +### The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles: + +- [Quick Guide to @RestClientTest in Spring Boot](http://www.baeldung.com/restclienttest-in-spring-boot) +- [A Java Client for a WebSockets API](http://www.baeldung.com/websockets-api-java-spring-client) \ No newline at end of file diff --git a/spring-boot-client/pom.xml b/spring-boot-client/pom.xml new file mode 100644 index 0000000000..fc89931f79 --- /dev/null +++ b/spring-boot-client/pom.xml @@ -0,0 +1,141 @@ + + 4.0.0 + com.baeldung + spring-boot-client + 0.0.1-SNAPSHOT + war + spring-boot-client + This is simple boot client application for Spring boot actuator test + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + org.junit.platform + junit-platform-launcher + ${junit-platform.version} + test + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter + + + com.google.guava + guava + ${guava.version} + + + org.springframework + spring-websocket + + + org.springframework + spring-messaging + + + + + + spring-boot-client + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-war-plugin + + + + pl.project13.maven + git-commit-id-plugin + ${git-commit-id-plugin.version} + + + + + + + + + autoconfiguration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + **/*IntegrationTest.java + **/*IntTest.java + + + **/AutoconfigurationTest.java + + + + + + + json + + + + + + + + + + 18.0 + 1.2.0 + 2.2.4 + + + \ No newline at end of file diff --git a/spring-boot-client/src/main/java/org/baeldung/boot/Application.java b/spring-boot-client/src/main/java/org/baeldung/boot/Application.java new file mode 100644 index 0000000000..c1b6558b26 --- /dev/null +++ b/spring-boot-client/src/main/java/org/baeldung/boot/Application.java @@ -0,0 +1,14 @@ +package org.baeldung.boot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; + +@SpringBootApplication +public class Application { + private static ApplicationContext applicationContext; + + public static void main(String[] args) { + applicationContext = SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot/src/main/java/org/baeldung/boot/client/Details.java b/spring-boot-client/src/main/java/org/baeldung/boot/client/Details.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/boot/client/Details.java rename to spring-boot-client/src/main/java/org/baeldung/boot/client/Details.java diff --git a/spring-boot/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java b/spring-boot-client/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java rename to spring-boot-client/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java diff --git a/spring-boot/src/main/java/org/baeldung/websocket/client/Message.java b/spring-boot-client/src/main/java/org/baeldung/websocket/client/Message.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/websocket/client/Message.java rename to spring-boot-client/src/main/java/org/baeldung/websocket/client/Message.java diff --git a/spring-boot/src/main/java/org/baeldung/websocket/client/MyStompSessionHandler.java b/spring-boot-client/src/main/java/org/baeldung/websocket/client/MyStompSessionHandler.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/websocket/client/MyStompSessionHandler.java rename to spring-boot-client/src/main/java/org/baeldung/websocket/client/MyStompSessionHandler.java diff --git a/spring-boot/src/main/java/org/baeldung/websocket/client/StompClient.java b/spring-boot-client/src/main/java/org/baeldung/websocket/client/StompClient.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/websocket/client/StompClient.java rename to spring-boot-client/src/main/java/org/baeldung/websocket/client/StompClient.java diff --git a/spring-boot-client/src/main/resources/logback.xml b/spring-boot-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..56af2d397e --- /dev/null +++ b/spring-boot-client/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot/src/test/java/com/baeldung/websocket/client/MyStompSessionHandlerIntegrationTest.java b/spring-boot-client/src/test/java/com/baeldung/websocket/client/MyStompSessionHandlerIntegrationTest.java similarity index 100% rename from spring-boot/src/test/java/com/baeldung/websocket/client/MyStompSessionHandlerIntegrationTest.java rename to spring-boot-client/src/test/java/com/baeldung/websocket/client/MyStompSessionHandlerIntegrationTest.java diff --git a/spring-boot-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..97debc5b63 --- /dev/null +++ b/spring-boot-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.boot.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java b/spring-boot-client/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java similarity index 91% rename from spring-boot/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java rename to spring-boot-client/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java index 37fc202e8a..71fb330663 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java +++ b/spring-boot-client/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java @@ -1,23 +1,24 @@ package org.baeldung.boot.client; -import com.fasterxml.jackson.databind.ObjectMapper; -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.autoconfigure.web.client.RestClientTest; -import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.client.MockRestServiceServer; - import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; -import org.baeldung.boot.client.Details; -import org.baeldung.boot.client.DetailsServiceClient; +import org.baeldung.boot.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.autoconfigure.web.client.RestClientTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.client.MockRestServiceServer; + +import com.fasterxml.jackson.databind.ObjectMapper; @RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) @RestClientTest(DetailsServiceClient.class) public class DetailsServiceClientIntegrationTest { diff --git a/spring-boot-ctx-fluent/pom.xml b/spring-boot-ctx-fluent/pom.xml index 6d767f9ef7..f9b691aea7 100644 --- a/spring-boot-ctx-fluent/pom.xml +++ b/spring-boot-ctx-fluent/pom.xml @@ -1,28 +1,24 @@ - 4.0.0 + 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 - spring-boot-ctx-fluent - 0.0.1-SNAPSHOT - jar + com.baeldung + spring-boot-ctx-fluent + 0.0.1-SNAPSHOT + jar - + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT ../parent-boot-2 - - - org.springframework.boot - spring-boot-starter-web - - - - - UTF-8 - - + + + org.springframework.boot + spring-boot-starter-web + + + diff --git a/spring-boot-ctx-fluent/src/main/resources/logback.xml b/spring-boot-ctx-fluent/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-ctx-fluent/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-ctx-fluent/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-ctx-fluent/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..c9f7220ab9 --- /dev/null +++ b/spring-boot-ctx-fluent/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,13 @@ +package org.baeldung; + +import org.junit.Test; + +import com.baeldung.parent.App; + +public class SpringContextIntegrationTest { + + @Test + public final void testMain() throws Exception { + App.main(new String[] {}); + } +} diff --git a/spring-boot-custom-starter/README.md b/spring-boot-custom-starter/README.md index 5b05394d6e..f983441ca0 100644 --- a/spring-boot-custom-starter/README.md +++ b/spring-boot-custom-starter/README.md @@ -1,2 +1,12 @@ ### Relevant Articles: - [Creating a Custom Starter with Spring Boot](http://www.baeldung.com/spring-boot-custom-starter) + +- **greeter-library**: The sample library that we're creating the starter for. + +- **greeter-spring-boot-autoconfigure**: The project containing the auto-configuration for the library. + +- **greeter-spring-boot-starter**: The custom starter for the library. + +- **greeter-spring-boot-sample-app**: The sample project that uses the custom starter. + +- [Multi-Module Project With Spring Boot](http://www.baeldung.com/spring-boot-multiple-modules) diff --git a/spring-boot-custom-starter/greeter/README.md b/spring-boot-custom-starter/greeter-library/README.md similarity index 100% rename from spring-boot-custom-starter/greeter/README.md rename to spring-boot-custom-starter/greeter-library/README.md diff --git a/spring-boot-custom-starter/greeter-library/pom.xml b/spring-boot-custom-starter/greeter-library/pom.xml new file mode 100644 index 0000000000..3717ba005c --- /dev/null +++ b/spring-boot-custom-starter/greeter-library/pom.xml @@ -0,0 +1,14 @@ + + 4.0.0 + + com.baeldung + greeter-library + 0.0.1-SNAPSHOT + + spring-boot-custom-starter + com.baeldung + 0.0.1-SNAPSHOT + ../../spring-boot-custom-starter + + \ No newline at end of file diff --git a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/Greeter.java b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/Greeter.java similarity index 90% rename from spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/Greeter.java rename to spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/Greeter.java index 970561d1fd..50fb31ddcb 100644 --- a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/Greeter.java +++ b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/Greeter.java @@ -1,6 +1,6 @@ -package com.baeldung.greeter; +package com.baeldung.greeter.library; -import static com.baeldung.greeter.GreeterConfigParams.*; +import static com.baeldung.greeter.library.GreeterConfigParams.*; import java.time.LocalDateTime; diff --git a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreeterConfigParams.java b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreeterConfigParams.java similarity index 90% rename from spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreeterConfigParams.java rename to spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreeterConfigParams.java index fa30b0f312..14cef3e92d 100644 --- a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreeterConfigParams.java +++ b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreeterConfigParams.java @@ -1,4 +1,4 @@ -package com.baeldung.greeter; +package com.baeldung.greeter.library; public class GreeterConfigParams { diff --git a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreetingConfig.java b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreetingConfig.java similarity index 80% rename from spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreetingConfig.java rename to spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreetingConfig.java index fbbe11cf4f..23d4ac0a0d 100644 --- a/spring-boot-custom-starter/greeter/src/main/java/com/baeldung/greeter/GreetingConfig.java +++ b/spring-boot-custom-starter/greeter-library/src/main/java/com/baeldung/greeter/library/GreetingConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.greeter; +package com.baeldung.greeter.library; import java.util.Properties; diff --git a/spring-boot-custom-starter/greeter-library/src/main/resources/logback.xml b/spring-boot-custom-starter/greeter-library/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-custom-starter/greeter-library/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-custom-starter/greeter/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java b/spring-boot-custom-starter/greeter-library/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java similarity index 92% rename from spring-boot-custom-starter/greeter/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java rename to spring-boot-custom-starter/greeter-library/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java index 787f795480..2b09ecc615 100644 --- a/spring-boot-custom-starter/greeter/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java +++ b/spring-boot-custom-starter/greeter-library/src/test/java/com/baeldung/greeter/GreeterIntegrationTest.java @@ -1,10 +1,12 @@ package com.baeldung.greeter; -import static com.baeldung.greeter.GreeterConfigParams.*; +import static com.baeldung.greeter.library.GreeterConfigParams.*; import static org.junit.Assert.assertEquals; import java.time.LocalDateTime; +import com.baeldung.greeter.library.Greeter; +import com.baeldung.greeter.library.GreetingConfig; import org.junit.BeforeClass; import org.junit.Test; 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 96647ea0f1..5862bdd6c8 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml +++ b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml @@ -5,17 +5,13 @@ com.baeldung greeter-spring-boot-autoconfigure 0.0.1-SNAPSHOT + - parent-boot-1 + spring-boot-custom-starter com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-1 + ../../spring-boot-custom-starter - - UTF-8 - 1.5.2.RELEASE - 0.0.1-SNAPSHOT - @@ -40,10 +36,17 @@ com.baeldung - greeter + greeter-library ${greeter.version} true + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + @@ -52,13 +55,20 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + ${maven-compiler-plugin.version} - 1.8 - 1.8 + ${java.version} + ${java.version} + + UTF-8 + 1.5.2.RELEASE + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/java/com/baeldung/greeter/autoconfigure/GreeterAutoConfiguration.java b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/java/com/baeldung/greeter/autoconfigure/GreeterAutoConfiguration.java index 4cf078aa00..ae3f88f9ff 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/java/com/baeldung/greeter/autoconfigure/GreeterAutoConfiguration.java +++ b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/java/com/baeldung/greeter/autoconfigure/GreeterAutoConfiguration.java @@ -1,6 +1,6 @@ package com.baeldung.greeter.autoconfigure; -import static com.baeldung.greeter.GreeterConfigParams.*; +import static com.baeldung.greeter.library.GreeterConfigParams.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -9,8 +9,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.baeldung.greeter.Greeter; -import com.baeldung.greeter.GreetingConfig; +import com.baeldung.greeter.library.Greeter; +import com.baeldung.greeter.library.GreetingConfig; @Configuration @ConditionalOnClass(Greeter.class) diff --git a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/resources/logback.xml b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..9c8d825ea4 --- /dev/null +++ b/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.greeter.autoconfigure.GreeterAutoConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = GreeterAutoConfiguration.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} 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 a2c96a8555..4eac7eba19 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 @@ -1,5 +1,5 @@ + 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 @@ -13,19 +13,16 @@ ../../parent-boot-1 - - 0.0.1-SNAPSHOT - - - com.baeldung greeter-spring-boot-starter ${greeter-starter.version} - + + 0.0.1-SNAPSHOT + \ No newline at end of file diff --git a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/java/com/baeldung/greeter/sample/GreeterSampleApplication.java b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/java/com/baeldung/greeter/sample/GreeterSampleApplication.java index 3c87524648..5aa3ac7015 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/java/com/baeldung/greeter/sample/GreeterSampleApplication.java +++ b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/java/com/baeldung/greeter/sample/GreeterSampleApplication.java @@ -5,7 +5,7 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import com.baeldung.greeter.Greeter; +import com.baeldung.greeter.library.Greeter; @SpringBootApplication public class GreeterSampleApplication implements CommandLineRunner { diff --git a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/resources/logback.xml b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/com/baeldung/greeter/sample/GreeterSampleApplicationIntegrationTest.java b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/com/baeldung/greeter/sample/GreeterSampleApplicationIntegrationTest.java index a4816cf319..50193ccd60 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/com/baeldung/greeter/sample/GreeterSampleApplicationIntegrationTest.java +++ b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/com/baeldung/greeter/sample/GreeterSampleApplicationIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.baeldung.greeter.Greeter; +import com.baeldung.greeter.library.Greeter; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = GreeterSampleApplication.class) diff --git a/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..23f285238b --- /dev/null +++ b/spring-boot-custom-starter/greeter-spring-boot-sample-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.greeter.sample.GreeterSampleApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = GreeterSampleApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} 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 7bf13eebc8..e71882db29 100644 --- a/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml +++ b/spring-boot-custom-starter/greeter-spring-boot-starter/pom.xml @@ -5,17 +5,13 @@ com.baeldung greeter-spring-boot-starter 0.0.1-SNAPSHOT + - parent-boot-1 + spring-boot-custom-starter com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-1 + ../../spring-boot-custom-starter - - UTF-8 - 0.0.1-SNAPSHOT - 1.5.2.RELEASE - @@ -33,7 +29,7 @@ com.baeldung - greeter + greeter-library ${greeter.version} @@ -44,13 +40,19 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + ${maven-compiler-plugin.version} - 1.8 - 1.8 + ${java.version} + ${java.version} + + UTF-8 + 0.0.1-SNAPSHOT + 1.5.2.RELEASE + + \ No newline at end of file diff --git a/spring-boot-custom-starter/greeter/pom.xml b/spring-boot-custom-starter/greeter/pom.xml index aa45b8e6a4..3cfd6da09e 100644 --- a/spring-boot-custom-starter/greeter/pom.xml +++ b/spring-boot-custom-starter/greeter/pom.xml @@ -1,5 +1,5 @@ + 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 diff --git a/spring-boot-custom-starter/pom.xml b/spring-boot-custom-starter/pom.xml index 1bc0e14d8e..b8ad8fa12c 100644 --- a/spring-boot-custom-starter/pom.xml +++ b/spring-boot-custom-starter/pom.xml @@ -1,5 +1,5 @@ + 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 spring-boot-custom-starter @@ -13,14 +13,10 @@ - greeter + greeter-library greeter-spring-boot-autoconfigure greeter-spring-boot-starter greeter-spring-boot-sample-app - - UTF-8 - - \ No newline at end of file diff --git a/spring-boot-gradle/README.md b/spring-boot-gradle/README.md index f96aa9ccf8..76b82dce02 100644 --- a/spring-boot-gradle/README.md +++ b/spring-boot-gradle/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Spring Boot: Configuring a Main Class](http://www.baeldung.com/spring-boot-main-class) +- [Thin JARs with Spring Boot](http://www.baeldung.com/spring-boot-thin-jar) diff --git a/spring-boot-gradle/src/main/resources/logback.xml b/spring-boot-gradle/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-gradle/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-h2/README.md b/spring-boot-h2/README.md new file mode 100644 index 0000000000..af5f395440 --- /dev/null +++ b/spring-boot-h2/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Access the Same In-Memory H2 Database in Multiple Spring Boot Applications](https://www.baeldung.com/spring-boot-access-h2-database-multiple-apps) diff --git a/spring-boot-h2/spring-boot-h2-database/.gitignore b/spring-boot-h2/spring-boot-h2-database/.gitignore new file mode 100644 index 0000000000..82eca336e3 --- /dev/null +++ b/spring-boot-h2/spring-boot-h2-database/.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-boot-h2/spring-boot-h2-database/pom.xml b/spring-boot-h2/spring-boot-h2-database/pom.xml new file mode 100644 index 0000000000..94f2293c34 --- /dev/null +++ b/spring-boot-h2/spring-boot-h2-database/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + com.baeldung.h2db + spring-boot-h2-database + 0.0.1-SNAPSHOT + jar + + Demo Spring Boot applications that starts H2 in memory database + + + org.springframework.boot + spring-boot-starter-parent + 2.0.4.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + com.mycorp.starter.HelloWorldApplication + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/auto/configuration/AutoConfigurationDemo.java b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/auto/configuration/AutoConfigurationDemo.java new file mode 100644 index 0000000000..8d92e18754 --- /dev/null +++ b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/auto/configuration/AutoConfigurationDemo.java @@ -0,0 +1,14 @@ +package com.baeldung.h2db.auto.configuration; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +public class AutoConfigurationDemo { + + public static void main(String[] args) { + SpringApplication.run(AutoConfigurationDemo.class, args); + } + +} diff --git a/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java new file mode 100644 index 0000000000..7402312e1c --- /dev/null +++ b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java @@ -0,0 +1,53 @@ +package com.baeldung.h2db.demo.client; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.PropertySource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +@SpringBootApplication +@ComponentScan("com.baeldung.h2db.demo.client") +public class ClientSpringBootApp { + + @Autowired + private JdbcTemplate jdbcTemplate; + + public static void main(String[] args) { + System.setProperty("spring.datasource.url","jdbc:h2:tcp://localhost:9091/mem:mydb"); + SpringApplication.run(ClientSpringBootApp.class, args); + } + + @PostConstruct + private void initDb() { + System.out.println("****** Inserting more sample data in the table: Employees ******"); + String sqlStatements[] = { + "insert into employees(first_name, last_name) values('Donald','Trump')", + "insert into employees(first_name, last_name) values('Barack','Obama')" + }; + + Arrays.asList(sqlStatements).stream().forEach(sql -> { + System.out.println(sql); + jdbcTemplate.execute(sql); + }); + + System.out.println(String.format("****** Fetching from table: %s ******", "Employees")); + jdbcTemplate.query("select id,first_name,last_name from employees", + new RowMapper() { + @Override + public Object mapRow(ResultSet rs, int i) throws SQLException { + System.out.println(String.format("id:%s,first_name:%s,last_name:%s", + rs.getString("id"), + rs.getString("first_name"), + rs.getString("last_name"))); + return null; + } + }); + } +} diff --git a/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java new file mode 100644 index 0000000000..e75b42a934 --- /dev/null +++ b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java @@ -0,0 +1,61 @@ +package com.baeldung.h2db.demo.server; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import javax.annotation.PostConstruct; +import org.h2.tools.Server; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +@SpringBootApplication +@ComponentScan("com.baeldung.h2db.demo.server") +public class SpringBootApp { + + @Autowired + private JdbcTemplate jdbcTemplate; + + public static void main(String[] args) { + SpringApplication.run(SpringBootApp.class, args); + } + + @PostConstruct + private void initDb() { + System.out.println(String.format("****** Creating table: %s, and Inserting test data ******", "Employees")); + + String sqlStatements[] = { + "drop table employees if exists", + "create table employees(id serial,first_name varchar(255),last_name varchar(255))", + "insert into employees(first_name, last_name) values('Eugen','Paraschiv')", + "insert into employees(first_name, last_name) values('Scott','Tiger')" + }; + + Arrays.asList(sqlStatements).stream().forEach(sql -> { + System.out.println(sql); + jdbcTemplate.execute(sql); + }); + + System.out.println(String.format("****** Fetching from table: %s ******", "Employees")); + jdbcTemplate.query("select id,first_name,last_name from employees", + new RowMapper() { + @Override + public Object mapRow(ResultSet rs, int i) throws SQLException { + System.out.println(String.format("id:%s,first_name:%s,last_name:%s", + rs.getString("id"), + rs.getString("first_name"), + rs.getString("last_name"))); + return null; + } + }); + } + + @Bean(initMethod = "start", destroyMethod = "stop") + public Server inMemoryH2DatabaseServer() throws SQLException { + return Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9091"); + } +} diff --git a/spring-boot-h2/spring-boot-h2-database/src/main/resources/application.properties b/spring-boot-h2/spring-boot-h2-database/src/main/resources/application.properties new file mode 100644 index 0000000000..5e425a3550 --- /dev/null +++ b/spring-boot-h2/spring-boot-h2-database/src/main/resources/application.properties @@ -0,0 +1,8 @@ +spring.datasource.url=jdbc:h2:mem:mydb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= +spring.jpa.hibernate.ddl-auto=create +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console +debug=true \ No newline at end of file diff --git a/spring-boot-h2/spring-boot-h2-remote-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-h2/spring-boot-h2-remote-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..f48199d4e8 --- /dev/null +++ b/spring-boot-h2/spring-boot-h2-remote-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.h2db.demo.ClientSpringBootApp; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ClientSpringBootApp.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-jasypt/pom.xml b/spring-boot-jasypt/pom.xml index e094f0b061..de0df92678 100644 --- a/spring-boot-jasypt/pom.xml +++ b/spring-boot-jasypt/pom.xml @@ -4,26 +4,18 @@ 4.0.0 com.example.jasypt - JasyptDemo - 0.0.1-SNAPSHOT + spring-boot-jasypt jar - - JasyptDemo + spring-boot-jasypt Demo project for Spring Boot - org.springframework.boot - spring-boot-starter-parent - 2.0.1.RELEASE - + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 - - UTF-8 - UTF-8 - 1.8 - - org.springframework.boot @@ -35,17 +27,17 @@ spring-boot-starter-test test - + com.github.ulisesbocchio jasypt-spring-boot-starter - 2.0.0 + ${jasypt.version} com.github.ulisesbocchio jasypt-spring-boot - 2.0.0 + ${jasypt.version} @@ -57,4 +49,9 @@ + + + 2.0.0 + + diff --git a/spring-boot-jasypt/src/main/resources/logback.xml b/spring-boot-jasypt/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-jasypt/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptIntegrationTest.java similarity index 94% rename from spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java rename to spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptIntegrationTest.java index 58c2dc7bb2..c24cfe6efa 100644 --- a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptIntegrationTest.java @@ -14,7 +14,7 @@ import com.baeldung.jasypt.Main; @RunWith(SpringRunner.class) @SpringBootTest(classes = {Main.class}) -public class CustomJasyptTest { +public class CustomJasyptIntegrationTest { @Autowired ApplicationContext appCtx; diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleIntegrationTest.java similarity index 95% rename from spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java rename to spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleIntegrationTest.java index f9b66b5044..e8dda73b4a 100644 --- a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleIntegrationTest.java @@ -13,7 +13,7 @@ import com.baeldung.jasypt.simple.PropertyServiceForJasyptSimple; @RunWith(SpringRunner.class) @SpringBootTest -public class JasyptSimpleTest { +public class JasyptSimpleIntegrationTest { @Autowired ApplicationContext appCtx; diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterIntegrationTest.java similarity index 95% rename from spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java rename to spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterIntegrationTest.java index d246c21036..5f5d409ab9 100644 --- a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterIntegrationTest.java @@ -14,7 +14,7 @@ import com.baeldung.jasypt.starter.PropertyServiceForJasyptStarter; @RunWith(SpringRunner.class) @SpringBootTest -public class JasyptWithStarterTest { +public class JasyptWithStarterIntegrationTest { @Autowired ApplicationContext appCtx; diff --git a/spring-boot-jasypt/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-jasypt/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..dce3819a26 --- /dev/null +++ b/spring-boot-jasypt/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.jasypt.Main; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Main.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-keycloak/pom.xml b/spring-boot-keycloak/pom.xml index b7b15935ec..3a39d4aa94 100644 --- a/spring-boot-keycloak/pom.xml +++ b/spring-boot-keycloak/pom.xml @@ -1,6 +1,6 @@ + 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.keycloak spring-boot-keycloak @@ -75,8 +75,6 @@ - UTF-8 - UTF-8 3.3.0.Final diff --git a/spring-boot-keycloak/src/main/resources/logback.xml b/spring-boot-keycloak/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-keycloak/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-keycloak/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-keycloak/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7367568611 --- /dev/null +++ b/spring-boot-keycloak/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.keycloak.SpringBoot; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBoot.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-logging-log4j2/README.md b/spring-boot-logging-log4j2/README.md new file mode 100644 index 0000000000..305957ed8d --- /dev/null +++ b/spring-boot-logging-log4j2/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [Logging in Spring Boot](http://www.baeldung.com/spring-boot-logging) +- [How to Disable Console Logging in Spring Boot](https://www.baeldung.com/spring-boot-disable-console-logging) diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/pom.xml b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/pom.xml new file mode 100644 index 0000000000..c3bad74352 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + disabling-console-jul + + + com.baeldung + disabling-console-logging + 0.0.1-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.slf4j + jul-to-slf4j + + + org.slf4j + slf4j-simple + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/java/com/baeldung/springbootlogging/disablingconsole/jul/properties/DisablingConsoleJulApp.java b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/java/com/baeldung/springbootlogging/disablingconsole/jul/properties/DisablingConsoleJulApp.java new file mode 100644 index 0000000000..c9187e9ace --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/java/com/baeldung/springbootlogging/disablingconsole/jul/properties/DisablingConsoleJulApp.java @@ -0,0 +1,11 @@ +package com.baeldung.springbootlogging.disablingconsole.jul.properties; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DisablingConsoleJulApp { + public static void main(String[] args) { + SpringApplication.run(DisablingConsoleJulApp.class, args); + } +} diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/java/com/baeldung/springbootlogging/disablingconsole/jul/properties/controllers/DisabledConsoleRestController.java b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/java/com/baeldung/springbootlogging/disablingconsole/jul/properties/controllers/DisabledConsoleRestController.java new file mode 100644 index 0000000000..e33089ed36 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/java/com/baeldung/springbootlogging/disablingconsole/jul/properties/controllers/DisabledConsoleRestController.java @@ -0,0 +1,19 @@ +package com.baeldung.springbootlogging.disablingconsole.jul.properties.controllers; + +import java.time.LocalTime; +import java.util.logging.Logger; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DisabledConsoleRestController { + + private static final Logger LOG = Logger.getLogger(DisabledConsoleRestController.class.getName()); + + @GetMapping("/disabled-console-jul-properties") + public String logTime() { + LOG.info("Current time: " + LocalTime.now()); + return "finished!"; + } +} diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/resources/application.properties b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/resources/application.properties new file mode 100644 index 0000000000..d81eed95d3 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/resources/application.properties @@ -0,0 +1 @@ +logging.file=true \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/resources/logging.properties b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/resources/logging.properties new file mode 100644 index 0000000000..0136354868 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/src/main/resources/logging.properties @@ -0,0 +1,4 @@ +handlers= java.util.logging.FileHandler + +java.util.logging.FileHandler.pattern=baeldung.log +java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/pom.xml b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/pom.xml new file mode 100644 index 0000000000..f9b34ec7d9 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/pom.xml @@ -0,0 +1,42 @@ + + 4.0.0 + disabling-console-log4j2 + + + com.baeldung + disabling-console-logging + 0.0.1-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/java/com/baeldung/springbootlogging/disablingconsole/log4j2/xml/DisablingConsoleLog4j2App.java b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/java/com/baeldung/springbootlogging/disablingconsole/log4j2/xml/DisablingConsoleLog4j2App.java new file mode 100644 index 0000000000..ae59f3b3e1 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/java/com/baeldung/springbootlogging/disablingconsole/log4j2/xml/DisablingConsoleLog4j2App.java @@ -0,0 +1,11 @@ +package com.baeldung.springbootlogging.disablingconsole.log4j2.xml; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DisablingConsoleLog4j2App { + public static void main(String[] args) { + SpringApplication.run(DisablingConsoleLog4j2App.class, args); + } +} diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/java/com/baeldung/springbootlogging/disablingconsole/log4j2/xml/controllers/DisabledConsoleRestController.java b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/java/com/baeldung/springbootlogging/disablingconsole/log4j2/xml/controllers/DisabledConsoleRestController.java new file mode 100644 index 0000000000..f6485b63d4 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/java/com/baeldung/springbootlogging/disablingconsole/log4j2/xml/controllers/DisabledConsoleRestController.java @@ -0,0 +1,20 @@ +package com.baeldung.springbootlogging.disablingconsole.log4j2.xml.controllers; + +import java.time.LocalTime; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DisabledConsoleRestController { + + private static final Logger LOG = LoggerFactory.getLogger(DisabledConsoleRestController.class); + + @GetMapping("/disabled-console-log4j2-xml") + public String logTime() { + LOG.info("Current time: {}", LocalTime.now()); + return "finished!"; + } +} diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/resources/log4j2.xml b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..20975f40d9 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/src/main/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/pom.xml b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/pom.xml new file mode 100644 index 0000000000..6f2170390b --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/pom.xml @@ -0,0 +1,9 @@ + + 4.0.0 + + com.baeldung + disabling-console-logging + 0.0.1-SNAPSHOT + + disabling-console-logback + \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/java/com/baeldung/springbootlogging/disablingconsole/logback/xml/DisablingConsoleLogbackApp.java b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/java/com/baeldung/springbootlogging/disablingconsole/logback/xml/DisablingConsoleLogbackApp.java new file mode 100644 index 0000000000..9b38d42477 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/java/com/baeldung/springbootlogging/disablingconsole/logback/xml/DisablingConsoleLogbackApp.java @@ -0,0 +1,11 @@ +package com.baeldung.springbootlogging.disablingconsole.logback.xml; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DisablingConsoleLogbackApp { + public static void main(String[] args) { + SpringApplication.run(DisablingConsoleLogbackApp.class, args); + } +} diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/java/com/baeldung/springbootlogging/disablingconsole/logback/xml/controllers/DisabledConsoleRestController.java b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/java/com/baeldung/springbootlogging/disablingconsole/logback/xml/controllers/DisabledConsoleRestController.java new file mode 100644 index 0000000000..e1d6b1d45e --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/java/com/baeldung/springbootlogging/disablingconsole/logback/xml/controllers/DisabledConsoleRestController.java @@ -0,0 +1,20 @@ +package com.baeldung.springbootlogging.disablingconsole.logback.xml.controllers; + +import java.time.LocalTime; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DisabledConsoleRestController { + + private static final Logger LOG = LoggerFactory.getLogger(DisabledConsoleRestController.class); + + @GetMapping("/disabled-console-logback-xml") + public String logTime() { + LOG.info("Current time: {}", LocalTime.now()); + return "finished!"; + } +} diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/resources/application.properties b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/resources/application.properties new file mode 100644 index 0000000000..70c2f97194 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/resources/application.properties @@ -0,0 +1,7 @@ +logging.file=disabled-console.log + +### we could potentially 'disable' console logging by setting a blank log pattern: +#logging.pattern.console= + +### or disable the logs completely by setting the root logging level as 'OFF': +#logging.level.root=OFF diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/resources/logback-spring.xml b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/resources/logback-spring.xml new file mode 100644 index 0000000000..5c751e994f --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-logback/src/main/resources/logback-spring.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/pom.xml b/spring-boot-logging-log4j2/disabling-console-logging/pom.xml new file mode 100644 index 0000000000..39a4a40f12 --- /dev/null +++ b/spring-boot-logging-log4j2/disabling-console-logging/pom.xml @@ -0,0 +1,19 @@ + + 4.0.0 + disabling-console-logging + pom + Projects for Disabling Spring Boot Console Logging tutorials + + + com.baeldung + spring-boot-logging-log4j2 + 0.0.1-SNAPSHOT + + + + disabling-console-logback + disabling-console-log4j2 + disabling-console-jul + + \ No newline at end of file diff --git a/spring-boot-logging-log4j2/pom.xml b/spring-boot-logging-log4j2/pom.xml index c07c157eee..7caf1e8690 100644 --- a/spring-boot-logging-log4j2/pom.xml +++ b/spring-boot-logging-log4j2/pom.xml @@ -1,42 +1,23 @@ - 4.0.0 - com.baeldung spring-boot-logging-log4j2 - 0.0.1-SNAPSHOT - jar - Demo project for Spring Boot Logging with Log4J2 + pom + Projects for Spring Boot Logging tutorials - org.springframework.boot - spring-boot-starter-parent - 2.0.3.RELEASE - + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 - - UTF-8 - UTF-8 - 1.8 - - org.springframework.boot spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-logging - - - - - org.springframework.boot - spring-boot-starter-log4j2 @@ -45,6 +26,11 @@ test + + + spring-boot-logging-log4j2-app + disabling-console-logging + diff --git a/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/pom.xml b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/pom.xml new file mode 100644 index 0000000000..571794167e --- /dev/null +++ b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + spring-boot-logging-log4j2-app + jar + Demo project for Spring Boot Logging with Log4J2 + + + spring-boot-logging-log4j2 + com.baeldung + 0.0.1-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + diff --git a/spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/LoggingController.java b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/main/java/com/baeldung/springbootlogging/LoggingController.java similarity index 100% rename from spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/LoggingController.java rename to spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/main/java/com/baeldung/springbootlogging/LoggingController.java diff --git a/spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/SpringBootLoggingApplication.java b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/main/java/com/baeldung/springbootlogging/SpringBootLoggingApplication.java similarity index 100% rename from spring-boot-logging-log4j2/src/main/java/com/baeldung/springbootlogging/SpringBootLoggingApplication.java rename to spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/main/java/com/baeldung/springbootlogging/SpringBootLoggingApplication.java diff --git a/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/main/resources/application.properties b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-logging-log4j2/src/main/resources/log4j2-spring.xml b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/main/resources/log4j2-spring.xml similarity index 100% rename from spring-boot-logging-log4j2/src/main/resources/log4j2-spring.xml rename to spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/main/resources/log4j2-spring.xml diff --git a/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2d46b21ba5 --- /dev/null +++ b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springbootlogging.SpringBootLoggingApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootLoggingApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-mvc/README.md b/spring-boot-mvc/README.md new file mode 100644 index 0000000000..b46dbe3bae --- /dev/null +++ b/spring-boot-mvc/README.md @@ -0,0 +1,10 @@ +### Relevant Articles: + +- [Guide to the Favicon in Spring Boot](http://www.baeldung.com/spring-boot-favicon) +- [Custom Validation MessageSource in Spring Boot](https://www.baeldung.com/spring-custom-validation-message-source) +- [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) +- [Display RSS Feed with Spring MVC](http://www.baeldung.com/spring-mvc-rss-feed) + diff --git a/spring-boot-mvc/pom.xml b/spring-boot-mvc/pom.xml index 81968973f8..65d23ebfc6 100644 --- a/spring-boot-mvc/pom.xml +++ b/spring-boot-mvc/pom.xml @@ -2,39 +2,51 @@ 4.0.0 - - com.baeldung spring-boot-mvc - 0.0.1-SNAPSHOT jar - spring-boot-mvc - Demo project for Spring Boot + Module For Spring Boot MVC - org.springframework.boot - spring-boot-starter-parent - 2.0.2.RELEASE - - - - - UTF-8 - UTF-8 - 1.8 - + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + org.springframework.boot spring-boot-starter-web + + org.apache.tomcat.embed + tomcat-embed-jasper + + + + org.glassfish + javax.faces + 2.3.7 + org.springframework.boot spring-boot-starter-test test + + + org.springframework.boot + spring-boot-starter-validation + + + + + com.rometools + rome + ${rome.version} + @@ -42,9 +54,18 @@ org.springframework.boot spring-boot-maven-plugin + + com.baeldung.springbootmvc.SpringBootMvcApplication + JAR + + + + 1.10.0 + com.baeldung.springbootmvc.SpringBootMvcApplication + diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Bike.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/Bike.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/Bike.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/Bike.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Biker.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/Biker.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/Biker.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/Biker.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Car.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/Car.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/Car.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/Car.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/CarMechanic.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/CarMechanic.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/CarMechanic.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/CarMechanic.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/CarUtility.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/CarUtility.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/CarUtility.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/CarUtility.java diff --git a/spring-boot-mvc/src/main/java/com/baeldung/annotations/CustomException.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/CustomException.java new file mode 100644 index 0000000000..4502a45301 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/annotations/CustomException.java @@ -0,0 +1,8 @@ +package com.baeldung.annotations; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.BAD_REQUEST) +public class CustomException extends RuntimeException { +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/CustomResponseController.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/CustomResponseController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/CustomResponseController.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/CustomResponseController.java diff --git a/spring-boot-mvc/src/main/java/com/baeldung/annotations/CustomResponseWithBuilderController.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/CustomResponseWithBuilderController.java new file mode 100644 index 0000000000..9a77029128 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/annotations/CustomResponseWithBuilderController.java @@ -0,0 +1,52 @@ +package com.baeldung.annotations; + +import java.time.Year; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +@RequestMapping("/customResponseWithBuilder") +public class CustomResponseWithBuilderController { + + @GetMapping("/hello") + public ResponseEntity hello() { + return ResponseEntity.ok("Hello World!"); + } + + @GetMapping("/age") + public ResponseEntity age(@RequestParam("yearOfBirth") int yearOfBirth) { + if (isInFuture(yearOfBirth)) { + return ResponseEntity.badRequest() + .body("Year of birth cannot be in the future"); + } + + return ResponseEntity.status(HttpStatus.OK) + .body("Your age is " + calculateAge(yearOfBirth)); + } + + private int calculateAge(int yearOfBirth) { + return currentYear() - yearOfBirth; + } + + private boolean isInFuture(int year) { + return currentYear() < year; + } + + private int currentYear() { + return Year.now() + .getValue(); + } + + @GetMapping("/customHeader") + public ResponseEntity customHeader() { + return ResponseEntity.ok() + .header("Custom-Header", "foo") + .body("Custom header set"); + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Driver.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/Driver.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/Driver.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/Driver.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Engine.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/Engine.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/Engine.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/Engine.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Vehicle.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/Vehicle.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/Vehicle.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/Vehicle.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleController.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleController.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleController.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryApplication.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleFactoryApplication.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryApplication.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleFactoryApplication.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryConfig.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleFactoryConfig.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryConfig.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleFactoryConfig.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRepository.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleRepository.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRepository.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleRepository.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRestController.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleRestController.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRestController.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleRestController.java diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleService.java b/spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleService.java similarity index 100% rename from spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleService.java rename to spring-boot-mvc/src/main/java/com/baeldung/annotations/VehicleService.java diff --git a/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanA.java b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanA.java new file mode 100644 index 0000000000..030216b747 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanA.java @@ -0,0 +1,12 @@ +package com.baeldung.nosuchbeandefinitionexception; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class BeanA { + + @Autowired + BeanB dependency; + +} \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanB.java b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanB.java new file mode 100644 index 0000000000..f0cc263504 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanB.java @@ -0,0 +1,5 @@ +package com.baeldung.nosuchbeandefinitionexception; + +public class BeanB { + +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/NoSuchBeanDefinitionDemoApp.java b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/NoSuchBeanDefinitionDemoApp.java new file mode 100644 index 0000000000..8709cf85ac --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/NoSuchBeanDefinitionDemoApp.java @@ -0,0 +1,12 @@ +package com.baeldung.nosuchbeandefinitionexception; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class NoSuchBeanDefinitionDemoApp { + + public static void main(String[] args) { + SpringApplication.run(NoSuchBeanDefinitionDemoApp.class, args); + } +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedApplication.java b/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedApplication.java new file mode 100644 index 0000000000..0f9de840d5 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedApplication.java @@ -0,0 +1,23 @@ +package com.baeldung.rss; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Spring Boot launcher for an application which exposes an RSS Feed. + * + * @author Donato Rimenti + * + */ +@SpringBootApplication +public class RssFeedApplication { + + /** + * Launches a Spring Boot application which exposes an RSS Feed. + * + * @param args null + */ + public static void main(final String[] args) { + SpringApplication.run(RssFeedApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedController.java b/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedController.java new file mode 100644 index 0000000000..9d4e36dd5f --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedController.java @@ -0,0 +1,32 @@ +package com.baeldung.rss; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.View; + +/** + * REST Controller which returns an RSS Feed created by {@link RssFeedView}. + * + * @author Donato Rimenti + * + */ +@RestController +public class RssFeedController { + + /** + * View used by this controller. + */ + @Autowired + private RssFeedView view; + + /** + * Returns an RSS Feed created by {@link #view}. + * + * @return an RSS Feed + */ + @GetMapping("/rss") + public View getFeed() { + return view; + } +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedView.java b/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedView.java new file mode 100644 index 0000000000..c9b9c51bec --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/rss/RssFeedView.java @@ -0,0 +1,98 @@ +package com.baeldung.rss; + +import java.sql.Date; +import java.time.Instant; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.view.feed.AbstractRssFeedView; + +import com.rometools.rome.feed.rss.Channel; +import com.rometools.rome.feed.rss.Item; + +/** + * View for a RSS feed. + * + * @author Donato Rimenti + */ +@Component +public class RssFeedView extends AbstractRssFeedView { + + /* + * (non-Javadoc) + * + * @see org.springframework.web.servlet.view.feed.AbstractFeedView# + * buildFeedMetadata(java.util.Map, com.rometools.rome.feed.WireFeed, + * javax.servlet.http.HttpServletRequest) + */ + @Override + protected void buildFeedMetadata(Map model, Channel feed, HttpServletRequest request) { + feed.setTitle("Baeldung RSS Feed"); + feed.setDescription("Learn how to program in Java"); + feed.setLink("http://www.baeldung.com"); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.web.servlet.view.feed.AbstractRssFeedView# + * buildFeedItems(java.util.Map, javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected List buildFeedItems(Map model, HttpServletRequest request, + HttpServletResponse response) { + + // Builds the single entries. + Item entryOne = new Item(); + entryOne.setTitle("JUnit 5 @Test Annotation"); + entryOne.setAuthor("donatohan.rimenti@gmail.com"); + entryOne.setLink("http://www.baeldung.com/junit-5-test-annotation"); + entryOne.setPubDate(Date.from(Instant.parse("2017-12-19T00:00:00Z"))); + + Item entryTwo = new Item(); + entryTwo.setTitle("Creating and Configuring Jetty 9 Server in Java"); + entryTwo.setAuthor("donatohan.rimenti@gmail.com"); + entryTwo.setLink("http://www.baeldung.com/jetty-java-programmatic"); + entryTwo.setPubDate(Date.from(Instant.parse("2018-01-23T00:00:00Z"))); + + Item entryThree = new Item(); + entryThree.setTitle("Flyweight Pattern in Java"); + entryThree.setAuthor("donatohan.rimenti@gmail.com"); + entryThree.setLink("http://www.baeldung.com/java-flyweight"); + entryThree.setPubDate(Date.from(Instant.parse("2018-02-01T00:00:00Z"))); + + Item entryFour = new Item(); + entryFour.setTitle("Multi-Swarm Optimization Algorithm in Java"); + entryFour.setAuthor("donatohan.rimenti@gmail.com"); + entryFour.setLink("http://www.baeldung.com/java-multi-swarm-algorithm"); + entryFour.setPubDate(Date.from(Instant.parse("2018-03-09T00:00:00Z"))); + + Item entryFive = new Item(); + entryFive.setTitle("A Simple Tagging Implementation with MongoDB"); + entryFive.setAuthor("donatohan.rimenti@gmail.com"); + entryFive.setLink("http://www.baeldung.com/mongodb-tagging"); + entryFive.setPubDate(Date.from(Instant.parse("2018-03-27T00:00:00Z"))); + + Item entrySix = new Item(); + entrySix.setTitle("Double-Checked Locking with Singleton"); + entrySix.setAuthor("donatohan.rimenti@gmail.com"); + entrySix.setLink("http://www.baeldung.com/java-singleton-double-checked-locking"); + entrySix.setPubDate(Date.from(Instant.parse("2018-04-23T00:00:00Z"))); + + Item entrySeven = new Item(); + entrySeven.setTitle("Introduction to Dagger 2"); + entrySeven.setAuthor("donatohan.rimenti@gmail.com"); + entrySeven.setLink("http://www.baeldung.com/dagger-2"); + entrySeven.setPubDate(Date.from(Instant.parse("2018-06-30T00:00:00Z"))); + + // Creates the feed. + return Arrays.asList(entryOne, entryTwo, entryThree, entryFour, entryFive, entrySix, entrySeven); + } + +} \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoginController.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoginController.java new file mode 100644 index 0000000000..589024c0bc --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/LoginController.java @@ -0,0 +1,20 @@ +package com.baeldung.springbootmvc; + +import javax.validation.Valid; + +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.springbootmvc.model.LoginForm; + +@RestController +@RequestMapping("/") +public class LoginController { + + @PostMapping("loginform") + public String processLogin(@Valid LoginForm form) { + return "Success"; + + } +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/SpringBootMvcApplication.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/SpringBootMvcApplication.java index c4213af0a3..df8f72f500 100644 --- a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/SpringBootMvcApplication.java +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/SpringBootMvcApplication.java @@ -2,12 +2,11 @@ package com.baeldung.springbootmvc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; @SpringBootApplication public class SpringBootMvcApplication { - public static void main(String[] args) { - SpringApplication.run(SpringBootMvcApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(SpringBootMvcApplication.class, args); + } } diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/config/CustomMessageSourceConfiguration.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/config/CustomMessageSourceConfiguration.java new file mode 100644 index 0000000000..e83f15a366 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/config/CustomMessageSourceConfiguration.java @@ -0,0 +1,27 @@ +package com.baeldung.springbootmvc.config; + +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; + +@Configuration +public class CustomMessageSourceConfiguration { + + @Bean + public MessageSource messageSource() { + ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); + messageSource.setBasename("classpath:messages"); + messageSource.setDefaultEncoding("UTF-8"); + return messageSource; + } + + @Bean + public LocalValidatorFactoryBean getValidator() { + LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean(); + bean.setValidationMessageSource(messageSource()); + return bean; + } + +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/config/FaviconConfiguration.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/config/FaviconConfiguration.java index 1ee13ccec2..9a1f47b5cb 100644 --- a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/config/FaviconConfiguration.java +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/config/FaviconConfiguration.java @@ -32,12 +32,13 @@ public class FaviconConfiguration { requestHandler.setLocations(locations); return requestHandler; } - - //@Controller + + // @Controller static class FaviconController { - - @RequestMapping(value="favicon.ico", method=RequestMethod.GET) + + @RequestMapping(value = "favicon.ico", method = RequestMethod.GET) @ResponseBody - void favicon() {} + void favicon() { + } } } diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java new file mode 100644 index 0000000000..5b4250d5e3 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java @@ -0,0 +1,31 @@ +package com.baeldung.springbootmvc.jsfapplication; + +import javax.faces.webapp.FacesServlet; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +import com.baeldung.springbootmvc.jsfapplication.controller.JsfController; +import com.baeldung.springbootmvc.jsfapplication.model.TodoDao; +import com.baeldung.springbootmvc.jsfapplication.service.TodoService; + +@SpringBootApplication +@ComponentScan(basePackageClasses = { JsfController.class, TodoDao.class, TodoService.class }) +public class JsfApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(JsfApplication.class, args); + } + + @Bean + public ServletRegistrationBean servletRegistrationBean() { + FacesServlet servlet = new FacesServlet(); + ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "*.jsf"); + return servletRegistrationBean; + } + +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/controller/JsfController.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/controller/JsfController.java new file mode 100644 index 0000000000..a9d21175c7 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/controller/JsfController.java @@ -0,0 +1,19 @@ +package com.baeldung.springbootmvc.jsfapplication.controller; + +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Scope(value = "session") +@Component(value = "jsfController") +public class JsfController { + + public String loadTodoPage() { + checkPermission(); + return "/todo.xhtml"; + } + + private void checkPermission() { + // Details omitted + } + +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Dao.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Dao.java new file mode 100644 index 0000000000..0b97c5a78e --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Dao.java @@ -0,0 +1,17 @@ +package com.baeldung.springbootmvc.jsfapplication.model; + +import java.util.Collection; +import java.util.Optional; + +public interface Dao { + + Optional get(int id); + + Collection getAll(); + + int save(T t); + + void update(T t); + + void delete(T t); +} \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Todo.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Todo.java new file mode 100644 index 0000000000..7aa8480f43 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Todo.java @@ -0,0 +1,32 @@ +package com.baeldung.springbootmvc.jsfapplication.model; + +public class Todo { + + private int id; + private String message; + private int priority; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/TodoDao.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/TodoDao.java new file mode 100644 index 0000000000..96d44474af --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/TodoDao.java @@ -0,0 +1,48 @@ +package com.baeldung.springbootmvc.jsfapplication.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Component; + +@Component +public class TodoDao implements Dao { + + private List todoList = new ArrayList<>(); + + @Override + public Optional get(int id) { + return Optional.ofNullable(todoList.get(id)); + } + + @Override + public Collection getAll() { + return todoList.stream() + .filter(Objects::nonNull) + .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)); + } + + @Override + public int save(Todo todo) { + todoList.add(todo); + int index = todoList.size() - 1; + todo.setId(index); + return index; + } + + @Override + public void update(Todo todo) { + todoList.set(todo.getId(), todo); + } + + @Override + public void delete(Todo todo) { + todoList.set(todo.getId(), null); + } + +} \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/service/TodoService.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/service/TodoService.java new file mode 100644 index 0000000000..89af3c66b9 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/service/TodoService.java @@ -0,0 +1,50 @@ +package com.baeldung.springbootmvc.jsfapplication.service; + +import java.util.Collection; +import java.util.Comparator; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.baeldung.springbootmvc.jsfapplication.model.Dao; +import com.baeldung.springbootmvc.jsfapplication.model.Todo; + +@Scope(value = "session") +@Component(value = "todoService") +public class TodoService { + + @Autowired + private Dao todoDao; + private Todo todo = new Todo(); + + public void save() { + todoDao.save(todo); + todo = new Todo(); + } + + public Collection getAllTodo() { + return todoDao.getAll(); + } + + public Collection getAllTodoSortedByPriority() { + return todoDao.getAll() + .stream() + .sorted(Comparator.comparingInt(Todo::getId)) + .collect(Collectors.toList()); + } + + public int saveTodo(Todo todo) { + validate(todo); + return todoDao.save(todo); + } + + private void validate(Todo todo) { + // Details omitted + } + + public Todo getTodo() { + return todo; + } +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/model/LoginForm.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/model/LoginForm.java new file mode 100644 index 0000000000..107cd1bbf1 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/model/LoginForm.java @@ -0,0 +1,32 @@ +package com.baeldung.springbootmvc.model; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +public class LoginForm { + + @NotEmpty(message = "{email.notempty}") + @Email + private String email; + + @NotNull + private String password; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/spring-boot-mvc/src/main/resources/logback.xml b/spring-boot-mvc/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-mvc/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-mvc/src/main/resources/messages.properties b/spring-boot-mvc/src/main/resources/messages.properties new file mode 100644 index 0000000000..9794c89651 --- /dev/null +++ b/spring-boot-mvc/src/main/resources/messages.properties @@ -0,0 +1 @@ +email.notempty=Please provide valid email id. \ No newline at end of file diff --git a/spring-boot-mvc/src/main/resources/messages_fr.properties b/spring-boot-mvc/src/main/resources/messages_fr.properties new file mode 100644 index 0000000000..070f4e0bfc --- /dev/null +++ b/spring-boot-mvc/src/main/resources/messages_fr.properties @@ -0,0 +1 @@ +email.notempty=Veuillez fournir un identifiant de messagerie valide. \ No newline at end of file diff --git a/spring-boot-mvc/src/main/webapp/WEB-INF/faces-config.xml b/spring-boot-mvc/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 0000000000..9e31a2e09d --- /dev/null +++ b/spring-boot-mvc/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,9 @@ + + + + org.springframework.web.jsf.el.SpringBeanFacesELResolver + + \ No newline at end of file diff --git a/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml b/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..e0cd4d8850 --- /dev/null +++ b/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,21 @@ + + + + + Faces Servlet + javax.faces.webapp.FacesServlet + 1 + + + Faces Servlet + *.jsf + + + com.sun.faces.forceLoadConfiguration + true + + \ No newline at end of file diff --git a/spring-boot-mvc/src/main/webapp/index.xhtml b/spring-boot-mvc/src/main/webapp/index.xhtml new file mode 100644 index 0000000000..40042b812c --- /dev/null +++ b/spring-boot-mvc/src/main/webapp/index.xhtml @@ -0,0 +1,20 @@ + + + + + TO-DO application + + +
    +

    Welcome in the TO-DO application!

    +

    + This is a static message rendered from xhtml. + + + +

    +
    +
    +
    \ No newline at end of file diff --git a/spring-boot-mvc/src/main/webapp/todo.xhtml b/spring-boot-mvc/src/main/webapp/todo.xhtml new file mode 100644 index 0000000000..426e101908 --- /dev/null +++ b/spring-boot-mvc/src/main/webapp/todo.xhtml @@ -0,0 +1,38 @@ + + + + + TO-DO application + + +
    +
    + List of TO-DO items +
    + + + Message + #{item.message} + + + Priority + #{item.priority} + + +
    +
    +
    + Add new to-do item: +
    + + + + + + + +
    +
    +
    \ No newline at end of file diff --git a/spring-boot-mvc/src/test/java/com/baeldung/rss/RssFeedUnitTest.java b/spring-boot-mvc/src/test/java/com/baeldung/rss/RssFeedUnitTest.java new file mode 100644 index 0000000000..f5524c36fe --- /dev/null +++ b/spring-boot-mvc/src/test/java/com/baeldung/rss/RssFeedUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.rss; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +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.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +/** + * Test for {@link RssFeedApplication}. + * + * @author Donato Rimenti + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = RssFeedApplication.class) +public class RssFeedUnitTest { + + /** + * Application context. + */ + @Autowired + private WebApplicationContext context; + + /** + * Mock to perform tests on Spring Web Controller. + */ + private MockMvc mvc; + + /** + * Sets the test up. + */ + @Before + public void setup() { + mvc = MockMvcBuilders.webAppContextSetup(context).build(); + } + + /** + * Calls the RSS feed endpoint and checks that the result matches an + * expected one. + * + * @throws Exception + */ + @Test + public void givenRssFeed_whenComparedWithExisting_thenEquals() throws Exception { + // The expected response. + String expectedResult = " Baeldung RSS Feed http://www.baeldung.com Learn how to program in Java JUnit 5 @Test Annotation http://www.baeldung.com/junit-5-test-annotation Tue, 19 Dec 2017 00:00:00 GMT donatohan.rimenti@gmail.com Creating and Configuring Jetty 9 Server in Java http://www.baeldung.com/jetty-java-programmatic Tue, 23 Jan 2018 00:00:00 GMT donatohan.rimenti@gmail.com Flyweight Pattern in Java http://www.baeldung.com/java-flyweight Thu, 01 Feb 2018 00:00:00 GMT donatohan.rimenti@gmail.com Multi-Swarm Optimization Algorithm in Java http://www.baeldung.com/java-multi-swarm-algorithm Fri, 09 Mar 2018 00:00:00 GMT donatohan.rimenti@gmail.com A Simple Tagging Implementation with MongoDB http://www.baeldung.com/mongodb-tagging Tue, 27 Mar 2018 00:00:00 GMT donatohan.rimenti@gmail.com Double-Checked Locking with Singleton http://www.baeldung.com/java-singleton-double-checked-locking Mon, 23 Apr 2018 00:00:00 GMT donatohan.rimenti@gmail.com Introduction to Dagger 2 http://www.baeldung.com/dagger-2 Sat, 30 Jun 2018 00:00:00 GMT donatohan.rimenti@gmail.com "; + + // Performs a post against the RSS feed endpoint and checks that the + // result is equals to the expected one. + mvc.perform(MockMvcRequestBuilders.get("/rss")).andExpect(status().isOk()) + .andExpect(content().xml(expectedResult)); + } + +} diff --git a/spring-boot-mvc/src/test/java/com/baeldung/springbootmvc/LoginControllerUnitTest.java b/spring-boot-mvc/src/test/java/com/baeldung/springbootmvc/LoginControllerUnitTest.java new file mode 100644 index 0000000000..68229f459c --- /dev/null +++ b/spring-boot-mvc/src/test/java/com/baeldung/springbootmvc/LoginControllerUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.springbootmvc; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.RequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import com.baeldung.springbootmvc.config.CustomMessageSourceConfiguration; + +@RunWith(SpringRunner.class) +@WebMvcTest(value = LoginController.class, secure = false) +@ContextConfiguration(classes = { SpringBootMvcApplication.class, CustomMessageSourceConfiguration.class }) +public class LoginControllerUnitTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void givenLoginForm_whenEmailFieldNotProvided_testCustomValidMessageIsReturned() throws Exception { + + RequestBuilder builder = MockMvcRequestBuilders.post("/loginform").param("email", "").param("password", "helo"); + + // header("accept-language", "fr"). + MvcResult perform = mockMvc.perform(builder).andReturn(); + Assert.assertTrue(perform.getResolvedException().getMessage().contains("valid email")); + + } +} \ No newline at end of file diff --git a/spring-boot-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6ed93e8c44 --- /dev/null +++ b/spring-boot-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springbootmvc.SpringBootMvcApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootMvcApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-ops/README.md b/spring-boot-ops/README.md index 7eca307924..c125c96c36 100644 --- a/spring-boot-ops/README.md +++ b/spring-boot-ops/README.md @@ -1,10 +1,12 @@ -### 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) +### 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) + - [Spring Boot Console Application](http://www.baeldung.com/spring-boot-console-app) + - [Comparing Embedded Servlet Containers in Spring Boot](http://www.baeldung.com/spring-boot-servlet-containers) + diff --git a/spring-boot-ops/pom.xml b/spring-boot-ops/pom.xml index 21a7d22077..57779c3f8e 100644 --- a/spring-boot-ops/pom.xml +++ b/spring-boot-ops/pom.xml @@ -1,149 +1,112 @@ - 4.0.0 + 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 - spring-boot-ops - 0.0.1-SNAPSHOT - war + spring-boot-ops + war + spring-boot-ops + Demo project for Spring Boot - spring-boot-ops - Demo project for Spring Boot - - + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT ../parent-boot-2 - - - org.baeldung.boot.Application - UTF-8 - UTF-8 - 1.8 - 3.1.1 - 3.3.7-1 - + - + + org.springframework.boot + spring-boot-starter-web + - + + org.springframework.boot + spring-boot-starter-thymeleaf + provided + - - org.springframework.boot - spring-boot-starter-web - + + org.springframework.boot + spring-boot-starter-test + test + - - org.springframework.boot - spring-boot-starter-thymeleaf - provided - + + org.springframework.boot + spring-boot-starter-data-jpa + - - org.springframework.boot - spring-boot-starter-test - test - + + org.springframework.boot + spring-boot-starter-mail + - - org.springframework.boot - spring-boot-starter-data-jpa - + + org.springframework.boot + spring-boot-starter-actuator + - - org.springframework.boot - spring-boot-starter-mail - + + com.h2database + h2 + runtime + - - org.springframework.boot - spring-boot-starter-actuator - + + javax.persistence + javax.persistence-api + ${jpa.version} + - - com.h2database - h2 - runtime - + + com.google.guava + guava + ${guava.version} + - - javax.persistence - javax.persistence-api - 2.2 - + + org.subethamail + subethasmtp + ${subethasmtp.version} + test + - - com.google.guava - guava - 18.0 - + + org.webjars + bootstrap + ${bootstrap.version} + - - org.subethamail - subethasmtp - 3.1.7 - test - + + org.webjars + jquery + ${jquery.version} + - - org.webjars - bootstrap - ${bootstrap.version} - + - - org.webjars - jquery - ${jquery.version} - - - - - - ${artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - com.baeldung.webjar.WebjarsdemoApplication - - - - - - + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + com.baeldung.webjar.WebjarsdemoApplication + + + + + + @@ -163,7 +126,7 @@ **/*LiveTest.java **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/AutoconfigurationTest.java @@ -181,5 +144,15 @@ + + + + org.baeldung.boot.Application + 3.1.1 + 3.3.7-1 + 2.2 + 18.0 + 3.1.7 + diff --git a/spring-boot-ops/src/main/java/com/baeldung/compare/ComparisonApplication.java b/spring-boot-ops/src/main/java/com/baeldung/compare/ComparisonApplication.java new file mode 100644 index 0000000000..eb9d5ec4d0 --- /dev/null +++ b/spring-boot-ops/src/main/java/com/baeldung/compare/ComparisonApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.compare; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ComparisonApplication { + + public static void main(String[] args) { + SpringApplication.run(ComparisonApplication.class, args); + } +} diff --git a/spring-boot-ops/src/main/java/com/baeldung/compare/StartupEventHandler.java b/spring-boot-ops/src/main/java/com/baeldung/compare/StartupEventHandler.java new file mode 100644 index 0000000000..e0756f704e --- /dev/null +++ b/spring-boot-ops/src/main/java/com/baeldung/compare/StartupEventHandler.java @@ -0,0 +1,65 @@ +package com.baeldung.compare; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.BiFunction; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Statistic; + +@Component +public class StartupEventHandler { + + // logger, constructor + private static Logger logger = LoggerFactory.getLogger(StartupEventHandler.class); + + public StartupEventHandler(MeterRegistry registry) { + this.meterRegistry = registry; + } + + private String[] METRICS = { + "jvm.memory.used", + "jvm.classes.loaded", + "jvm.threads.live"}; + + private String METRIC_MSG_FORMAT = "Startup Metric >> {}={}"; + + private MeterRegistry meterRegistry; + + @EventListener + public void getAndLogStartupMetrics( + ApplicationReadyEvent event) { + Arrays.asList(METRICS) + .forEach(this::getAndLogActuatorMetric); + } + + private void getAndLogActuatorMetric(String metric) { + Meter meter = meterRegistry.find(metric).meter(); + Map stats = getSamples(meter); + + logger.info(METRIC_MSG_FORMAT, metric, stats.get(Statistic.VALUE).longValue()); + } + + private Map getSamples(Meter meter) { + Map samples = new LinkedHashMap<>(); + mergeMeasurements(samples, meter); + return samples; + } + + private void mergeMeasurements(Map samples, Meter meter) { + meter.measure().forEach((measurement) -> samples.merge(measurement.getStatistic(), + measurement.getValue(), mergeFunction(measurement.getStatistic()))); + } + + private BiFunction mergeFunction(Statistic statistic) { + return Statistic.MAX.equals(statistic) ? Double::max : Double::sum; + } +} diff --git a/spring-boot-ops/src/main/resources/application.properties b/spring-boot-ops/src/main/resources/application.properties new file mode 100644 index 0000000000..a86bd3052e --- /dev/null +++ b/spring-boot-ops/src/main/resources/application.properties @@ -0,0 +1,3 @@ +management.endpoints.web.exposure.include=* +management.metrics.enable.root=true +management.metrics.enable.jvm=true \ No newline at end of file diff --git a/spring-boot-ops/src/main/resources/logback.xml b/spring-boot-ops/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-ops/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-persistence/README.MD b/spring-boot-persistence/README.MD index 71cd226b3a..6cf172426a 100644 --- a/spring-boot-persistence/README.MD +++ b/spring-boot-persistence/README.MD @@ -1,3 +1,6 @@ ### Relevant Articles: -- [Spring Boot with multiple SQL import files](http://www.baeldung.com/spring-Boot-with-multiple-SQL-import-files) \ No newline at end of file +- [Spring Boot with Multiple SQL Import Files](http://www.baeldung.com/spring-boot-sql-import-files) +- [Configuring Separate Spring DataSource for Tests](http://www.baeldung.com/spring-testing-separate-data-source) +- [Quick Guide on data.sql and schema.sql Files in Spring Boot](http://www.baeldung.com/spring-boot-data-sql-and-schema-sql) +- [Configuring a Tomcat Connection Pool in Spring Boot](https://www.baeldung.com/spring-boot-tomcat-connection-pool) diff --git a/spring-boot-persistence/pom.xml b/spring-boot-persistence/pom.xml index af0d7ea505..08989edfa9 100644 --- a/spring-boot-persistence/pom.xml +++ b/spring-boot-persistence/pom.xml @@ -1,53 +1,75 @@ - + + 4.0.0 + com.baeldung spring-boot-persistence - 0.0.1-SNAPSHOT - jar - spring-boot-persistence - This is a simple Spring Data Repositories test - + 0.1.0 + parent-boot-2 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 - + org.springframework.boot spring-boot-starter-data-jpa + + + com.zaxxer + HikariCP + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.apache.tomcat + tomcat-jdbc + ${tomcat-jdbc.version} + + + mysql + mysql-connector-java + ${mysql-connector-java.version} com.h2database h2 - - - org.springframework.boot - spring-boot-starter + ${h2database.version} + runtime - + + + UTF-8 + 1.8 + 8.0.12 + 9.0.10 + 1.4.197 + + spring-boot-persistence - - src/main/resources - true - + + src/main/resources + true + - org.apache.maven.plugins - maven-war-plugin - - - pl.project13.maven - git-commit-id-plugin + org.springframework.boot + spring-boot-maven-plugin - - \ No newline at end of file + diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java b/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java similarity index 73% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java rename to spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java index 439c6cb602..ef90714347 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java +++ b/spring-boot-persistence/src/main/java/com/baeldung/boot/config/H2JpaConfig.java @@ -1,11 +1,10 @@ -package org.baeldung.config; +package com.baeldung.boot.config; import java.util.Properties; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; -import org.baeldung.extended.persistence.dao.ExtendedRepositoryImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -19,10 +18,10 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration -@EnableJpaRepositories(basePackages = "org.baeldung.extended.persistence.dao", repositoryBaseClass = ExtendedRepositoryImpl.class) -@PropertySource("persistence-student-h2.properties") +@EnableJpaRepositories(basePackages = { "org.baeldung.boot.repository", "org.baeldung.repository" }) +@PropertySource("classpath:persistence-generic-entity.properties") @EnableTransactionManagement -public class StudentJPAH2Config { +public class H2JpaConfig { @Autowired private Environment env; @@ -42,15 +41,15 @@ public class StudentJPAH2Config { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.inmemory.persistence.model" }); + em.setPackagesToScan(new String[] { "org.baeldung.boot.domain" }); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); em.setJpaProperties(additionalProperties()); return em; } @Bean - JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { - JpaTransactionManager transactionManager = new JpaTransactionManager(); + JpaTransactionManager transactionManager(final EntityManagerFactory entityManagerFactory) { + final JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(entityManagerFactory); return transactionManager; } @@ -61,9 +60,8 @@ public class StudentJPAH2Config { hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql")); - hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache")); - hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache")); return hibernateProperties; } + } diff --git a/spring-boot-persistence/src/main/java/com/baeldung/domain/Country.java b/spring-boot-persistence/src/main/java/com/baeldung/domain/Country.java new file mode 100644 index 0000000000..e6a88c7121 --- /dev/null +++ b/spring-boot-persistence/src/main/java/com/baeldung/domain/Country.java @@ -0,0 +1,36 @@ +package com.baeldung.domain; + +import static javax.persistence.GenerationType.IDENTITY; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Country { + + @Id + @GeneratedValue(strategy = IDENTITY) + private Integer id; + + @Column(nullable = false) + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/SpringBootConsoleApplication.java b/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/SpringBootConsoleApplication.java new file mode 100644 index 0000000000..ff37442cd4 --- /dev/null +++ b/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/SpringBootConsoleApplication.java @@ -0,0 +1,22 @@ +package com.baeldung.tomcatconnectionpool.application; + +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.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@SpringBootApplication +@EnableAutoConfiguration +@ComponentScan(basePackages={"com.baeldung.tomcatconnectionpool.application"}) +@EnableJpaRepositories(basePackages="com.baeldung.tomcatconnectionpool.application.repositories") +@EnableTransactionManagement +@EntityScan(basePackages="com.baeldung.tomcatconnectionpool.application.entities") +public class SpringBootConsoleApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootConsoleApplication.class); + } +} diff --git a/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/entities/Customer.java b/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/entities/Customer.java new file mode 100644 index 0000000000..4003d5aca9 --- /dev/null +++ b/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/entities/Customer.java @@ -0,0 +1,53 @@ +package com.baeldung.tomcatconnectionpool.application.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "customers") +public class Customer { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + @Column(name = "first_name") + private String firstName; + @Column(name = "last_name") + private String lastName; + + public Customer() {} + + public Customer(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public long getId() { + return id; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + @Override + public String toString() { + return "Customer{" + "id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + '}'; + } +} diff --git a/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/repositories/CustomerRepository.java b/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/repositories/CustomerRepository.java new file mode 100644 index 0000000000..770906439c --- /dev/null +++ b/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/repositories/CustomerRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.tomcatconnectionpool.application.repositories; + +import com.baeldung.tomcatconnectionpool.application.entities.Customer; +import java.util.List; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CustomerRepository extends CrudRepository { + + List findByLastName(String lastName); +} diff --git a/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/runners/CommandLineCrudRunner.java b/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/runners/CommandLineCrudRunner.java new file mode 100644 index 0000000000..9666bac5a5 --- /dev/null +++ b/spring-boot-persistence/src/main/java/com/baeldung/tomcatconnectionpool/application/runners/CommandLineCrudRunner.java @@ -0,0 +1,37 @@ +package com.baeldung.tomcatconnectionpool.application.runners; + +import com.baeldung.tomcatconnectionpool.application.entities.Customer; +import com.baeldung.tomcatconnectionpool.application.repositories.CustomerRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +@Component +public class CommandLineCrudRunner implements CommandLineRunner { + + private static final Logger logger = LoggerFactory.getLogger(CommandLineCrudRunner.class); + + @Autowired + private CustomerRepository customerRepository; + + @Override + public void run(String... args) throws Exception { + customerRepository.save(new Customer("John", "Doe")); + customerRepository.save(new Customer("Jennifer", "Wilson")); + + logger.info("Customers found with findAll():"); + customerRepository.findAll().forEach(c -> logger.info(c.toString())); + + logger.info("Customer found with findById(1L):"); + Customer customer = customerRepository.findById(1L) + .orElseGet(() -> new Customer("Non-existing customer", "")); + logger.info(customer.toString()); + + logger.info("Customer found with findByLastName('Wilson'):"); + customerRepository.findByLastName("Wilson").forEach(c -> { + logger.info(c.toString()); + }); + } +} diff --git a/spring-boot/src/main/java/org/baeldung/boot/domain/GenericEntity.java b/spring-boot-persistence/src/main/java/org/baeldung/boot/domain/GenericEntity.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/boot/domain/GenericEntity.java rename to spring-boot-persistence/src/main/java/org/baeldung/boot/domain/GenericEntity.java diff --git a/spring-boot/src/main/java/org/baeldung/boot/repository/GenericEntityRepository.java b/spring-boot-persistence/src/main/java/org/baeldung/boot/repository/GenericEntityRepository.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/boot/repository/GenericEntityRepository.java rename to spring-boot-persistence/src/main/java/org/baeldung/boot/repository/GenericEntityRepository.java diff --git a/spring-boot-persistence/src/main/resources/application.properties b/spring-boot-persistence/src/main/resources/application.properties index e69de29bb2..303ce33c25 100644 --- a/spring-boot-persistence/src/main/resources/application.properties +++ b/spring-boot-persistence/src/main/resources/application.properties @@ -0,0 +1,16 @@ +spring.datasource.tomcat.initial-size=15 +spring.datasource.tomcat.max-wait=20000 +spring.datasource.tomcat.max-active=50 +spring.datasource.tomcat.max-idle=15 +spring.datasource.tomcat.min-idle=8 +spring.datasource.tomcat.default-auto-commit=true +spring.datasource.url=jdbc:h2:mem:test +spring.datasource.username=root +spring.datasource.password= +spring.datasource.driver-class-name=org.h2.Driver + +spring.jpa.show-sql=false +spring.jpa.hibernate.ddl-auto=update +spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect +spring.jpa.properties.hibernate.id.new_generator_mappings=false diff --git a/spring-boot-persistence/src/main/resources/data.sql b/spring-boot-persistence/src/main/resources/data.sql new file mode 100644 index 0000000000..feef02b6cf --- /dev/null +++ b/spring-boot-persistence/src/main/resources/data.sql @@ -0,0 +1,10 @@ +insert into users values (1, 'Alex', 1); +insert into users values (2, 'Bob', 1); +insert into users values (3, 'John', 0); +insert into users values (4, 'Harry', 0); +insert into users values (5, 'Smith', 1); + +INSERT INTO country (name) VALUES ('India'); +INSERT INTO country (name) VALUES ('Brazil'); +INSERT INTO country (name) VALUES ('USA'); +INSERT INTO country (name) VALUES ('Italy'); \ No newline at end of file diff --git a/spring-boot-persistence/src/main/resources/logback.xml b/spring-boot-persistence/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-persistence/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-persistence/src/main/resources/persistence-generic-entity.properties b/spring-boot-persistence/src/main/resources/persistence-generic-entity.properties new file mode 100644 index 0000000000..b19304cb1f --- /dev/null +++ b/spring-boot-persistence/src/main/resources/persistence-generic-entity.properties @@ -0,0 +1,8 @@ +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +jdbc.user=sa +jdbc.pass=sa + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop diff --git a/spring-boot-persistence/src/main/resources/schema.sql b/spring-boot-persistence/src/main/resources/schema.sql new file mode 100644 index 0000000000..4cfc8a7927 --- /dev/null +++ b/spring-boot-persistence/src/main/resources/schema.sql @@ -0,0 +1,15 @@ +drop table if exists USERS; +drop table if exists country; + +create table USERS( + ID int not null AUTO_INCREMENT, + NAME varchar(100) not null, + STATUS int, + PRIMARY KEY ( ID ) +); + +CREATE TABLE country ( + id INTEGER NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + PRIMARY KEY (id) +); \ No newline at end of file diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootH2IntegrationTest.java b/spring-boot-persistence/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java similarity index 91% rename from spring-boot/src/test/java/org/baeldung/SpringBootH2IntegrationTest.java rename to spring-boot-persistence/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java index 290cfbe081..6479e90113 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootH2IntegrationTest.java +++ b/spring-boot-persistence/src/test/java/com/baeldung/SpringBootH2IntegrationTest.java @@ -1,7 +1,8 @@ -package org.baeldung; +package com.baeldung; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; -import org.baeldung.boot.Application; -import org.baeldung.boot.config.H2JpaConfig; import org.baeldung.boot.domain.GenericEntity; import org.baeldung.boot.repository.GenericEntityRepository; import org.junit.Test; @@ -10,8 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import com.baeldung.boot.config.H2JpaConfig; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = { Application.class, H2JpaConfig.class }) diff --git a/spring-boot-persistence/src/test/java/com/baeldung/SpringBootJPAIntegrationTest.java b/spring-boot-persistence/src/test/java/com/baeldung/SpringBootJPAIntegrationTest.java new file mode 100644 index 0000000000..eef9ebe953 --- /dev/null +++ b/spring-boot-persistence/src/test/java/com/baeldung/SpringBootJPAIntegrationTest.java @@ -0,0 +1,27 @@ +package com.baeldung; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.baeldung.boot.domain.GenericEntity; +import org.baeldung.boot.repository.GenericEntityRepository; +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.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringBootJPAIntegrationTest { + @Autowired + private GenericEntityRepository genericEntityRepository; + + @Test + public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() { + GenericEntity genericEntity = genericEntityRepository.save(new GenericEntity("test")); + GenericEntity foundEntity = genericEntityRepository.findById(genericEntity.getId()).orElse(null); + assertNotNull(foundEntity); + assertEquals(genericEntity.getValue(), foundEntity.getValue()); + } +} \ No newline at end of file diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootProfileIntegrationTest.java b/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java similarity index 95% rename from spring-boot/src/test/java/org/baeldung/SpringBootProfileIntegrationTest.java rename to spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java index 128a05f103..4c68f1d4a0 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootProfileIntegrationTest.java +++ b/spring-boot-persistence/src/test/java/com/baeldung/SpringBootProfileIntegrationTest.java @@ -1,6 +1,8 @@ -package org.baeldung; +package com.baeldung; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; -import org.baeldung.boot.Application; import org.baeldung.boot.domain.GenericEntity; import org.baeldung.boot.repository.GenericEntityRepository; import org.baeldung.config.H2TestProfileJPAConfig; @@ -11,9 +13,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - @RunWith(SpringRunner.class) @SpringBootTest(classes = { Application.class, H2TestProfileJPAConfig.class }) @ActiveProfiles("test") diff --git a/spring-boot-persistence/src/test/java/com/baeldung/tomcatconnectionpool/test/application/SpringBootTomcatConnectionPoolIntegrationTest.java b/spring-boot-persistence/src/test/java/com/baeldung/tomcatconnectionpool/test/application/SpringBootTomcatConnectionPoolIntegrationTest.java new file mode 100644 index 0000000000..c68e137fb0 --- /dev/null +++ b/spring-boot-persistence/src/test/java/com/baeldung/tomcatconnectionpool/test/application/SpringBootTomcatConnectionPoolIntegrationTest.java @@ -0,0 +1,22 @@ +package com.baeldung.tomcatconnectionpool.test.application; + +import javax.sql.DataSource; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.junit4.SpringRunner; +import static org.assertj.core.api.Assertions.*; +import org.springframework.boot.test.context.SpringBootTest; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringBootTomcatConnectionPoolIntegrationTest { + + @Autowired + private DataSource dataSource; + + @Test + public void givenTomcatConnectionPoolInstance_whenCheckedPoolClassName_thenCorrect() { + assertThat(dataSource.getClass().getName()).isEqualTo("org.apache.tomcat.jdbc.pool.DataSource"); + } +} diff --git a/spring-boot/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java b/spring-boot-persistence/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java similarity index 94% rename from spring-boot/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java rename to spring-boot-persistence/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java index d0b92a7a93..7f962e1417 100644 --- a/spring-boot/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java +++ b/spring-boot-persistence/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java @@ -18,7 +18,7 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration -@EnableJpaRepositories(basePackages = { "org.baeldung.repository", "org.baeldung.boot.repository", "org.baeldung.boot.boottest" }) +@EnableJpaRepositories(basePackages = { "org.baeldung.repository", "org.baeldung.boot.repository" }) @EnableTransactionManagement public class H2TestProfileJPAConfig { @@ -41,7 +41,7 @@ public class H2TestProfileJPAConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.domain", "org.baeldung.boot.domain", "org.baeldung.boot.boottest", "org.baeldung.model" }); + em.setPackagesToScan(new String[] { "org.baeldung.domain", "org.baeldung.boot.domain" }); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); em.setJpaProperties(additionalProperties()); return em; diff --git a/spring-boot-property-exp/pom.xml b/spring-boot-property-exp/pom.xml index abf9f45d1c..7d8f2480ac 100644 --- a/spring-boot-property-exp/pom.xml +++ b/spring-boot-property-exp/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-property-exp com.baeldung @@ -18,8 +18,4 @@ property-exp-custom-config - - UTF-8 - - diff --git a/spring-boot-property-exp/property-exp-custom-config/pom.xml b/spring-boot-property-exp/property-exp-custom-config/pom.xml index 019e2362a1..ab22c5ad30 100644 --- a/spring-boot-property-exp/property-exp-custom-config/pom.xml +++ b/spring-boot-property-exp/property-exp-custom-config/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 property-exp-custom @@ -14,14 +15,19 @@ - org.springframework.boot spring-boot-starter - 1.5.10.RELEASE + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test - + @@ -68,7 +74,7 @@ - UTF-8 + 1.5.10.RELEASE Custom Property Value diff --git a/spring-boot-property-exp/property-exp-custom-config/src/main/resources/logback.xml b/spring-boot-property-exp/property-exp-custom-config/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-property-exp/property-exp-custom-config/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-property-exp/property-exp-custom-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-property-exp/property-exp-custom-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6dd3419d39 --- /dev/null +++ b/spring-boot-property-exp/property-exp-custom-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.propertyexpansion.SpringBootPropertyExpansionApp; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootPropertyExpansionApp.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} 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 0ac4a31c7c..4ede36e61a 100644 --- a/spring-boot-property-exp/property-exp-default-config/pom.xml +++ b/spring-boot-property-exp/property-exp-default-config/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 property-exp-default @@ -34,7 +35,6 @@ - UTF-8 Custom Property Value diff --git a/spring-boot-property-exp/property-exp-default-config/src/main/resources/logback.xml b/spring-boot-property-exp/property-exp-default-config/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-property-exp/property-exp-default-config/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-property-exp/property-exp-default-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-property-exp/property-exp-default-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6dd3419d39 --- /dev/null +++ b/spring-boot-property-exp/property-exp-default-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.propertyexpansion.SpringBootPropertyExpansionApp; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootPropertyExpansionApp.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot-security/README.md b/spring-boot-security/README.md index a79e7de610..30a3218672 100644 --- a/spring-boot-security/README.md +++ b/spring-boot-security/README.md @@ -9,3 +9,5 @@ ### Relevant Articles: - [Spring Boot Security Auto-Configuration](http://www.baeldung.com/spring-boot-security-autoconfiguration) +- [Spring Security for Spring Boot Integration Tests](https://www.baeldung.com/spring-security-integration-tests) +- [Introduction to Spring Security Taglibs](https://www.baeldung.com/spring-security-taglibs) diff --git a/spring-boot-security/pom.xml b/spring-boot-security/pom.xml index 8763c210c8..6bc013d1ed 100644 --- a/spring-boot-security/pom.xml +++ b/spring-boot-security/pom.xml @@ -1,8 +1,7 @@ + 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 spring-boot-security 0.0.1-SNAPSHOT jar @@ -20,7 +19,7 @@ org.springframework.boot spring-boot-dependencies - 1.5.9.RELEASE + ${spring-boot.version} pom import @@ -28,10 +27,6 @@ - - - - org.springframework.boot spring-boot-starter-security @@ -44,6 +39,23 @@ org.springframework.boot spring-boot-starter-web + + + + org.springframework.security + spring-security-taglibs + + + + + org.apache.tomcat.embed + tomcat-embed-jasper + provided + + + javax.servlet + jstl + org.springframework.boot @@ -62,13 +74,14 @@ org.springframework.boot spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} - UTF-8 - UTF-8 + 1.5.9.RELEASE + 2.0.4.RELEASE diff --git a/spring-boot-security/src/main/java/com/baeldung/integrationtesting/MethodSecurityConfigurer.java b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/MethodSecurityConfigurer.java new file mode 100644 index 0000000000..dccbace106 --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/MethodSecurityConfigurer.java @@ -0,0 +1,13 @@ +package com.baeldung.integrationtesting; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity( + prePostEnabled = true, + securedEnabled = true) +public class MethodSecurityConfigurer extends GlobalMethodSecurityConfiguration { + +} diff --git a/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredApplication.java b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredApplication.java new file mode 100644 index 0000000000..18469e4752 --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.integrationtesting; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SecuredApplication { + + public static void main(String[] args) { + SpringApplication.run(SecuredApplication.class, args); + } + +} diff --git a/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredController.java b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredController.java new file mode 100644 index 0000000000..495c358784 --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredController.java @@ -0,0 +1,21 @@ +package com.baeldung.integrationtesting; + +import java.util.Arrays; +import java.util.List; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class SecuredController { + + @GetMapping("/public/hello") + public List publicHello() { + return Arrays.asList("Hello", "World", "from", "Public"); + } + + @GetMapping("/private/hello") + public List privateHello() { + return Arrays.asList("Hello", "World", "from", "Private"); + } + +} diff --git a/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredService.java b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredService.java new file mode 100644 index 0000000000..25253f163a --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/SecuredService.java @@ -0,0 +1,13 @@ +package com.baeldung.integrationtesting; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; + +@Service +public class SecuredService { + + @PreAuthorize("authenticated") + public String sayHelloSecured() { + return "Hello user."; + } +} diff --git a/spring-boot-security/src/main/java/com/baeldung/integrationtesting/WebSecurityConfigurer.java b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/WebSecurityConfigurer.java new file mode 100644 index 0000000000..32a48ce612 --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/integrationtesting/WebSecurityConfigurer.java @@ -0,0 +1,31 @@ +package com.baeldung.integrationtesting; + +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.WebSecurityConfigurerAdapter; + +@Configuration +public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("spring") + .password("secret") + .roles("USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/private/**") + .hasRole("USER") + .antMatchers("/public/**") + .permitAll() + .and() + .httpBasic(); + } + + +} diff --git a/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/HomeController.java b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/HomeController.java new file mode 100644 index 0000000000..eca093a76f --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/HomeController.java @@ -0,0 +1,14 @@ +package com.baeldung.springsecuritytaglibs; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/") +public class HomeController { + + @RequestMapping + public String home() { + return "home"; + } +} diff --git a/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/SpringBootSecurityTagLibsApplication.java b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/SpringBootSecurityTagLibsApplication.java new file mode 100644 index 0000000000..397ea47f96 --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/SpringBootSecurityTagLibsApplication.java @@ -0,0 +1,9 @@ +package com.baeldung.springsecuritytaglibs; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@PropertySource("classpath:application-taglibs.properties") +public class SpringBootSecurityTagLibsApplication { +} diff --git a/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/config/SpringBootSecurityTagLibsConfig.java b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/config/SpringBootSecurityTagLibsConfig.java new file mode 100644 index 0000000000..665dd0bce9 --- /dev/null +++ b/spring-boot-security/src/main/java/com/baeldung/springsecuritytaglibs/config/SpringBootSecurityTagLibsConfig.java @@ -0,0 +1,31 @@ +package com.baeldung.springsecuritytaglibs.config; + +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; + +@Configuration +@EnableWebSecurity +public class SpringBootSecurityTagLibsConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("testUser") + .password("password") + .roles("ADMIN"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.csrf() + .and() + .authorizeRequests() + .antMatchers("/userManagement").hasRole("ADMIN") + .anyRequest().permitAll().and().httpBasic(); + // @formatter:on + } +} \ No newline at end of file diff --git a/spring-boot-security/src/main/resources/application-taglibs.properties b/spring-boot-security/src/main/resources/application-taglibs.properties new file mode 100644 index 0000000000..218868405f --- /dev/null +++ b/spring-boot-security/src/main/resources/application-taglibs.properties @@ -0,0 +1,3 @@ +#jsp config +spring.mvc.view.prefix: /WEB-INF/views/ +spring.mvc.view.suffix: .jsp diff --git a/spring-boot-security/src/main/resources/application.properties b/spring-boot-security/src/main/resources/application.properties index c2b8d70dc6..e776132359 100644 --- a/spring-boot-security/src/main/resources/application.properties +++ b/spring-boot-security/src/main/resources/application.properties @@ -1,4 +1,4 @@ #spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration #security.user.password=password #security.oauth2.client.client-id=client -#security.oauth2.client.client-secret=secret +#security.oauth2.client.client-secret=secret \ No newline at end of file diff --git a/spring-boot-security/src/main/resources/logback.xml b/spring-boot-security/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-security/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-security/src/main/webapp/WEB-INF/views/home.jsp b/spring-boot-security/src/main/webapp/WEB-INF/views/home.jsp new file mode 100644 index 0000000000..80ecd61cb5 --- /dev/null +++ b/spring-boot-security/src/main/webapp/WEB-INF/views/home.jsp @@ -0,0 +1,38 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="sec" + uri="http://www.springframework.org/security/tags"%> + + + + + +Home Page + + + + Login + + + + Logout + + + +

    + Welcome back, +

    + + Manage Users + +
    + + Text Field:
    + + + + Manage Users + +
    + + \ No newline at end of file diff --git a/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerRestTemplateIntegrationTest.java b/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerRestTemplateIntegrationTest.java new file mode 100644 index 0000000000..c224058155 --- /dev/null +++ b/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerRestTemplateIntegrationTest.java @@ -0,0 +1,34 @@ +package com.baeldung.integrationtesting; + +import static org.junit.Assert.assertEquals; +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class SecuredControllerRestTemplateIntegrationTest { + + @Autowired + private TestRestTemplate template; + + @Test + public void givenRequestOnPrivateService_shouldFailWith401() throws Exception { + ResponseEntity result = template.getForEntity("/private/hello", String.class); + assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode()); + } + + @Test + public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception { + ResponseEntity result = template.withBasicAuth("spring", "secret") + .getForEntity("/private/hello", String.class); + assertEquals(HttpStatus.OK, result.getStatusCode()); + } + +} diff --git a/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerSpringBootIntegrationTest.java b/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerSpringBootIntegrationTest.java new file mode 100644 index 0000000000..ce9e6de917 --- /dev/null +++ b/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerSpringBootIntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.integrationtesting; + +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class SecuredControllerSpringBootIntegrationTest { + + @Autowired + private WebApplicationContext context; + + private MockMvc mvc; + + @Before + public void setup() { + mvc = MockMvcBuilders + .webAppContextSetup(context) + .apply(springSecurity()) + .build(); + } + + @Test + public void givenRequestOnPrivateService_shouldFailWith401() throws Exception { + mvc.perform(get("/private/hello") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isUnauthorized()); + } + + @WithMockUser("spring") + @Test + public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception { + mvc.perform(get("/private/hello") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + +} diff --git a/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerWebMvcIntegrationTest.java b/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerWebMvcIntegrationTest.java new file mode 100644 index 0000000000..7281648856 --- /dev/null +++ b/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredControllerWebMvcIntegrationTest.java @@ -0,0 +1,39 @@ +package com.baeldung.integrationtesting; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.integrationtesting.SecuredController; + +@RunWith(SpringRunner.class) +@WebMvcTest(SecuredController.class) +public class SecuredControllerWebMvcIntegrationTest { + + @Autowired + private MockMvc mvc; + + @Test + public void givenRequestOnPrivateService_shouldFailWith401() throws Exception { + mvc.perform(get("/private/hello") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isUnauthorized()); + } + + @WithMockUser(value = "spring") + @Test + public void givenAuthRequestOnPrivateService_shouldSucceedWith200() throws Exception { + mvc.perform(get("/private/hello") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + +} diff --git a/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredMethodSpringBootIntegrationTest.java b/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredMethodSpringBootIntegrationTest.java new file mode 100644 index 0000000000..816b05bd5a --- /dev/null +++ b/spring-boot-security/src/test/java/com/baeldung/integrationtesting/SecuredMethodSpringBootIntegrationTest.java @@ -0,0 +1,32 @@ +package com.baeldung.integrationtesting; + +import static org.assertj.core.api.Assertions.assertThat; + +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.security.authentication.AuthenticationCredentialsNotFoundException; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.integrationtesting.SecuredService; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SecuredMethodSpringBootIntegrationTest { + + @Autowired + private SecuredService service; + + @Test(expected = AuthenticationCredentialsNotFoundException.class) + public void givenUnauthenticated_whenCallService_thenThrowsException() { + service.sayHelloSecured(); + } + + @WithMockUser(username="spring") + @Test + public void givenAuthenticated_whenCallServiceWithSecured_thenOk() { + assertThat(service.sayHelloSecured()).isNotBlank(); + } +} diff --git a/spring-boot-security/src/test/java/com/baeldung/springsecuritytaglibs/HomeControllerUnitTest.java b/spring-boot-security/src/test/java/com/baeldung/springsecuritytaglibs/HomeControllerUnitTest.java new file mode 100644 index 0000000000..0585c06a59 --- /dev/null +++ b/spring-boot-security/src/test/java/com/baeldung/springsecuritytaglibs/HomeControllerUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.springsecuritytaglibs; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = SpringBootSecurityTagLibsApplication.class) +public class HomeControllerUnitTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void whenUserIsAuthenticatedThenAuthenticatedSectionsShowOnSite() throws Exception { + String body = this.restTemplate.withBasicAuth("testUser", "password") + .getForEntity("/", String.class) + .getBody(); + + // test + assertFalse(body.contains("Login")); + + // test + assertTrue(body.contains("Logout")); + + // test + assertTrue(body.contains("Manage Users")); + + // test + assertTrue(body.contains("testUser")); + + // test + assertTrue(body.contains("")); + + // test + assertTrue(body.contains(" + assertTrue(body.contains("")); + } + + @Test + public void whenUserIsNotAuthenticatedThenOnlyAnonymousSectionsShowOnSite() throws Exception { + String body = this.restTemplate.getForEntity("/", String.class) + .getBody(); + + // test + assertTrue(body.contains("Login")); + + // test + assertFalse(body.contains("Logout")); + } +} diff --git a/spring-boot-vue/.gitignore b/spring-boot-vue/.gitignore new file mode 100644 index 0000000000..82eca336e3 --- /dev/null +++ b/spring-boot-vue/.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-boot-vue/README.md b/spring-boot-vue/README.md new file mode 100644 index 0000000000..e68f961e51 --- /dev/null +++ b/spring-boot-vue/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Vue.js Frontend with a Spring Boot Backend](http://www.baeldung.com/spring-boot-vue-js) diff --git a/spring-boot-vue/pom.xml b/spring-boot-vue/pom.xml new file mode 100644 index 0000000000..d581b11d68 --- /dev/null +++ b/spring-boot-vue/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + com.baeldung + spring-boot-vue + 0.0.1-SNAPSHOT + jar + + spring-boot-vue + Demo project for Spring Boot Vue project + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-boot-vue/src/main/java/com/baeldung/springbootmvc/SpringBootMvcApplication.java b/spring-boot-vue/src/main/java/com/baeldung/springbootmvc/SpringBootMvcApplication.java new file mode 100644 index 0000000000..c4213af0a3 --- /dev/null +++ b/spring-boot-vue/src/main/java/com/baeldung/springbootmvc/SpringBootMvcApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.springbootmvc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +@SpringBootApplication +public class SpringBootMvcApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootMvcApplication.class, args); + } +} diff --git a/spring-boot-vue/src/main/java/com/baeldung/springbootmvc/controllers/MainController.java b/spring-boot-vue/src/main/java/com/baeldung/springbootmvc/controllers/MainController.java new file mode 100644 index 0000000000..37b74876cf --- /dev/null +++ b/spring-boot-vue/src/main/java/com/baeldung/springbootmvc/controllers/MainController.java @@ -0,0 +1,18 @@ +package com.baeldung.springbootmvc.controllers; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +@Controller +public class MainController { + + @RequestMapping(value = "/", method = RequestMethod.GET) + public String index(Model model) { + // this attribute will be available in the view index.html as a thymeleaf variable + model.addAttribute("eventName", "FIFA 2018"); + // this just means render index.html from static/ area + return "index"; + } +} diff --git a/spring-boot-vue/src/main/resources/application.properties b/spring-boot-vue/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-vue/src/main/resources/logback.xml b/spring-boot-vue/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-vue/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-vue/src/main/resources/static/favicon.ico b/spring-boot-vue/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000..64105ac11c Binary files /dev/null and b/spring-boot-vue/src/main/resources/static/favicon.ico differ diff --git a/spring-boot-vue/src/main/resources/templates/index.html b/spring-boot-vue/src/main/resources/templates/index.html new file mode 100644 index 0000000000..9fa374282a --- /dev/null +++ b/spring-boot-vue/src/main/resources/templates/index.html @@ -0,0 +1,98 @@ + + + + + + + + + + + + + +
    +

    This is an example Vue.js application developed with Spring Boot

    +

    This file is rendered by a Spring built-in default controller for index.html (/) using + Spring's built-in + Thymeleaf templating engine. + Although we don't need it per se, we customized the information passed to this + view from thymeleaf by adding a controller method for "/" route to demonstrate how to pass information from + Thymeleaf to this page. + The combination of template engine and frontend framework like Vue can make this a powerful approach to build + more complex applications while leveraging the benefits of a framework like Vue.js. + You can use thymeleaf features too but this project focuses mainly on using Vue.js on the + frontend as the framework and makes minimal use of Thymeleaf. + Also we don't use any routing and multiple components in this example, so what you see is technically a + Single Page Application (SPA) without any routes configured. +

    + +
    +
    + Name of Event: + +
    +
    + +
      +
    • + + +
    • +
    +
    +
    +
    + + + + + + + + \ No newline at end of file diff --git a/spring-boot-vue/src/test/java/com/baeldung/springbootmvc/SpringBootMvcApplicationUnitTest.java b/spring-boot-vue/src/test/java/com/baeldung/springbootmvc/SpringBootMvcApplicationUnitTest.java new file mode 100644 index 0000000000..567b239ed2 --- /dev/null +++ b/spring-boot-vue/src/test/java/com/baeldung/springbootmvc/SpringBootMvcApplicationUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.springbootmvc; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class SpringBootMvcApplicationUnitTest { + + @Autowired + private MockMvc mockMvc; + + /** + * If this test passes, we got a page with the thymeleaf provided variable + * value for eventName + */ + @Test + public void shouldLoadCorrectIndexPage() throws Exception { + mockMvc.perform(get("/")).andExpect(status().isOk()). + andExpect(MockMvcResultMatchers.content() + .string(containsString("FIFA 2018"))); + } + +} diff --git a/spring-boot-vue/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-boot-vue/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6ed93e8c44 --- /dev/null +++ b/spring-boot-vue/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springbootmvc.SpringBootMvcApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootMvcApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-boot/.factorypath b/spring-boot/.factorypath index 68b2514aab..22b8a1ce95 100644 --- a/spring-boot/.factorypath +++ b/spring-boot/.factorypath @@ -1,4 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -16,7 +38,6 @@ - @@ -32,9 +53,7 @@ - - @@ -48,7 +67,6 @@ - @@ -68,11 +86,22 @@ + + + + + + + + + + + @@ -85,6 +114,9 @@ + + + @@ -124,6 +156,7 @@ + @@ -136,7 +169,6 @@ - diff --git a/spring-boot/README.MD b/spring-boot/README.MD index 595e13cd9f..192c4f9fed 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -3,7 +3,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [Quick Guide to @RestClientTest in Spring Boot](http://www.baeldung.com/restclienttest-in-spring-boot) - [A Guide to Spring in Eclipse STS](http://www.baeldung.com/eclipse-sts-spring) - [The @ServletComponentScan Annotation in Spring Boot](http://www.baeldung.com/spring-servletcomponentscan) - [Intro to Building an Application with Spring Boot](http://www.baeldung.com/intro-to-spring-boot) @@ -12,19 +11,15 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Using Custom Banners in Spring Boot](http://www.baeldung.com/spring-boot-custom-banners) - [Guide to Internationalization in Spring Boot](http://www.baeldung.com/spring-boot-internationalization) - [Create a Custom FailureAnalyzer with Spring Boot](http://www.baeldung.com/spring-boot-failure-analyzer) -- [Configuring Separate Spring DataSource for Tests](http://www.baeldung.com/spring-testing-separate-data-source) - [Dynamic DTO Validation Config Retrieved from DB](http://www.baeldung.com/spring-dynamic-dto-validation) - [Custom Information in Spring Boot Info Endpoint](http://www.baeldung.com/spring-boot-info-actuator-custom) - [Using @JsonComponent in Spring Boot](http://www.baeldung.com/spring-boot-jsoncomponent) - [Testing in Spring Boot](http://www.baeldung.com/spring-boot-testing) - [Guide to @ConfigurationProperties in Spring Boot](http://www.baeldung.com/configuration-properties-in-spring-boot) - [How to Get All Spring-Managed Beans?](http://www.baeldung.com/spring-show-all-beans) -- [A Java Client for a WebSockets API](http://www.baeldung.com/websockets-api-java-spring-client) - [Spring Boot and Togglz Aspect](http://www.baeldung.com/spring-togglz) - [Getting Started with GraphQL and Spring Boot](http://www.baeldung.com/spring-graphql) - [Guide to Spring Type Conversions](http://www.baeldung.com/spring-type-conversions) -- [Quick Guide on data.sql and schema.sql Files in Spring Boot](http://www.baeldung.com/spring-boot-data-sql-and-schema-sql) -- [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8) - [An Introduction to Kong](http://www.baeldung.com/kong) - [Spring Boot Customize Whitelabel Error Page](http://www.baeldung.com/spring-boot-custom-error-page) - [Spring Boot: Configuring a Main Class](http://www.baeldung.com/spring-boot-main-class) @@ -33,3 +28,9 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [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) +- [Spring Shutdown Callbacks](http://www.baeldung.com/spring-shutdown-callbacks) +- [Spring Boot Integration Testing with Embedded MongoDB](http://www.baeldung.com/spring-boot-embedded-mongodb) +- [Container Configuration in Spring Boot 2](http://www.baeldung.com/embeddedservletcontainercustomizer-configurableembeddedservletcontainer-spring-boot) +- [Introduction to Chaos Monkey](https://www.baeldung.com/spring-boot-chaos-monkey) +- [Spring Component Scanning](https://www.baeldung.com/spring-component-scanning) +- [Load Spring Boot Properties From a JSON File](https://www.baeldung.com/spring-boot-json-properties) diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index d8ee3cc2d9..0ea6b6156f 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -1,5 +1,5 @@ + 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 spring-boot @@ -16,6 +16,35 @@ + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + test + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + org.junit.platform + junit-platform-launcher + ${junit-platform.version} + test + org.springframework.boot spring-boot-starter-thymeleaf @@ -36,12 +65,12 @@ com.graphql-java graphql-spring-boot-starter - 3.6.0 + ${graphql-spring-boot-starter.version} com.graphql-java graphql-java-tools - 3.2.0 + ${graphql-java-tools.version} @@ -55,11 +84,6 @@ test - - io.dropwizard.metrics metrics-core @@ -83,7 +107,7 @@ com.google.guava guava - 18.0 + ${guava.version} @@ -93,16 +117,6 @@ provided - - org.springframework - spring-websocket - - - - org.springframework - spring-messaging - - org.togglz togglz-spring-boot-starter @@ -125,6 +139,26 @@ rome ${rome.version} + + + de.codecentric + chaos-monkey-spring-boot + ${chaos.monkey.version} + + + + + + org.springframework.boot + spring-boot-starter-log4j + 1.3.8.RELEASE + + + org.graylog2 + gelfj + 1.1.16 + compile + @@ -146,6 +180,7 @@ pl.project13.maven git-commit-id-plugin + ${git-commit-id-plugin.version} @@ -170,7 +205,7 @@ **/*LiveTest.java **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/AutoconfigurationTest.java @@ -189,13 +224,18 @@ - org.baeldung.demo.DemoApplication 8.5.11 2.4.1.Final 1.9.0 + 2.0.0 + 3.6.0 + 3.2.0 + 18.0 + 1.2.0 + 2.2.4 - \ No newline at end of file +
    diff --git a/spring-boot/src/main/java/com/baeldung/chaosmonkey/SpringBootChaosMonkeyApp.java b/spring-boot/src/main/java/com/baeldung/chaosmonkey/SpringBootChaosMonkeyApp.java new file mode 100644 index 0000000000..16a0aea13b --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/chaosmonkey/SpringBootChaosMonkeyApp.java @@ -0,0 +1,15 @@ +package com.baeldung.chaosmonkey; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Created by adi on 8/2/18. + */ +@SpringBootApplication(scanBasePackages = { "com.baeldung.chaosmonkey" }) +public class SpringBootChaosMonkeyApp { + + public static void main(String[] args) { + SpringApplication.run(SpringBootChaosMonkeyApp.class, args); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/chaosmonkey/controller/PermissionsController.java b/spring-boot/src/main/java/com/baeldung/chaosmonkey/controller/PermissionsController.java new file mode 100644 index 0000000000..6ceb117f4e --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/chaosmonkey/controller/PermissionsController.java @@ -0,0 +1,25 @@ +package com.baeldung.chaosmonkey.controller; + +import com.baeldung.chaosmonkey.service.PermissionsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * Created by adi on 8/2/18. + */ +@RestController +@RequestMapping("/permissions") +public class PermissionsController { + + @Autowired private PermissionsService permissionsService; + + @GetMapping + public List getAllPermissions() { + return permissionsService.getAllPermissions(); + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/chaosmonkey/service/PermissionsService.java b/spring-boot/src/main/java/com/baeldung/chaosmonkey/service/PermissionsService.java new file mode 100644 index 0000000000..435e262901 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/chaosmonkey/service/PermissionsService.java @@ -0,0 +1,17 @@ +package com.baeldung.chaosmonkey.service; + +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by adi on 8/2/18. + */ +@Service +public class PermissionsService { + + public List getAllPermissions() { + return Arrays.asList("CREATE", "READ", "UPDATE", "DELETE"); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/ExampleBean.java b/spring-boot/src/main/java/com/baeldung/componentscan/ExampleBean.java new file mode 100644 index 0000000000..9ddcf12d4e --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/ExampleBean.java @@ -0,0 +1,5 @@ +package com.baeldung.componentscan; + +public class ExampleBean { + +} diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java b/spring-boot/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java new file mode 100644 index 0000000000..2377ed7a56 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/springapp/SpringComponentScanApp.java @@ -0,0 +1,38 @@ +package com.baeldung.componentscan.springapp; + +import org.springframework.context.annotation.FilterType; +import org.springframework.stereotype.Component; + +import com.baeldung.componentscan.ExampleBean; +import com.baeldung.componentscan.springapp.flowers.Rose; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +//@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Rose.class)) +//@ComponentScan(basePackages = "com.baeldung.componentscan.springapp") +//@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals") +//@ComponentScan (excludeFilters = @ComponentScan.Filter(type=FilterType.REGEX,pattern="com\\.baeldung\\.componentscan\\.springapp\\.flowers\\..*")) +public class SpringComponentScanApp { + + private static ApplicationContext applicationContext; + + @Bean + public ExampleBean exampleBean() { + return new ExampleBean(); + } + + public static void main(String[] args) { + applicationContext = new AnnotationConfigApplicationContext(SpringComponentScanApp.class); + + for (String beanName : applicationContext.getBeanDefinitionNames()) { + System.out.println(beanName); + } + } + +} \ No newline at end of file diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/springapp/animals/Cat.java b/spring-boot/src/main/java/com/baeldung/componentscan/springapp/animals/Cat.java new file mode 100644 index 0000000000..5f5b482972 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/springapp/animals/Cat.java @@ -0,0 +1,8 @@ +package com.baeldung.componentscan.springapp.animals; + +import org.springframework.stereotype.Component; + +@Component +public class Cat { + +} diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/springapp/animals/Dog.java b/spring-boot/src/main/java/com/baeldung/componentscan/springapp/animals/Dog.java new file mode 100644 index 0000000000..009162b57f --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/springapp/animals/Dog.java @@ -0,0 +1,8 @@ +package com.baeldung.componentscan.springapp.animals; + +import org.springframework.stereotype.Component; + +@Component +public class Dog { + +} diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/springapp/flowers/Rose.java b/spring-boot/src/main/java/com/baeldung/componentscan/springapp/flowers/Rose.java new file mode 100644 index 0000000000..b777b073b9 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/springapp/flowers/Rose.java @@ -0,0 +1,8 @@ +package com.baeldung.componentscan.springapp.flowers; + +import org.springframework.stereotype.Component; + +@Component +public class Rose { + +} diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/SpringBootComponentScanApp.java b/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/SpringBootComponentScanApp.java new file mode 100644 index 0000000000..ba29a4e1f5 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/SpringBootComponentScanApp.java @@ -0,0 +1,37 @@ +package com.baeldung.componentscan.springbootapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.context.annotation.FilterType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +import com.baeldung.componentscan.ExampleBean; +import com.baeldung.componentscan.springbootapp.flowers.Rose; + +@SpringBootApplication +//@ComponentScan(basePackages = "com.baeldung.componentscan.springbootapp.animals") +//@ComponentScan ( excludeFilters = @ComponentScan.Filter(type=FilterType.REGEX,pattern="com\\.baeldung\\.componentscan\\.springbootapp\\.flowers\\..*")) +//@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Rose.class)) + +public class SpringBootComponentScanApp { + private static ApplicationContext applicationContext; + + @Bean + public ExampleBean exampleBean() { + return new ExampleBean(); + } + + public static void main(String[] args) { + applicationContext = SpringApplication.run(SpringBootComponentScanApp.class, args); + checkBeansPresence("cat", "dog", "rose", "exampleBean", "springBootApp"); + + } + + private static void checkBeansPresence(String... beans) { + for (String beanName : beans) { + System.out.println("Is " + beanName + " in ApplicationContext: " + applicationContext.containsBean(beanName)); + } + } +} diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/animals/Cat.java b/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/animals/Cat.java new file mode 100644 index 0000000000..7c43d6a24c --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/animals/Cat.java @@ -0,0 +1,8 @@ +package com.baeldung.componentscan.springbootapp.animals; + +import org.springframework.stereotype.Component; + +@Component +public class Cat { + +} diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/animals/Dog.java b/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/animals/Dog.java new file mode 100644 index 0000000000..145430cb54 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/animals/Dog.java @@ -0,0 +1,8 @@ +package com.baeldung.componentscan.springbootapp.animals; + +import org.springframework.stereotype.Component; + +@Component +public class Dog { + +} diff --git a/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/flowers/Rose.java b/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/flowers/Rose.java new file mode 100644 index 0000000000..0ccf782685 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/componentscan/springbootapp/flowers/Rose.java @@ -0,0 +1,8 @@ +package com.baeldung.componentscan.springbootapp.flowers; + +import org.springframework.stereotype.Component; + +@Component +public class Rose { + +} diff --git a/spring-boot/src/main/java/com/baeldung/displayallbeans/controller/FooController.java b/spring-boot/src/main/java/com/baeldung/displayallbeans/controller/FooController.java index c4a83cc2d9..630820ff9f 100644 --- a/spring-boot/src/main/java/com/baeldung/displayallbeans/controller/FooController.java +++ b/spring-boot/src/main/java/com/baeldung/displayallbeans/controller/FooController.java @@ -3,6 +3,7 @@ package com.baeldung.displayallbeans.controller; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @@ -14,9 +15,9 @@ public class FooController { private FooService fooService; @GetMapping(value = "/displayallbeans") - public String getHeaderAndBody(Map model) { + public ResponseEntity getHeaderAndBody(Map model) { model.put("header", fooService.getHeader()); model.put("message", fooService.getBody()); - return "displayallbeans"; + return ResponseEntity.ok("displayallbeans"); } } diff --git a/spring-boot/src/main/java/com/baeldung/graylog/GraylogDemoApplication.java b/spring-boot/src/main/java/com/baeldung/graylog/GraylogDemoApplication.java new file mode 100644 index 0000000000..be49a0e927 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/graylog/GraylogDemoApplication.java @@ -0,0 +1,17 @@ +package com.baeldung.graylog; + +import org.apache.log4j.Logger; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GraylogDemoApplication { + + private final static Logger LOG = + Logger.getLogger(GraylogDemoApplication.class); + + public static void main(String[] args) { + SpringApplication.run(GraylogDemoApplication.class, args); + LOG.info("Hello from Spring Boot"); + } +} diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java b/spring-boot/src/main/java/com/baeldung/mongodb/Application.java similarity index 60% rename from spring-mvc-email/src/main/java/com/baeldung/spring/Application.java rename to spring-boot/src/main/java/com/baeldung/mongodb/Application.java index bc5d6b3151..092ce3352b 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java +++ b/spring-boot/src/main/java/com/baeldung/mongodb/Application.java @@ -1,12 +1,10 @@ -package com.baeldung.spring; +package com.baeldung.mongodb; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; - @SpringBootApplication -public class Application extends SpringBootServletInitializer { +public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } diff --git a/spring-boot/src/main/java/com/baeldung/properties/ConfigProperties.java b/spring-boot/src/main/java/com/baeldung/properties/ConfigProperties.java new file mode 100644 index 0000000000..863510738b --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/properties/ConfigProperties.java @@ -0,0 +1,117 @@ +package com.baeldung.properties; + +import java.util.List; +import java.util.Map; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Pattern; + +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.NotBlank; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.validation.annotation.Validated; + +@Configuration +@PropertySource("classpath:configprops.properties") +@ConfigurationProperties(prefix = "mail") +@Validated +public class ConfigProperties { + + @Validated + public static class Credentials { + + @Length(max = 4, min = 1) + private String authMethod; + private String username; + private String password; + + public String getAuthMethod() { + return authMethod; + } + + public void setAuthMethod(String authMethod) { + this.authMethod = authMethod; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + } + + @NotBlank + private String host; + + @Min(1025) + @Max(65536) + private int port; + + @Pattern(regexp = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,6}$") + private String from; + + private Credentials credentials; + private List defaultRecipients; + private Map additionalHeaders; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public Credentials getCredentials() { + return credentials; + } + + public void setCredentials(Credentials credentials) { + this.credentials = credentials; + } + + public List getDefaultRecipients() { + return defaultRecipients; + } + + public void setDefaultRecipients(List defaultRecipients) { + this.defaultRecipients = defaultRecipients; + } + + public Map getAdditionalHeaders() { + return additionalHeaders; + } + + public void setAdditionalHeaders(Map additionalHeaders) { + this.additionalHeaders = additionalHeaders; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/properties/ConfigPropertiesDemoApplication.java b/spring-boot/src/main/java/com/baeldung/properties/ConfigPropertiesDemoApplication.java new file mode 100644 index 0000000000..ee9671c755 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/properties/ConfigPropertiesDemoApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.properties; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackageClasses = { ConfigProperties.class, JsonProperties.class, CustomJsonProperties.class }) +public class ConfigPropertiesDemoApplication { + public static void main(String[] args) { + new SpringApplicationBuilder(ConfigPropertiesDemoApplication.class).initializers(new JsonPropertyContextInitializer()) + .run(); + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/properties/CustomJsonProperties.java b/spring-boot/src/main/java/com/baeldung/properties/CustomJsonProperties.java new file mode 100644 index 0000000000..084138ec6f --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/properties/CustomJsonProperties.java @@ -0,0 +1,71 @@ +package com.baeldung.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "custom") +public class CustomJsonProperties { + + private String host; + + private int port; + + private boolean resend; + + private Person sender; + + public static class Person { + + private String name; + private String address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public boolean isResend() { + return resend; + } + + public void setResend(boolean resend) { + this.resend = resend; + } + + public Person getSender() { + return sender; + } + + public void setSender(Person sender) { + this.sender = sender; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/properties/JsonProperties.java b/spring-boot/src/main/java/com/baeldung/properties/JsonProperties.java new file mode 100644 index 0000000000..31b3be14b4 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/properties/JsonProperties.java @@ -0,0 +1,64 @@ +package com.baeldung.properties; + +import java.util.LinkedHashMap; +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +@Component +@PropertySource(value = "classpath:configprops.json", factory = JsonPropertySourceFactory.class) +@ConfigurationProperties +public class JsonProperties { + + private String host; + + private int port; + + private boolean resend; + + private List topics; + + private LinkedHashMap sender; + + public LinkedHashMap getSender() { + return sender; + } + + public void setSender(LinkedHashMap sender) { + this.sender = sender; + } + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public boolean isResend() { + return resend; + } + + public void setResend(boolean resend) { + this.resend = resend; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/properties/JsonPropertyContextInitializer.java b/spring-boot/src/main/java/com/baeldung/properties/JsonPropertyContextInitializer.java new file mode 100644 index 0000000000..0aee149123 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/properties/JsonPropertyContextInitializer.java @@ -0,0 +1,68 @@ +package com.baeldung.properties; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.Resource; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonPropertyContextInitializer implements ApplicationContextInitializer { + + private final static String CUSTOM_PREFIX = "custom."; + + @Override + @SuppressWarnings("unchecked") + public void initialize(ConfigurableApplicationContext configurableApplicationContext) { + try { + Resource resource = configurableApplicationContext.getResource("classpath:configprops.json"); + Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class); + Set set = readValue.entrySet(); + List propertySources = convertEntrySet(set, Optional.empty()); + for (PropertySource propertySource : propertySources) { + configurableApplicationContext.getEnvironment() + .getPropertySources() + .addFirst(propertySource); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static List convertEntrySet(Set entrySet, Optional parentKey) { + return entrySet.stream() + .map((Map.Entry e) -> convertToPropertySourceList(e, parentKey)) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + + private static List convertToPropertySourceList(Map.Entry e, Optional parentKey) { + String key = parentKey.map(s -> s + ".") + .orElse("") + (String) e.getKey(); + Object value = e.getValue(); + return covertToPropertySourceList(key, value); + } + + @SuppressWarnings("unchecked") + private static List covertToPropertySourceList(String key, Object value) { + if (value instanceof LinkedHashMap) { + LinkedHashMap map = (LinkedHashMap) value; + Set entrySet = map.entrySet(); + return convertEntrySet(entrySet, Optional.ofNullable(key)); + } + String finalKey = CUSTOM_PREFIX + key; + return Collections.singletonList(new MapPropertySource(finalKey, Collections.singletonMap(finalKey, value))); + } + +} \ No newline at end of file diff --git a/spring-boot/src/main/java/com/baeldung/properties/JsonPropertySourceFactory.java b/spring-boot/src/main/java/com/baeldung/properties/JsonPropertySourceFactory.java new file mode 100644 index 0000000000..c14d3faea5 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/properties/JsonPropertySourceFactory.java @@ -0,0 +1,21 @@ +package com.baeldung.properties; + +import java.io.IOException; +import java.util.Map; + +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.support.EncodedResource; +import org.springframework.core.io.support.PropertySourceFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonPropertySourceFactory implements PropertySourceFactory { + + @Override + public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException { + Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class); + return new MapPropertySource("json-property", readValue); + } + +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java b/spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java new file mode 100644 index 0000000000..9554facb12 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java @@ -0,0 +1,20 @@ +package org.baeldung.boot.config; + +import org.baeldung.boot.converter.StringToEmployeeConverter; +import org.baeldung.boot.converter.StringToEnumConverterFactory; +import org.baeldung.boot.converter.GenericBigDecimalConverter; +import org.springframework.context.annotation.Configuration; +import org.springframework.format.FormatterRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void addFormatters(FormatterRegistry registry) { + registry.addConverter(new StringToEmployeeConverter()); + registry.addConverterFactory(new StringToEnumConverterFactory()); + registry.addConverter(new GenericBigDecimalConverter()); + } +} + diff --git a/spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java b/spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java new file mode 100644 index 0000000000..8add28fc2d --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java @@ -0,0 +1,31 @@ +package org.baeldung.boot.converter; + +import com.google.common.collect.ImmutableSet; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; +import java.math.BigDecimal; +import java.util.Set; +public class GenericBigDecimalConverter implements GenericConverter { + @Override + public Set getConvertibleTypes () { + ConvertiblePair[] pairs = new ConvertiblePair[] { + new ConvertiblePair(Number.class, BigDecimal.class), + new ConvertiblePair(String.class, BigDecimal.class)}; + return ImmutableSet.copyOf(pairs); + } + @Override + public Object convert (Object source, TypeDescriptor sourceType, + TypeDescriptor targetType) { + if (sourceType.getType() == BigDecimal.class) { + return source; + } + if(sourceType.getType() == String.class) { + String number = (String) source; + return new BigDecimal(number); + } else { + Number number = (Number) source; + BigDecimal converted = new BigDecimal(number.doubleValue()); + return converted.setScale(2, BigDecimal.ROUND_HALF_EVEN); + } + } +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java new file mode 100644 index 0000000000..1bf75b38f0 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java @@ -0,0 +1,14 @@ +package org.baeldung.boot.converter; + +import org.springframework.core.convert.converter.Converter; + +import com.baeldung.toggle.Employee; + +public class StringToEmployeeConverter implements Converter { + + @Override + public Employee convert(String from) { + String[] data = from.split(","); + return new Employee(Long.parseLong(data[0]), Double.parseDouble(data[1])); + } +} diff --git a/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java new file mode 100644 index 0000000000..ddb2cd2b08 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java @@ -0,0 +1,30 @@ +package org.baeldung.boot.converter; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.converter.ConverterFactory; +import org.springframework.stereotype.Component; + +@Component +public class StringToEnumConverterFactory + implements ConverterFactory { + + private static class StringToEnumConverter + implements Converter { + + private Class enumType; + + public StringToEnumConverter(Class enumType) { + this.enumType = enumType; + } + + public T convert(String source) { + return (T) Enum.valueOf(this.enumType, source.trim()); + } + } + + @Override + public Converter getConverter( + Class targetType) { + return new StringToEnumConverter(targetType); + } +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java b/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java new file mode 100644 index 0000000000..27bad4c387 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java @@ -0,0 +1,17 @@ +package org.baeldung.boot.converter.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.toggle.Employee; + +@RestController +public class StringToEmployeeConverterController { + + @GetMapping("/string-to-employee") + public ResponseEntity getStringToEmployee(@RequestParam("employee") Employee employee) { + return ResponseEntity.ok(employee); + } +} diff --git a/spring-boot/src/main/java/org/baeldung/common/error/MyCustomErrorController.java b/spring-boot/src/main/java/org/baeldung/common/error/MyCustomErrorController.java index e4e20de671..6b342a1bfb 100644 --- a/spring-boot/src/main/java/org/baeldung/common/error/MyCustomErrorController.java +++ b/spring-boot/src/main/java/org/baeldung/common/error/MyCustomErrorController.java @@ -13,7 +13,7 @@ public class MyCustomErrorController implements ErrorController { @GetMapping(value = PATH) public String error() { - return "Error heaven"; + return "Error haven"; } @Override diff --git a/spring-boot/src/main/java/org/baeldung/common/error/controller/ErrorController.java b/spring-boot/src/main/java/org/baeldung/common/error/controller/ErrorController.java index d503f5da6d..3e26f8c9d8 100644 --- a/spring-boot/src/main/java/org/baeldung/common/error/controller/ErrorController.java +++ b/spring-boot/src/main/java/org/baeldung/common/error/controller/ErrorController.java @@ -14,9 +14,9 @@ public class ErrorController { return "Error Code: 400 occured."; } - @GetMapping("/errorHeaven") + @GetMapping("/errorHaven") String errorHeaven() { - return "You have reached the heaven of errors!!!"; + return "You have reached the haven of errors!!!"; } } diff --git a/spring-boot/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java b/spring-boot/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java index 2d955bac9b..f6ab017298 100644 --- a/spring-boot/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java +++ b/spring-boot/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java @@ -19,7 +19,7 @@ public class MyServletContainerCustomizationBean implements WebServerFactoryCust container.setContextPath("/springbootapp"); container.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400")); - container.addErrorPages(new ErrorPage("/errorHeaven")); + container.addErrorPages(new ErrorPage("/errorHaven")); } } diff --git a/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java b/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java index cb0304fc41..395d68060b 100644 --- a/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java +++ b/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java @@ -1,13 +1,15 @@ package org.baeldung.properties; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.ComponentScan; -@EnableAutoConfiguration -@ComponentScan(basePackageClasses = ConfigProperties.class) +@SpringBootApplication +@ComponentScan(basePackageClasses = { ConfigProperties.class, JsonProperties.class, CustomJsonProperties.class }) public class ConfigPropertiesDemoApplication { public static void main(String[] args) { - SpringApplication.run(ConfigPropertiesDemoApplication.class); + new SpringApplicationBuilder(ConfigPropertiesDemoApplication.class).initializers(new JsonPropertyContextInitializer()) + .run(); } + } diff --git a/spring-boot/src/main/java/org/baeldung/properties/CustomJsonProperties.java b/spring-boot/src/main/java/org/baeldung/properties/CustomJsonProperties.java new file mode 100644 index 0000000000..3fae8a8e98 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/CustomJsonProperties.java @@ -0,0 +1,71 @@ +package org.baeldung.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "custom") +public class CustomJsonProperties { + + private String host; + + private int port; + + private boolean resend; + + private Person sender; + + public static class Person { + + private String name; + private String address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public boolean isResend() { + return resend; + } + + public void setResend(boolean resend) { + this.resend = resend; + } + + public Person getSender() { + return sender; + } + + public void setSender(Person sender) { + this.sender = sender; + } +} diff --git a/spring-boot/src/main/java/org/baeldung/properties/JsonProperties.java b/spring-boot/src/main/java/org/baeldung/properties/JsonProperties.java new file mode 100644 index 0000000000..5c31cd1344 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/JsonProperties.java @@ -0,0 +1,64 @@ +package org.baeldung.properties; + +import java.util.LinkedHashMap; +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +@Component +@PropertySource(value = "classpath:configprops.json", factory = JsonPropertySourceFactory.class) +@ConfigurationProperties +public class JsonProperties { + + private String host; + + private int port; + + private boolean resend; + + private List topics; + + private LinkedHashMap sender; + + public LinkedHashMap getSender() { + return sender; + } + + public void setSender(LinkedHashMap sender) { + this.sender = sender; + } + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public boolean isResend() { + return resend; + } + + public void setResend(boolean resend) { + this.resend = resend; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } +} diff --git a/spring-boot/src/main/java/org/baeldung/properties/JsonPropertyContextInitializer.java b/spring-boot/src/main/java/org/baeldung/properties/JsonPropertyContextInitializer.java new file mode 100644 index 0000000000..fd9b3f35a5 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/JsonPropertyContextInitializer.java @@ -0,0 +1,68 @@ +package org.baeldung.properties; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.Resource; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonPropertyContextInitializer implements ApplicationContextInitializer { + + private final static String CUSTOM_PREFIX = "custom."; + + @Override + @SuppressWarnings("unchecked") + public void initialize(ConfigurableApplicationContext configurableApplicationContext) { + try { + Resource resource = configurableApplicationContext.getResource("classpath:configprops.json"); + Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class); + Set set = readValue.entrySet(); + List propertySources = convertEntrySet(set, Optional.empty()); + for (PropertySource propertySource : propertySources) { + configurableApplicationContext.getEnvironment() + .getPropertySources() + .addFirst(propertySource); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static List convertEntrySet(Set entrySet, Optional parentKey) { + return entrySet.stream() + .map((Map.Entry e) -> convertToPropertySourceList(e, parentKey)) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + + private static List convertToPropertySourceList(Map.Entry e, Optional parentKey) { + String key = parentKey.map(s -> s + ".") + .orElse("") + (String) e.getKey(); + Object value = e.getValue(); + return covertToPropertySourceList(key, value); + } + + @SuppressWarnings("unchecked") + private static List covertToPropertySourceList(String key, Object value) { + if (value instanceof LinkedHashMap) { + LinkedHashMap map = (LinkedHashMap) value; + Set entrySet = map.entrySet(); + return convertEntrySet(entrySet, Optional.ofNullable(key)); + } + String finalKey = CUSTOM_PREFIX + key; + return Collections.singletonList(new MapPropertySource(finalKey, Collections.singletonMap(finalKey, value))); + } + +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/properties/JsonPropertySourceFactory.java b/spring-boot/src/main/java/org/baeldung/properties/JsonPropertySourceFactory.java new file mode 100644 index 0000000000..9578179519 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/JsonPropertySourceFactory.java @@ -0,0 +1,21 @@ +package org.baeldung.properties; + +import java.io.IOException; +import java.util.Map; + +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.support.EncodedResource; +import org.springframework.core.io.support.PropertySourceFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonPropertySourceFactory implements PropertySourceFactory { + + @Override + public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException { + Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class); + return new MapPropertySource("json-property", readValue); + } + +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java b/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java index cba504b6c6..7335af2616 100644 --- a/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java +++ b/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java @@ -24,8 +24,6 @@ public interface UserRepository extends JpaRepository { Optional findOneByName(String name); - Stream findAllByName(String name); - @Async CompletableFuture findOneByStatus(Integer status); diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties index 8c02e528ab..629e880940 100644 --- a/spring-boot/src/main/resources/application.properties +++ b/spring-boot/src/main/resources/application.properties @@ -43,3 +43,34 @@ servlet.mapping=/dispatcherExampleURL #spring.banner.image.invert= //TODO contactInfoType=email + +#chaos monkey for spring boot props +management.endpoint.chaosmonkey.enabled=true +management.endpoint.chaosmonkeyjmx.enabled=true + +spring.profiles.active=chaos-monkey +#Determine whether should execute or not +chaos.monkey.enabled=true +#How many requests are to be attacked. 1: attack each request; 5: each 5th request is attacked +chaos.monkey.assaults.level=1 +#Minimum latency in ms added to the request +chaos.monkey.assaults.latencyRangeStart=3000 +#Maximum latency in ms added to the request +chaos.monkey.assaults.latencyRangeEnd=15000 +#Latency assault active +chaos.monkey.assaults.latencyActive=true +#Exception assault active +chaos.monkey.assaults.exceptionsActive=false +#AppKiller assault active +chaos.monkey.assaults.killApplicationActive=false +#Controller watcher active +chaos.monkey.watcher.controller=false +#RestController watcher active +chaos.monkey.watcher.restController=false +#Service watcher active +chaos.monkey.watcher.service=true +#Repository watcher active +chaos.monkey.watcher.repository=false +#Component watcher active +chaos.monkey.watcher.component=false + diff --git a/spring-boot/src/main/resources/configprops.json b/spring-boot/src/main/resources/configprops.json new file mode 100644 index 0000000000..1602663775 --- /dev/null +++ b/spring-boot/src/main/resources/configprops.json @@ -0,0 +1,10 @@ +{ + "host" : "mailer@mail.com", + "port" : 9090, + "resend" : true, + "topics" : ["spring", "boot"], + "sender" : { + "name": "sender", + "address": "street" + } +} diff --git a/spring-boot/src/main/resources/log4j.xml b/spring-boot/src/main/resources/log4j.xml new file mode 100644 index 0000000000..61c1b7b229 --- /dev/null +++ b/spring-boot/src/main/resources/log4j.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-boot/src/main/resources/logback.xml b/spring-boot/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-boot/src/main/resources/logback.xml +++ b/spring-boot/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-boot/src/test/java/com/baeldung/mongodb/ManualEmbeddedMongoDbIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/mongodb/ManualEmbeddedMongoDbIntegrationTest.java new file mode 100644 index 0000000000..30a4d61fbd --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/mongodb/ManualEmbeddedMongoDbIntegrationTest.java @@ -0,0 +1,62 @@ +package com.baeldung.mongodb; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.data.mongodb.core.MongoTemplate; + +import com.mongodb.BasicDBObjectBuilder; +import com.mongodb.DBObject; +import com.mongodb.MongoClient; + +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.IMongodConfig; +import de.flapdoodle.embed.mongo.config.MongodConfigBuilder; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; + +class ManualEmbeddedMongoDbIntegrationTest { + private MongodExecutable mongodExecutable; + private MongoTemplate mongoTemplate; + + @AfterEach + void clean() { + mongodExecutable.stop(); + } + + @BeforeEach + void setup() throws Exception { + String ip = "localhost"; + int port = 27017; + + IMongodConfig mongodConfig = new MongodConfigBuilder().version(Version.Main.PRODUCTION) + .net(new Net(ip, port, Network.localhostIsIPv6())) + .build(); + + MongodStarter starter = MongodStarter.getDefaultInstance(); + mongodExecutable = starter.prepare(mongodConfig); + mongodExecutable.start(); + mongoTemplate = new MongoTemplate(new MongoClient(ip, port), "test"); + } + + @DisplayName("Given object When save object using MongoDB template Then object can be found") + @Test + void test() throws Exception { + // given + DBObject objectToSave = BasicDBObjectBuilder.start() + .add("key", "value") + .get(); + + // when + mongoTemplate.save(objectToSave, "collection"); + + // then + assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key") + .containsOnly("value"); + } +} diff --git a/spring-boot/src/test/java/com/baeldung/mongodb/MongoDbSpringIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/mongodb/MongoDbSpringIntegrationTest.java new file mode 100644 index 0000000000..5431217c3e --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/mongodb/MongoDbSpringIntegrationTest.java @@ -0,0 +1,36 @@ +package com.baeldung.mongodb; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.mongodb.BasicDBObjectBuilder; +import com.mongodb.DBObject; + +@ContextConfiguration(classes = Application.class) +@DataMongoTest +@ExtendWith(SpringExtension.class) +public class MongoDbSpringIntegrationTest { + @DisplayName("Given object When save object using MongoDB template Then object can be found") + @Test + public void test(@Autowired MongoTemplate mongoTemplate) { + // given + DBObject objectToSave = BasicDBObjectBuilder.start() + .add("key", "value") + .get(); + + // when + mongoTemplate.save(objectToSave, "collection"); + + // then + assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key") + .containsOnly("value"); + } +} diff --git a/spring-boot/src/test/java/com/baeldung/properties/ConfigPropertiesIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/properties/ConfigPropertiesIntegrationTest.java new file mode 100644 index 0000000000..3a4b6551b1 --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/properties/ConfigPropertiesIntegrationTest.java @@ -0,0 +1,45 @@ +package com.baeldung.properties; + +import org.baeldung.properties.ConfigProperties; +import org.baeldung.properties.ConfigPropertiesDemoApplication; +import org.junit.Assert; +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.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ConfigPropertiesDemoApplication.class) +@TestPropertySource("classpath:configprops-test.properties") +public class ConfigPropertiesIntegrationTest { + + @Autowired + private ConfigProperties properties; + + @Test + public void whenSimplePropertyQueriedthenReturnsProperty() throws Exception { + Assert.assertTrue("From address is read as null!", properties.getFrom() != null); + } + + @Test + public void whenListPropertyQueriedthenReturnsProperty() throws Exception { + Assert.assertTrue("Couldn't bind list property!", properties.getDefaultRecipients().size() == 2); + Assert.assertTrue("Incorrectly bound list property. Expected 2 entries!", properties.getDefaultRecipients().size() == 2); + } + + @Test + public void whenMapPropertyQueriedthenReturnsProperty() throws Exception { + Assert.assertTrue("Couldn't bind map property!", properties.getAdditionalHeaders() != null); + Assert.assertTrue("Incorrectly bound map property. Expected 3 Entries!", properties.getAdditionalHeaders().size() == 3); + } + + @Test + public void whenObjectPropertyQueriedthenReturnsProperty() throws Exception { + Assert.assertTrue("Couldn't bind map property!", properties.getCredentials() != null); + Assert.assertTrue("Incorrectly bound object property!", properties.getCredentials().getAuthMethod().equals("SHA1")); + Assert.assertTrue("Incorrectly bound object property!", properties.getCredentials().getUsername().equals("john")); + Assert.assertTrue("Incorrectly bound object property!", properties.getCredentials().getPassword().equals("password")); + } +} diff --git a/spring-boot/src/test/java/com/baeldung/properties/JsonPropertiesIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/properties/JsonPropertiesIntegrationTest.java new file mode 100644 index 0000000000..48c551d1dd --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/properties/JsonPropertiesIntegrationTest.java @@ -0,0 +1,63 @@ +package com.baeldung.properties; + +import java.util.Arrays; + +import org.baeldung.properties.ConfigPropertiesDemoApplication; +import org.baeldung.properties.CustomJsonProperties; +import org.baeldung.properties.JsonProperties; +import org.baeldung.properties.JsonPropertyContextInitializer; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ConfigPropertiesDemoApplication.class, initializers = JsonPropertyContextInitializer.class) +public class JsonPropertiesIntegrationTest { + + @Autowired + private JsonProperties jsonProperties; + + @Autowired + private CustomJsonProperties customJsonProperties; + + @Test + public void whenPropertiesLoadedViaJsonPropertySource_thenLoadFlatValues() { + Assert.assertEquals("mailer@mail.com", jsonProperties.getHost()); + Assert.assertEquals(9090, jsonProperties.getPort()); + Assert.assertTrue(jsonProperties.isResend()); + } + + @Test + public void whenPropertiesLoadedViaJsonPropertySource_thenLoadListValues() { + Assert.assertThat(jsonProperties.getTopics(), Matchers.is(Arrays.asList("spring", "boot"))); + } + + @Test + public void whenPropertiesLoadedViaJsonPropertySource_thenNestedLoadedAsMap() { + Assert.assertEquals("sender", jsonProperties.getSender() + .get("name")); + Assert.assertEquals("street", jsonProperties.getSender() + .get("address")); + } + + @Test + public void whenLoadedIntoEnvironment_thenFlatValuesPopulated() { + Assert.assertEquals("mailer@mail.com", customJsonProperties.getHost()); + Assert.assertEquals(9090, customJsonProperties.getPort()); + Assert.assertTrue(customJsonProperties.isResend()); + } + + @Test + public void whenLoadedIntoEnvironment_thenValuesLoadedIntoClassObject() { + Assert.assertNotNull(customJsonProperties.getSender()); + Assert.assertEquals("sender", customJsonProperties.getSender() + .getName()); + Assert.assertEquals("street", customJsonProperties.getSender() + .getAddress()); + } + +} diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java index 4658861162..baa4f70e83 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java @@ -4,17 +4,15 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertThat; -import org.baeldung.boot.ApplicationIntegrationTest; +import org.baeldung.boot.DemoApplicationIntegrationTest; import org.baeldung.demo.model.Foo; -import org.baeldung.session.exception.repository.FooRepository; +import org.baeldung.demo.repository.FooRepository; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.TestPropertySource; import org.springframework.transaction.annotation.Transactional; @Transactional -@TestPropertySource("classpath:exception-hibernate.properties") -public class HibernateSessionIntegrationTest extends ApplicationIntegrationTest { +public class HibernateSessionIntegrationTest extends DemoApplicationIntegrationTest { @Autowired private FooRepository fooRepository; @@ -23,7 +21,7 @@ public class HibernateSessionIntegrationTest extends ApplicationIntegrationTest Foo foo = new Foo("Exception Solved"); fooRepository.save(foo); foo = null; - foo = fooRepository.get(1); + foo = fooRepository.findByName("Exception Solved"); assertThat(foo, notNullValue()); assertThat(foo.getId(), is(1)); diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java index 8de7068949..5c8d10223b 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java @@ -6,9 +6,11 @@ import org.baeldung.session.exception.repository.FooRepository; import org.hibernate.HibernateException; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.TestPropertySource; import org.springframework.transaction.annotation.Transactional; @Transactional +@TestPropertySource("classpath:exception-hibernate.properties") public class NoHibernateSessionIntegrationTest extends ApplicationIntegrationTest { @Autowired private FooRepository fooRepository; diff --git a/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeServiceImplIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeServiceImplIntegrationTest.java index 4eec62db13..df28111a57 100644 --- a/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeServiceImplIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeServiceImplIntegrationTest.java @@ -1,9 +1,11 @@ package org.baeldung.demo.boottest; -import org.baeldung.demo.boottest.Employee; -import org.baeldung.demo.boottest.EmployeeRepository; -import org.baeldung.demo.boottest.EmployeeService; -import org.baeldung.demo.boottest.EmployeeServiceImpl; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -15,11 +17,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Bean; import org.springframework.test.context.junit4.SpringRunner; -import java.util.Arrays; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - @RunWith(SpringRunner.class) public class EmployeeServiceImplIntegrationTest { @@ -50,9 +47,9 @@ public class EmployeeServiceImplIntegrationTest { Mockito.when(employeeRepository.findByName(john.getName())).thenReturn(john); Mockito.when(employeeRepository.findByName(alex.getName())).thenReturn(alex); Mockito.when(employeeRepository.findByName("wrong_name")).thenReturn(null); - Mockito.when(employeeRepository.findById(john.getId()).orElse(null)).thenReturn(john); + Mockito.when(employeeRepository.findById(john.getId())).thenReturn(Optional.of(john)); Mockito.when(employeeRepository.findAll()).thenReturn(allEmployees); - Mockito.when(employeeRepository.findById(-99L).orElse(null)).thenReturn(null); + Mockito.when(employeeRepository.findById(-99L)).thenReturn(Optional.empty()); } @Test diff --git a/spring-boot/src/test/java/org/baeldung/properties/JsonPropertiesIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/properties/JsonPropertiesIntegrationTest.java new file mode 100644 index 0000000000..e3d4c62953 --- /dev/null +++ b/spring-boot/src/test/java/org/baeldung/properties/JsonPropertiesIntegrationTest.java @@ -0,0 +1,59 @@ +package org.baeldung.properties; + +import java.util.Arrays; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ConfigPropertiesDemoApplication.class, initializers = JsonPropertyContextInitializer.class) +public class JsonPropertiesIntegrationTest { + + @Autowired + private JsonProperties jsonProperties; + + @Autowired + private CustomJsonProperties customJsonProperties; + + @Test + public void whenPropertiesLoadedViaJsonPropertySource_thenLoadFlatValues() { + Assert.assertEquals("mailer@mail.com", jsonProperties.getHost()); + Assert.assertEquals(9090, jsonProperties.getPort()); + Assert.assertTrue(jsonProperties.isResend()); + } + + @Test + public void whenPropertiesLoadedViaJsonPropertySource_thenLoadListValues() { + Assert.assertThat(jsonProperties.getTopics(), Matchers.is(Arrays.asList("spring", "boot"))); + } + + @Test + public void whenPropertiesLoadedViaJsonPropertySource_thenNestedLoadedAsMap() { + Assert.assertEquals("sender", jsonProperties.getSender() + .get("name")); + Assert.assertEquals("street", jsonProperties.getSender() + .get("address")); + } + + @Test + public void whenLoadedIntoEnvironment_thenFlatValuesPopulated() { + Assert.assertEquals("mailer@mail.com", customJsonProperties.getHost()); + Assert.assertEquals(9090, customJsonProperties.getPort()); + Assert.assertTrue(customJsonProperties.isResend()); + } + + @Test + public void whenLoadedIntoEnvironment_thenValuesLoadedIntoClassObject() { + Assert.assertNotNull(customJsonProperties.getSender()); + Assert.assertEquals("sender", customJsonProperties.getSender() + .getName()); + Assert.assertEquals("street", customJsonProperties.getSender() + .getAddress()); + } + +} diff --git a/spring-boot/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java index 72d204820e..04bb1170f8 100644 --- a/spring-boot/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/repository/UserRepositoryIntegrationTest.java @@ -52,30 +52,6 @@ public class UserRepositoryIntegrationTest { .getName()).isEqualTo(USER_NAME_ADAM); } - @Test - @Transactional - public void givenUsersWithSameNameInDBWhenFindAllByNameThenReturnStreamOfUsers() { - User user1 = new User(); - user1.setName(USER_NAME_ADAM); - userRepository.save(user1); - - User user2 = new User(); - user2.setName(USER_NAME_ADAM); - userRepository.save(user2); - - User user3 = new User(); - user3.setName(USER_NAME_ADAM); - userRepository.save(user3); - - User user4 = new User(); - user4.setName("SAMPLE"); - userRepository.save(user4); - - try (Stream foundUsersStream = userRepository.findAllByName(USER_NAME_ADAM)) { - assertThat(foundUsersStream.count()).isEqualTo(3l); - } - } - @Test public void givenUserInDBWhenFindOneByStatusAsyncThenReturnCompletableFutureUser() throws ExecutionException, InterruptedException { User user = new User(); diff --git a/spring-cloud-bus/pom.xml b/spring-cloud-bus/pom.xml new file mode 100644 index 0000000000..d493c4e984 --- /dev/null +++ b/spring-cloud-bus/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + com.baeldung.spring.cloud + spring-cloud-bus + 1.0.0-SNAPSHOT + pom + + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 + + + + spring-cloud-config-client + spring-cloud-config-server + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud-dependencies.version} + pom + import + + + + + + Brixton.SR7 + + + diff --git a/spring-cloud-bus/spring-cloud-config-client/pom.xml b/spring-cloud-bus/spring-cloud-config-client/pom.xml index 61660b6d8f..b2b69303bf 100644 --- a/spring-cloud-bus/spring-cloud-config-client/pom.xml +++ b/spring-cloud-bus/spring-cloud-config-client/pom.xml @@ -1,81 +1,53 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + spring-cloud-config-client + jar - com.baeldung.spring.cloud - spring-cloud-config-client - 0.0.1-SNAPSHOT - jar + spring-cloud-config-client + Demo Spring Cloud Config Client - spring-cloud-config-client - Demo Spring Cloud Config Client + + spring-cloud-bus + com.baeldung.spring.cloud + 1.0.0-SNAPSHOT + - - org.springframework.boot - spring-boot-starter-parent - 1.5.4.RELEASE - + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.boot + spring-boot-starter-web + - - UTF-8 - UTF-8 - 1.8 - Dalston.SR1 - + + org.springframework.boot + spring-boot-starter-test + test + - - - org.springframework.cloud - spring-cloud-starter-config - 1.3.1.RELEASE - - - org.springframework.boot - spring-boot-starter-web - 1.5.4.RELEASE - + + org.springframework.boot + spring-boot-actuator + - - org.springframework.boot - spring-boot-starter-test - 1.5.4.RELEASE - test - + + org.springframework.cloud + spring-cloud-starter-bus-amqp + + - - org.springframework.boot - spring-boot-actuator - 1.5.4.RELEASE - - - - org.springframework.cloud - spring-cloud-starter-bus-amqp - 1.3.1.RELEASE - - - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - 1.5.4.RELEASE - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/spring-cloud-bus/spring-cloud-config-client/src/main/resources/logback.xml b/spring-cloud-bus/spring-cloud-config-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud-bus/spring-cloud-config-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-mvc/src/test/java/com/baeldung/springbootmvc/SpringBootMvcApplicationTests.java b/spring-cloud-bus/spring-cloud-config-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 56% rename from spring-boot-mvc/src/test/java/com/baeldung/springbootmvc/SpringBootMvcApplicationTests.java rename to spring-cloud-bus/spring-cloud-config-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 1add635ed8..c0298daeb1 100644 --- a/spring-boot-mvc/src/test/java/com/baeldung/springbootmvc/SpringBootMvcApplicationTests.java +++ b/spring-cloud-bus/spring-cloud-config-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,13 +1,15 @@ -package com.baeldung.springbootmvc; +package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.SpringCloudConfigClientApplication; + @RunWith(SpringRunner.class) -@SpringBootTest -public class SpringBootMvcApplicationTests { +@SpringBootTest(classes = SpringCloudConfigClientApplication.class) +public class SpringContextIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud-bus/spring-cloud-config-server/pom.xml b/spring-cloud-bus/spring-cloud-config-server/pom.xml index 2fb6afb5a0..f50b78ff18 100644 --- a/spring-cloud-bus/spring-cloud-config-server/pom.xml +++ b/spring-cloud-bus/spring-cloud-config-server/pom.xml @@ -1,82 +1,54 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + spring-cloud-config-server + jar - com.baeldung.spring.cloud - spring-cloud-config-server - 0.0.1-SNAPSHOT - jar + spring-cloud-config-server + Demo Spring Cloud Config Server - spring-cloud-config-server - Demo Spring Cloud Config Server + + spring-cloud-bus + com.baeldung.spring.cloud + 1.0.0-SNAPSHOT + - - org.springframework.boot - spring-boot-starter-parent - 1.5.4.RELEASE - + + + org.springframework.cloud + spring-cloud-config-server + - - UTF-8 - UTF-8 - 1.8 - Dalston.SR1 - + + org.springframework.boot + spring-boot-starter-security + - - - org.springframework.cloud - spring-cloud-config-server - 1.3.1.RELEASE - + + org.springframework.boot + spring-boot-starter-test + test + - - org.springframework.boot - spring-boot-starter-security - 1.5.4.RELEASE - + + org.springframework.cloud + spring-cloud-config-monitor + - - org.springframework.boot - spring-boot-starter-test - 1.5.4.RELEASE - test - + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + - - org.springframework.cloud - spring-cloud-config-monitor - 1.3.1.RELEASE - - - - org.springframework.cloud - spring-cloud-starter-stream-rabbit - 1.2.1.RELEASE - - - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - 1.5.4.RELEASE - - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/spring-cloud-bus/spring-cloud-config-server/src/main/resources/logback.xml b/spring-cloud-bus/spring-cloud-config-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud-bus/spring-cloud-config-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-bus/spring-cloud-config-client/src/test/java/com/baeldung/SpringCloudConfigClientApplicationTests.java b/spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringCloudConfigServerApplicationIntegrationTest.java similarity index 81% rename from spring-cloud-bus/spring-cloud-config-client/src/test/java/com/baeldung/SpringCloudConfigClientApplicationTests.java rename to spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringCloudConfigServerApplicationIntegrationTest.java index 3b361f385a..12e0928ad8 100644 --- a/spring-cloud-bus/spring-cloud-config-client/src/test/java/com/baeldung/SpringCloudConfigClientApplicationTests.java +++ b/spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringCloudConfigServerApplicationIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class SpringCloudConfigClientApplicationTests { +public class SpringCloudConfigServerApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud/spring-cloud-kubernetes/demo-backend/src/test/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplicationIntegrationTest.java b/spring-cloud-bus/spring-cloud-config-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 56% rename from spring-cloud/spring-cloud-kubernetes/demo-backend/src/test/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplicationIntegrationTest.java rename to spring-cloud-bus/spring-cloud-config-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 2440b97aaf..c43bb9f067 100644 --- a/spring-cloud/spring-cloud-kubernetes/demo-backend/src/test/java/com/baeldung/spring/cloud/kubernetes/backend/KubernetesBackendApplicationIntegrationTest.java +++ b/spring-cloud-bus/spring-cloud-config-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,13 +1,15 @@ -package com.baeldung.spring.cloud.kubernetes.backend; +package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.SpringCloudConfigServerApplication; + @RunWith(SpringRunner.class) -@SpringBootTest -public class KubernetesBackendApplicationIntegrationTest { +@SpringBootTest(classes = SpringCloudConfigServerApplication.class) +public class SpringContextIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud-data-flow/batch-job/pom.xml b/spring-cloud-data-flow/batch-job/pom.xml index 08439065a4..7bc2909f4c 100644 --- a/spring-cloud-data-flow/batch-job/pom.xml +++ b/spring-cloud-data-flow/batch-job/pom.xml @@ -1,13 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.baeldung.spring.cloud batch-job 0.0.1-SNAPSHOT jar - batch-job Demo project for Spring Boot @@ -18,10 +16,6 @@ ../../parent-boot-1 - - 1.0.3.RELEASE - - org.springframework.cloud @@ -53,4 +47,8 @@ + + 1.0.3.RELEASE + + diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java index f717f0f644..30f6ff6897 100644 --- a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java +++ b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/BatchJobApplication.java @@ -1,12 +1,10 @@ package org.baeldung.spring.cloud; -import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.task.configuration.EnableTask; @EnableTask -@EnableBatchProcessing @SpringBootApplication public class BatchJobApplication { diff --git a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java index dc6a5e2827..7ce867b60a 100644 --- a/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java +++ b/spring-cloud-data-flow/batch-job/src/main/java/org/baeldung/spring/cloud/JobConfiguration.java @@ -2,9 +2,9 @@ package org.baeldung.spring.cloud; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.batch.core.Job; import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; import org.springframework.batch.core.scope.context.ChunkContext; @@ -15,6 +15,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration +@EnableBatchProcessing public class JobConfiguration { private static final Log logger = LogFactory.getLog(JobConfiguration.class); diff --git a/spring-cloud-data-flow/batch-job/src/main/resources/logback.xml b/spring-cloud-data-flow/batch-job/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud-data-flow/batch-job/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..b87ace74a4 --- /dev/null +++ b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.baeldung.spring.cloud.JobConfiguration; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +@ContextConfiguration(classes = JobConfiguration.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java index f8dfdec197..1f77351acc 100644 --- a/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java +++ b/spring-cloud-data-flow/batch-job/src/test/java/org/baeldung/spring/cloud/BatchJobApplicationIntegrationTest.java @@ -3,10 +3,12 @@ package org.baeldung.spring.cloud; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest +@ContextConfiguration(classes = JobConfiguration.class) public class BatchJobApplicationIntegrationTest { @Test diff --git a/spring-cloud-data-flow/data-flow-server/pom.xml b/spring-cloud-data-flow/data-flow-server/pom.xml index 1b81e1ba2d..0133d65978 100644 --- a/spring-cloud-data-flow/data-flow-server/pom.xml +++ b/spring-cloud-data-flow/data-flow-server/pom.xml @@ -1,13 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.spring.cloud data-flow-server 0.0.1-SNAPSHOT jar - data-flow-server Demo project for Spring Boot @@ -18,11 +17,6 @@ ../../parent-boot-1 - - 1.1.0.RELEASE - Brixton.SR7 - - org.springframework.cloud @@ -49,4 +43,9 @@ + + 1.1.0.RELEASE + Brixton.SR7 + + diff --git a/spring-cloud-data-flow/data-flow-server/src/main/resources/logback.xml b/spring-cloud-data-flow/data-flow-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud-data-flow/data-flow-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..eb2a5c54ef --- /dev/null +++ b/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.spring.cloud.DataFlowServerApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = DataFlowServerApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java b/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java index bb8660b816..9eba12fc12 100644 --- a/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java +++ b/spring-cloud-data-flow/data-flow-server/src/test/java/org/baeldung/spring/cloud/DataFlowServerApplicationIntegrationTest.java @@ -2,7 +2,14 @@ package org.baeldung.spring.cloud; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @@ -13,4 +20,24 @@ public class DataFlowServerApplicationIntegrationTest { public void contextLoads() { } + @EnableRedisHttpSession + @Configuration + static class Config { + + @Bean + @SuppressWarnings("unchecked") + public RedisSerializer defaultRedisSerializer() { + return Mockito.mock(RedisSerializer.class); + } + + @Bean + public RedisConnectionFactory connectionFactory() { + + RedisConnectionFactory factory = Mockito.mock(RedisConnectionFactory.class); + RedisConnection connection = Mockito.mock(RedisConnection.class); + Mockito.when(factory.getConnection()).thenReturn(connection); + + return factory; + } + } } diff --git a/spring-cloud-data-flow/data-flow-shell/pom.xml b/spring-cloud-data-flow/data-flow-shell/pom.xml index 0166aa79c2..e4ec145277 100644 --- a/spring-cloud-data-flow/data-flow-shell/pom.xml +++ b/spring-cloud-data-flow/data-flow-shell/pom.xml @@ -1,13 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.spring.cloud data-flow-shell 0.0.1-SNAPSHOT jar - data-flow-shell Demo project for Spring Boot @@ -18,11 +17,6 @@ ../../parent-boot-1 - - Brixton.SR7 - 1.1.0.RELEASE - - org.springframework.cloud @@ -49,4 +43,9 @@ + + Brixton.SR7 + 1.1.0.RELEASE + + diff --git a/spring-cloud-data-flow/data-flow-shell/src/main/resources/logback.xml b/spring-cloud-data-flow/data-flow-shell/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud-data-flow/data-flow-shell/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..28dbc9a8d8 --- /dev/null +++ b/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.baeldung.spring.cloud.DataFlowShellApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = DataFlowShellApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/spring/cloud/DataFlowShellApplicationIntegrationTest.java b/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/spring/cloud/DataFlowShellApplicationIntegrationTest.java deleted file mode 100644 index 5ab3292388..0000000000 --- a/spring-cloud-data-flow/data-flow-shell/src/test/java/org/baeldung/spring/cloud/DataFlowShellApplicationIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.spring.cloud; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class DataFlowShellApplicationIntegrationTest { - - @Test - public void contextLoads() { - } - -} diff --git a/spring-cloud-data-flow/etl/README.MD b/spring-cloud-data-flow/etl/README.MD new file mode 100644 index 0000000000..0cbb460b01 --- /dev/null +++ b/spring-cloud-data-flow/etl/README.MD @@ -0,0 +1,9 @@ +# Overview +This is an example of a ETL stream pipeline, mixing a starter application with custom transform and sink. + +# Applications +JDBC Source - Application Starter distributed by default + +customer-transform - Custom application to transform the data + +customer-mongodb-sink - Custom application to sink the data diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml b/spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml new file mode 100644 index 0000000000..468d8e17d0 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + com.customer + customer-mongodb-sink + jar + + customer-mongodb-sink + Example ETL Load Project + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../../parent-boot-2 + + + + UTF-8 + UTF-8 + 1.8 + Finchley.SR1 + + + + + org.springframework.cloud + spring-cloud-stream + + + org.springframework.cloud + spring-cloud-stream-binder-rabbit + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.cloud + spring-cloud-stream-test-support + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java new file mode 100644 index 0000000000..cf44aec5b7 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/Customer.java @@ -0,0 +1,27 @@ +package com.customer.customermongodbsink; + +import org.springframework.data.mongodb.core.mapping.Document; + +@Document(collection = "customer") +public class Customer { + + private Long id; + private String 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; + } + +} \ No newline at end of file diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java new file mode 100644 index 0000000000..c841daea8a --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerListener.java @@ -0,0 +1,18 @@ +package com.customer.customermongodbsink; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.cloud.stream.messaging.Sink; + +@EnableBinding(Sink.class) +public class CustomerListener { + + @Autowired + private CustomerRepository repository; + + @StreamListener(Sink.INPUT) + public void save(Customer customer) { + repository.save(customer); + } +} diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java new file mode 100644 index 0000000000..2ef311457e --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerMongodbSinkApplication.java @@ -0,0 +1,12 @@ +package com.customer.customermongodbsink; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomerMongodbSinkApplication { + + public static void main(String[] args) { + SpringApplication.run(CustomerMongodbSinkApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java new file mode 100644 index 0000000000..f921ff51cf --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/java/com/customer/customermongodbsink/CustomerRepository.java @@ -0,0 +1,9 @@ +package com.customer.customermongodbsink; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CustomerRepository extends MongoRepository { + +} \ No newline at end of file diff --git a/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties b/spring-cloud-data-flow/etl/customer-mongodb-sink/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud-data-flow/etl/customer-transform/pom.xml b/spring-cloud-data-flow/etl/customer-transform/pom.xml new file mode 100644 index 0000000000..bc4b648907 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-transform/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + com.customer + customer-transform + 0.0.1-SNAPSHOT + jar + + customer-transform + Example transform ETL step + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../../parent-boot-2 + + + + UTF-8 + UTF-8 + 1.8 + Finchley.SR1 + + + + + org.springframework.cloud + spring-cloud-stream-binder-rabbit + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.cloud + spring-cloud-stream-test-support + test + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java new file mode 100644 index 0000000000..f0e4d79388 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/Customer.java @@ -0,0 +1,29 @@ +package com.customer.customertransform; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Customer { + + private Long id; + + private String name; + + @JsonProperty("customer_name") + public void setName(String name) { + this.name = name; + } + + @JsonProperty("name") + public String getName() { + return name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + +} \ No newline at end of file diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java new file mode 100644 index 0000000000..c99fcf55be --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerProcessorConfiguration.java @@ -0,0 +1,16 @@ +package com.customer.customertransform; + + +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.integration.annotation.Transformer; + +@EnableBinding(Processor.class) +public class CustomerProcessorConfiguration { + + @Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT) + public Customer convertToPojo(Customer payload) { + + return payload; + } +} \ No newline at end of file diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java new file mode 100644 index 0000000000..8781f4da54 --- /dev/null +++ b/spring-cloud-data-flow/etl/customer-transform/src/main/java/com/customer/customertransform/CustomerTransformApplication.java @@ -0,0 +1,12 @@ +package com.customer.customertransform; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomerTransformApplication { + + public static void main(String[] args) { + SpringApplication.run(CustomerTransformApplication.class, args); + } +} diff --git a/spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties b/spring-cloud-data-flow/etl/customer-transform/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-cloud-data-flow/etl/pom.xml b/spring-cloud-data-flow/etl/pom.xml new file mode 100644 index 0000000000..2b904f6e0d --- /dev/null +++ b/spring-cloud-data-flow/etl/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + org.baeldung.spring.cloud + etl-spring-cloud-data-flow + 0.0.1-SNAPSHOT + pom + + + org.baeldung.spring.cloud + spring-cloud-data-flow + 0.0.1-SNAPSHOT + + + + customer-mongodb-sink + customer-transform + + + diff --git a/spring-cloud-data-flow/log-sink/pom.xml b/spring-cloud-data-flow/log-sink/pom.xml index ab367fadd7..33a0a4df45 100644 --- a/spring-cloud-data-flow/log-sink/pom.xml +++ b/spring-cloud-data-flow/log-sink/pom.xml @@ -1,13 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.spring.cloud log-sink 0.0.1-SNAPSHOT jar - log-sink Demo project for Spring Boot @@ -18,10 +17,6 @@ ../../parent-boot-1 - - Brixton.SR7 - - org.springframework.cloud @@ -41,4 +36,8 @@ + + Brixton.SR7 + + diff --git a/spring-cloud-data-flow/log-sink/src/main/resources/logback.xml b/spring-cloud-data-flow/log-sink/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud-data-flow/log-sink/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..8dc814ddce --- /dev/null +++ b/spring-cloud-data-flow/log-sink/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.baeldung.spring.cloud.LogSinkApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = LogSinkApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/pom.xml b/spring-cloud-data-flow/pom.xml index 9ff23305fd..5a007f3c7d 100644 --- a/spring-cloud-data-flow/pom.xml +++ b/spring-cloud-data-flow/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.spring.cloud spring-cloud-data-flow @@ -19,6 +19,7 @@ time-processor log-sink batch-job + etl diff --git a/spring-cloud-data-flow/time-processor/pom.xml b/spring-cloud-data-flow/time-processor/pom.xml index 79bae89857..4f31e55b96 100644 --- a/spring-cloud-data-flow/time-processor/pom.xml +++ b/spring-cloud-data-flow/time-processor/pom.xml @@ -1,13 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.spring.cloud time-processor 0.0.1-SNAPSHOT jar - time-processor Demo project for Spring Boot @@ -18,10 +17,6 @@ ../../parent-boot-1 - - Brixton.SR7 - - org.springframework.cloud @@ -41,4 +36,8 @@ + + Brixton.SR7 + + diff --git a/spring-cloud-data-flow/time-processor/src/main/resources/logback.xml b/spring-cloud-data-flow/time-processor/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud-data-flow/time-processor/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..dcfeafa2bb --- /dev/null +++ b/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.baeldung.spring.cloud.TimeProcessorApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TimeProcessorApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/time-source/pom.xml b/spring-cloud-data-flow/time-source/pom.xml index 17d2f5c693..dc593fdb14 100644 --- a/spring-cloud-data-flow/time-source/pom.xml +++ b/spring-cloud-data-flow/time-source/pom.xml @@ -1,13 +1,12 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - + org.baeldung.spring.cloud time-source 0.0.1-SNAPSHOT jar - time-source Demo project for Spring Boot @@ -18,10 +17,6 @@ ../../parent-boot-1 - - Brixton.SR7 - - org.springframework.cloud @@ -41,4 +36,8 @@ + + Brixton.SR7 + + diff --git a/spring-cloud-data-flow/time-source/src/main/resources/logback.xml b/spring-cloud-data-flow/time-source/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud-data-flow/time-source/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2c402824f0 --- /dev/null +++ b/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.baeldung.spring.cloud.TimeSourceApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TimeSourceApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/spring/cloud/TimeSourceApplicationIntegrationTest.java b/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/spring/cloud/TimeSourceApplicationIntegrationTest.java deleted file mode 100644 index 6d71a785a3..0000000000 --- a/spring-cloud-data-flow/time-source/src/test/java/org/baeldung/spring/cloud/TimeSourceApplicationIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.spring.cloud; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class TimeSourceApplicationIntegrationTest { - - @Test - public void contextLoads() { - } - -} diff --git a/spring-cloud/README.md b/spring-cloud/README.md index 31d9ffb684..16bc2d110a 100644 --- a/spring-cloud/README.md +++ b/spring-cloud/README.md @@ -27,3 +27,6 @@ - [An Intro to Spring Cloud Security](http://www.baeldung.com/spring-cloud-security) - [An Intro to Spring Cloud Task](http://www.baeldung.com/spring-cloud-task) - [Running Spring Boot Applications With Minikube](http://www.baeldung.com/spring-boot-minikube) +- [Introduction to Netflix Archaius with Spring Cloud](https://www.baeldung.com/netflix-archaius-spring-cloud-integration) +- [An Intro to Spring Cloud Vault](https://www.baeldung.com/spring-cloud-vault) +- [Netflix Archaius with Various Database Configurations](https://www.baeldung.com/netflix-archaius-database-configurations) diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index 7c739d656e..924ea2be36 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung.spring.cloud spring-cloud @@ -26,30 +25,20 @@ spring-cloud-zookeeper spring-cloud-gateway spring-cloud-stream + spring-cloud-stream-starters/twitterhdfs spring-cloud-connectors-heroku spring-cloud-aws spring-cloud-consul spring-cloud-zuul-eureka-integration spring-cloud-contract spring-cloud-kubernetes + spring-cloud-archaius + spring-cloud-functions + spring-cloud-vault + spring-cloud-security + spring-cloud-task - - UTF-8 - 1.2.2.RELEASE - Brixton.SR7 - 1.2.2.RELEASE - 1.2.2.RELEASE - 1.2.3.RELEASE - 1.2.3.RELEASE - 1.2.3.RELEASE - 1.3.0.RELEASE - 1.4.2.RELEASE - 3.7.0 - 1.4.2.RELEASE - 1.2.3.RELEASE - - @@ -62,4 +51,18 @@ + + 1.2.2.RELEASE + Brixton.SR7 + 1.2.2.RELEASE + 1.2.2.RELEASE + 1.2.3.RELEASE + 1.2.3.RELEASE + 1.2.3.RELEASE + 1.3.0.RELEASE + 1.4.2.RELEASE + 1.4.2.RELEASE + 1.2.3.RELEASE + + diff --git a/spring-cloud/spring-cloud-archaius/README.md b/spring-cloud/spring-cloud-archaius/README.md new file mode 100644 index 0000000000..9de26352e1 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/README.md @@ -0,0 +1,14 @@ +# Spring Cloud Archaius + +#### Basic Config +This service has the basic, out-of-the-box Spring Cloud Netflix Archaius configuration. + +#### Extra Configs +This service customizes some properties supported by Archaius. + +These properties are set up on the main method, since Archaius uses System properties, but they could be added as command line arguments when launching the app. + +#### Additional Sources +In this service we create a new AbstractConfiguration bean, setting up a new Configuration Properties source. + +These properties have precedence over all the other properties in the Archaius Composite Configuration. \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/pom.xml b/spring-cloud/spring-cloud-archaius/additional-sources-simple/pom.xml new file mode 100644 index 0000000000..1ae6d543fb --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + additional-sources-simple + 1.0.0-SNAPSHOT + jar + additional-sources-simple + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/AdditionalSourcesSimpleApplication.java b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/AdditionalSourcesSimpleApplication.java new file mode 100644 index 0000000000..e1a1d106cf --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/AdditionalSourcesSimpleApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.cloud.archaius.additionalsources; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class AdditionalSourcesSimpleApplication { + + public static void main(String[] args) { + SpringApplication.run(AdditionalSourcesSimpleApplication.class, args); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/config/ApplicationPropertiesConfigurations.java b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/config/ApplicationPropertiesConfigurations.java new file mode 100644 index 0000000000..f2d8ca2638 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/config/ApplicationPropertiesConfigurations.java @@ -0,0 +1,21 @@ +package com.baeldung.spring.cloud.archaius.additionalsources.config; + +import org.apache.commons.configuration.AbstractConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.netflix.config.DynamicConfiguration; +import com.netflix.config.FixedDelayPollingScheduler; +import com.netflix.config.PolledConfigurationSource; +import com.netflix.config.sources.URLConfigurationSource; + +@Configuration +public class ApplicationPropertiesConfigurations { + + @Bean + public AbstractConfiguration addApplicationPropertiesSource() { + PolledConfigurationSource source = new URLConfigurationSource("classpath:other-config.properties"); + return new DynamicConfiguration(source, new FixedDelayPollingScheduler()); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/controller/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/controller/ConfigPropertiesController.java new file mode 100644 index 0000000000..304369a036 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/java/com/baeldung/spring/cloud/archaius/additionalsources/controller/ConfigPropertiesController.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.cloud.archaius.additionalsources.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + private DynamicStringProperty propertyFourWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.four", "not found!"); + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get()); + properties.put(propertyTwoWithDynamic.getName(), propertyTwoWithDynamic.get()); + properties.put(propertyThreeWithDynamic.getName(), propertyThreeWithDynamic.get()); + properties.put(propertyFourWithDynamic.getName(), propertyFourWithDynamic.get()); + return properties; + } +} diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/application.properties new file mode 100644 index 0000000000..bf55e89a27 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8082 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/config.properties b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/config.properties new file mode 100644 index 0000000000..b104c0c488 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/config.properties @@ -0,0 +1,2 @@ +baeldung.archaius.properties.one=one FROM:config.properties +baeldung.archaius.properties.three=three FROM:config.properties diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/other-config.properties b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/other-config.properties new file mode 100644 index 0000000000..00fe8ff2aa --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/main/resources/other-config.properties @@ -0,0 +1,2 @@ +baeldung.archaius.properties.one=one FROM:other-config.properties +baeldung.archaius.properties.four=four FROM:other-config.properties diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/java/com/baeldung/spring/cloud/archaius/additionalsources/ArchaiusAdditionalSourcesLiveTest.java b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/java/com/baeldung/spring/cloud/archaius/additionalsources/ArchaiusAdditionalSourcesLiveTest.java new file mode 100644 index 0000000000..f3a345d869 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/java/com/baeldung/spring/cloud/archaius/additionalsources/ArchaiusAdditionalSourcesLiveTest.java @@ -0,0 +1,54 @@ +package com.baeldung.spring.cloud.archaius.additionalsources; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +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.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusAdditionalSourcesLiveTest { + + private static final String BASE_URL = "http://localhost:8082"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:other-config.properties"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:config.properties"); + map.put("baeldung.archaius.properties.four", "four FROM:other-config.properties"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..e5ebbce1aa --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/additional-sources-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.archaius.additionalsources.AdditionalSourcesSimpleApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AdditionalSourcesSimpleApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-archaius/basic-config/pom.xml b/spring-cloud/spring-cloud-archaius/basic-config/pom.xml new file mode 100644 index 0000000000..b5b091712d --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + basic-config + 1.0.0-SNAPSHOT + jar + basic-config + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/main/java/com/baeldung/spring/cloud/archaius/basic/BasicArchaiusApplication.java b/spring-cloud/spring-cloud-archaius/basic-config/src/main/java/com/baeldung/spring/cloud/archaius/basic/BasicArchaiusApplication.java new file mode 100644 index 0000000000..e6e578eed3 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/main/java/com/baeldung/spring/cloud/archaius/basic/BasicArchaiusApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.cloud.archaius.basic; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class BasicArchaiusApplication { + + public static void main(String[] args) { + SpringApplication.run(BasicArchaiusApplication.class, args); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/main/java/com/baeldung/spring/cloud/archaius/basic/controller/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/basic-config/src/main/java/com/baeldung/spring/cloud/archaius/basic/controller/ConfigPropertiesController.java new file mode 100644 index 0000000000..46b8f345f6 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/main/java/com/baeldung/spring/cloud/archaius/basic/controller/ConfigPropertiesController.java @@ -0,0 +1,70 @@ +package com.baeldung.spring.cloud.archaius.basic.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicIntProperty; +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + @Value("${baeldung.archaius.properties.one:not found!}") + private String propertyOneWithValue; + + @Value("${baeldung.archaius.properties.two:not found!}") + private String propertyTwoWithValue; + + @Value("${baeldung.archaius.properties.three:not found!}") + private String propertyThreeWithValue; + + @Value("${baeldung.archaius.properties.four:not found!}") + private String propertyFourWithValue; + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + private DynamicStringProperty propertyFourWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.four", "not found!"); + + private DynamicIntProperty intPropertyWithDynamic = DynamicPropertyFactory.getInstance() + .getIntProperty("baeldung.archaius.properties.int", 0); + + @GetMapping("/properties-from-value") + public Map getPropertiesFromValue() { + Map properties = new HashMap<>(); + properties.put("baeldung.archaius.properties.one", propertyOneWithValue); + properties.put("baeldung.archaius.properties.two", propertyTwoWithValue); + properties.put("baeldung.archaius.properties.three", propertyThreeWithValue); + properties.put("baeldung.archaius.properties.four", propertyFourWithValue); + return properties; + } + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get()); + properties.put(propertyTwoWithDynamic.getName(), propertyTwoWithDynamic.get()); + properties.put(propertyThreeWithDynamic.getName(), propertyThreeWithDynamic.get()); + properties.put(propertyFourWithDynamic.getName(), propertyFourWithDynamic.get()); + return properties; + } + + @GetMapping("/int-property") + public Map getIntPropertyFromDynamic() { + Map properties = new HashMap<>(); + properties.put(intPropertyWithDynamic.getName(), intPropertyWithDynamic.get()); + return properties; + } +} diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/application.properties new file mode 100644 index 0000000000..1a35a22197 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8080 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/config.properties b/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/config.properties new file mode 100644 index 0000000000..86ae575d20 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/config.properties @@ -0,0 +1,4 @@ +baeldung.archaius.properties.one=one FROM:config.properties +baeldung.archaius.properties.three=three FROM:config.properties + +baeldung.archaius.properties.int=1 diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/other.properties b/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/other.properties new file mode 100644 index 0000000000..26796b7341 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/main/resources/other.properties @@ -0,0 +1,2 @@ +baeldung.archaius.properties.one=one FROM:other.properties +baeldung.archaius.properties.four=four FROM:other.properties diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationIntegrationTest.java b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationIntegrationTest.java new file mode 100644 index 0000000000..2948606c0b --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationIntegrationTest.java @@ -0,0 +1,45 @@ +package com.baeldung.spring.cloud.archaius.basic; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; + +import org.junit.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.cloud.context.environment.EnvironmentChangeEvent; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RunWith(JUnitPlatform.class) +@ExtendWith(SpringExtension.class) +@SpringBootTest +public class ArchaiusBasicConfigurationIntegrationTest { + + @Autowired + ConfigurableApplicationContext context; + + private DynamicStringProperty testPropertyWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.test.properties.one", "not found!"); + + @Test + public void givenIntialPropertyValue_whenPropertyChanges_thenArchaiusRetrievesNewValue() { + String initialValue = testPropertyWithDynamic.get(); + + TestPropertyValues.of("baeldung.archaius.test.properties.one=new-value") + .applyTo(context); + context.publishEvent(new EnvironmentChangeEvent(Collections.singleton("baeldung.archaius.test.properties.one"))); + String finalValue = testPropertyWithDynamic.get(); + + assertThat(initialValue).isEqualTo("test-one"); + assertThat(finalValue).isEqualTo("new-value"); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationLiveTest.java b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationLiveTest.java new file mode 100644 index 0000000000..70d43df60d --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/com/baeldung/spring/cloud/archaius/basic/ArchaiusBasicConfigurationLiveTest.java @@ -0,0 +1,74 @@ +package com.baeldung.spring.cloud.archaius.basic; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +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.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusBasicConfigurationLiveTest { + + private static final String BASE_URL = "http://localhost:8080"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:application.properties"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:config.properties"); + map.put("baeldung.archaius.properties.four", "not found!"); + return map; + } + + private static final String VALUE_PROPERTIES_URL = "/properties-from-value"; + private static final Map EXPECTED_VALUE_PROPERTIES = createExpectedValueProperties(); + + private static Map createExpectedValueProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:application.properties"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "not found!"); + map.put("baeldung.archaius.properties.four", "not found!"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenDefaultConfigurationSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestSpringVisibleProperties_thenEndpointDoesntRetrieveArchaiusProperties() { + Map initialResponse = this.exchangeAsMap(BASE_URL + VALUE_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_VALUE_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..16542981e8 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.archaius.basic.BasicArchaiusApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BasicArchaiusApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-archaius/basic-config/src/test/resources/config.properties b/spring-cloud/spring-cloud-archaius/basic-config/src/test/resources/config.properties new file mode 100644 index 0000000000..1ceb5d1161 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/basic-config/src/test/resources/config.properties @@ -0,0 +1,3 @@ +baeldung.archaius.test.properties.one=test-one +baeldung.archaius.test.properties.two=test-two +baeldung.archaius.test.properties.int=1 diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/pom.xml b/spring-cloud/spring-cloud-archaius/dynamodb-config/pom.xml new file mode 100644 index 0000000000..3ffbf8f619 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + dynamodb-config + jar + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + com.amazonaws + aws-java-sdk-dynamodb + ${aws.sdk.dynamo.version} + + + com.github.derjust + spring-data-dynamodb + ${spring.dynamo.version} + + + com.netflix.archaius + archaius-aws + ${archaius.version} + + + org.projectlombok + lombok + provided + + + + + 1.11.407 + 5.0.3 + 0.7.6 + + diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/DynamoSourcesApplication.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/DynamoSourcesApplication.java new file mode 100644 index 0000000000..ee08f2b1fb --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/DynamoSourcesApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.cloud.archaius.dynamosources; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DynamoSourcesApplication { + + public static void main(String[] args) { + SpringApplication.run(DynamoSourcesApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/ApplicationPropertiesConfigurations.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/ApplicationPropertiesConfigurations.java new file mode 100644 index 0000000000..7b533e8021 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/ApplicationPropertiesConfigurations.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.config; + +import java.util.Arrays; + +import org.apache.commons.configuration.AbstractConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; +import com.amazonaws.services.dynamodbv2.model.CreateTableRequest; +import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; +import com.amazonaws.services.dynamodbv2.util.TableUtils; +import com.baeldung.spring.cloud.archaius.dynamosources.dynamodb.ArchaiusProperties; +import com.baeldung.spring.cloud.archaius.dynamosources.dynamodb.ArchaiusPropertiesRepository; +import com.netflix.config.DynamicConfiguration; +import com.netflix.config.FixedDelayPollingScheduler; +import com.netflix.config.PolledConfigurationSource; +import com.netflix.config.sources.DynamoDbConfigurationSource; + +@Configuration +public class ApplicationPropertiesConfigurations { + + @Autowired + AmazonDynamoDB amazonDynamoDb; + + @Autowired + private ArchaiusPropertiesRepository repository; + + @Bean + public AbstractConfiguration addApplicationPropertiesSource() { + // Normally, the DB Table would be already created and populated. + // In this case, we'll do it just before creating the archaius config source that uses it + initDatabase(); + PolledConfigurationSource source = new DynamoDbConfigurationSource(amazonDynamoDb); + return new DynamicConfiguration(source, new FixedDelayPollingScheduler()); + } + + private void initDatabase() { + // Create the table + DynamoDBMapper mapper = new DynamoDBMapper(amazonDynamoDb); + CreateTableRequest tableRequest = mapper.generateCreateTableRequest(ArchaiusProperties.class); + tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L)); + TableUtils.createTableIfNotExists(amazonDynamoDb, tableRequest); + + // Populate the table + ArchaiusProperties property = new ArchaiusProperties("baeldung.archaius.properties.one", "one FROM:dynamoDB"); + ArchaiusProperties property3 = new ArchaiusProperties("baeldung.archaius.properties.three", "three FROM:dynamoDB"); + repository.saveAll(Arrays.asList(property, property3)); + } +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/DynamoDbConfiguration.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/DynamoDbConfiguration.java new file mode 100644 index 0000000000..8f12051a7f --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/DynamoDbConfiguration.java @@ -0,0 +1,46 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.config; + +import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; + +@Configuration +@EnableDynamoDBRepositories(basePackages = "com.baeldung.spring.cloud.archaius.dynamosources.dynamodb") +public class DynamoDbConfiguration { + + @Value("${amazon.dynamodb.endpoint}") + private String amazonDynamoDBEndpoint; + + @Value("${aws.accessKeyId}") + private String amazonDynamoDBAccessKeyId; + + @Value("${aws.secretKey}") + private String amazonDynamoDBSecretKey; + + @Bean + public AmazonDynamoDB amazonDynamoDB() { + AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard() + .withCredentials(amazonAWSCredentials()) + .withEndpointConfiguration(setupEndpointConfiguration()) + .build(); + + return amazonDynamoDB; + } + + private AWSCredentialsProvider amazonAWSCredentials() { + return new AWSStaticCredentialsProvider(new BasicAWSCredentials(amazonDynamoDBAccessKeyId, amazonDynamoDBSecretKey)); + } + + private EndpointConfiguration setupEndpointConfiguration() { + return new EndpointConfiguration(amazonDynamoDBEndpoint, Regions.DEFAULT_REGION.getName()); + } +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/controller/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/controller/ConfigPropertiesController.java new file mode 100644 index 0000000000..2ac5055fe3 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/controller/ConfigPropertiesController.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get()); + properties.put(propertyTwoWithDynamic.getName(), propertyTwoWithDynamic.get()); + properties.put(propertyThreeWithDynamic.getName(), propertyThreeWithDynamic.get()); + return properties; + } +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusProperties.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusProperties.java new file mode 100644 index 0000000000..016f8433cf --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusProperties.java @@ -0,0 +1,23 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.dynamodb; + +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@DynamoDBTable(tableName = "archaiusProperties") +public class ArchaiusProperties { + + @DynamoDBHashKey + @DynamoDBAttribute + private String key; + + @DynamoDBAttribute + private String value; +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusPropertiesRepository.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusPropertiesRepository.java new file mode 100644 index 0000000000..fbcc953261 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusPropertiesRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.dynamodb; + +import org.springframework.data.repository.CrudRepository; + +public interface ArchaiusPropertiesRepository extends CrudRepository { + +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/resources/application.properties new file mode 100644 index 0000000000..3823d2685f --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/resources/application.properties @@ -0,0 +1,6 @@ +server.port=8082 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties +amazon.dynamodb.endpoint=http://localhost:8000/ +aws.accessKeyId=key +aws.secretKey=key2 diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/ArchaiusDynamoDbLiveTest.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/ArchaiusDynamoDbLiveTest.java new file mode 100644 index 0000000000..3802cb99cd --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/ArchaiusDynamoDbLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.spring.cloud.archaius.dynamosources; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +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.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusDynamoDbLiveTest { + + private static final String BASE_URL = "http://localhost:8082"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:dynamoDB"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:dynamoDB"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/pom.xml b/spring-cloud/spring-cloud-archaius/extra-configs/pom.xml new file mode 100644 index 0000000000..2f3f2b084a --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + extra-configs + 1.0.0-SNAPSHOT + jar + extra-configs + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-netflix-archaius + + + + + + + org.springframework.cloud + spring-cloud-netflix + ${spring-cloud-dependencies.version} + pom + import + + + + + 2.0.1.RELEASE + + diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/main/java/com/baeldung/spring/cloud/archaius/extraconfigs/ExtraConfigsApplication.java b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/java/com/baeldung/spring/cloud/archaius/extraconfigs/ExtraConfigsApplication.java new file mode 100644 index 0000000000..4747d875db --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/java/com/baeldung/spring/cloud/archaius/extraconfigs/ExtraConfigsApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.archaius.extraconfigs; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ExtraConfigsApplication { + + public static void main(String[] args) { + // System properties can be set as command line arguments too + System.setProperty("archaius.configurationSource.additionalUrls", "classpath:other-config-dir/extra.properties"); + System.setProperty("archaius.configurationSource.defaultFileName", "other.properties"); + SpringApplication.run(ExtraConfigsApplication.class, args); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/main/java/com/baeldung/spring/cloud/archaius/extraconfigs/controllers/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/java/com/baeldung/spring/cloud/archaius/extraconfigs/controllers/ConfigPropertiesController.java new file mode 100644 index 0000000000..382c6b3a2c --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/java/com/baeldung/spring/cloud/archaius/extraconfigs/controllers/ConfigPropertiesController.java @@ -0,0 +1,60 @@ +package com.baeldung.spring.cloud.archaius.extraconfigs.controllers; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + @Value("${baeldung.archaius.properties.one:not found!}") + private String propertyOneWithValue; + + @Value("${baeldung.archaius.properties.two:not found!}") + private String propertyTwoWithValue; + + @Value("${baeldung.archaius.properties.three:not found!}") + private String propertyThreeWithValue; + + @Value("${baeldung.archaius.properties.four:not found!}") + private String propertyFourWithValue; + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + private DynamicStringProperty propertyFourWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.four", "not found!"); + + @GetMapping("/properties-from-value") + public Map getPropertiesFromValue() { + Map properties = new HashMap<>(); + properties.put("baeldung.archaius.properties.one", propertyOneWithValue); + properties.put("baeldung.archaius.properties.two", propertyTwoWithValue); + properties.put("baeldung.archaius.properties.three", propertyThreeWithValue); + properties.put("baeldung.archaius.properties.four", propertyFourWithValue); + return properties; + } + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put("baeldung.archaius.properties.one", propertyOneWithDynamic.get()); + properties.put("baeldung.archaius.properties.two", propertyTwoWithDynamic.get()); + properties.put("baeldung.archaius.properties.three", propertyThreeWithDynamic.get()); + properties.put("baeldung.archaius.properties.four", propertyFourWithDynamic.get()); + return properties; + } + +} diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/application.properties new file mode 100644 index 0000000000..1e36b134d4 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/application.properties @@ -0,0 +1,3 @@ +server.port=8081 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/other-config-dir/extra.properties b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/other-config-dir/extra.properties new file mode 100644 index 0000000000..ea99914cc1 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/other-config-dir/extra.properties @@ -0,0 +1,2 @@ +baeldung.archaius.properties.one=one FROM:extra.properties +baeldung.archaius.properties.three=three FROM:extra.properties diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/other.properties b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/other.properties new file mode 100644 index 0000000000..26796b7341 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/main/resources/other.properties @@ -0,0 +1,2 @@ +baeldung.archaius.properties.one=one FROM:other.properties +baeldung.archaius.properties.four=four FROM:other.properties diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/com/baeldung/spring/cloud/archaius/extraconfigs/ArchaiusExtraConfigsLiveTest.java b/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/com/baeldung/spring/cloud/archaius/extraconfigs/ArchaiusExtraConfigsLiveTest.java new file mode 100644 index 0000000000..232ca73352 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/com/baeldung/spring/cloud/archaius/extraconfigs/ArchaiusExtraConfigsLiveTest.java @@ -0,0 +1,54 @@ +package com.baeldung.spring.cloud.archaius.extraconfigs; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +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.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusExtraConfigsLiveTest { + + private static final String BASE_URL = "http://localhost:8081"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:application.properties"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:extra.properties"); + map.put("baeldung.archaius.properties.four", "four FROM:other.properties"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..4c2531f490 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/extra-configs/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.archaius.extraconfigs.ExtraConfigsApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ExtraConfigsApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/pom.xml b/spring-cloud/spring-cloud-archaius/jdbc-config/pom.xml new file mode 100644 index 0000000000..bb283576d8 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + jdbc-config + jar + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + runtime + + + diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/JdbcSourcesApplication.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/JdbcSourcesApplication.java new file mode 100644 index 0000000000..ee7beec87b --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/JdbcSourcesApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JdbcSourcesApplication { + + public static void main(String[] args) { + SpringApplication.run(JdbcSourcesApplication.class, args); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/config/ApplicationPropertiesConfigurations.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/config/ApplicationPropertiesConfigurations.java new file mode 100644 index 0000000000..f3eed0c2b5 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/config/ApplicationPropertiesConfigurations.java @@ -0,0 +1,27 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig.config; + +import javax.sql.DataSource; + +import org.apache.commons.configuration.AbstractConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.netflix.config.DynamicConfiguration; +import com.netflix.config.FixedDelayPollingScheduler; +import com.netflix.config.PolledConfigurationSource; +import com.netflix.config.sources.JDBCConfigurationSource; + +@Configuration +public class ApplicationPropertiesConfigurations { + + @Autowired + DataSource h2DataSource; + + @Bean + public AbstractConfiguration addApplicationPropertiesSource() { + PolledConfigurationSource source = new JDBCConfigurationSource(h2DataSource, "select distinct key, value from properties", "key", "value"); + return new DynamicConfiguration(source, new FixedDelayPollingScheduler()); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/controller/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/controller/ConfigPropertiesController.java new file mode 100644 index 0000000000..a793f39b29 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/controller/ConfigPropertiesController.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get()); + properties.put(propertyTwoWithDynamic.getName(), propertyTwoWithDynamic.get()); + properties.put(propertyThreeWithDynamic.getName(), propertyThreeWithDynamic.get()); + return properties; + } +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/jdbc/Properties.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/jdbc/Properties.java new file mode 100644 index 0000000000..cc2783b506 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/jdbc/Properties.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig.jdbc; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Properties { + + @Id + private String key; + + @SuppressWarnings("unused") + private String value; +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/application.properties new file mode 100644 index 0000000000..eca873f897 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port=8082 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties +spring.h2.console.enabled=true diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/data.sql b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/data.sql new file mode 100644 index 0000000000..eb80126d48 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/data.sql @@ -0,0 +1,5 @@ +insert into properties +values('baeldung.archaius.properties.one', 'one FROM:jdbc_source'); + +insert into properties +values('baeldung.archaius.properties.three', 'three FROM:jdbc_source'); \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/ArchaiusJDBCSourceLiveTest.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/ArchaiusJDBCSourceLiveTest.java new file mode 100644 index 0000000000..91d5f5754e --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/ArchaiusJDBCSourceLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +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.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusJDBCSourceLiveTest { + + private static final String BASE_URL = "http://localhost:8082"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:jdbc_source"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:jdbc_source"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-archaius/pom.xml b/spring-cloud/spring-cloud-archaius/pom.xml new file mode 100644 index 0000000000..fd3e34e463 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + spring-cloud-archaius + Spring Cloud Archaius Pom parent + pom + + + com.baeldung.spring.cloud + spring-cloud + 1.0.0-SNAPSHOT + .. + + + + basic-config + additional-sources-simple + extra-configs + jdbc-config + dynamodb-config + zookeeper-config + + + + + org.springframework.cloud + spring-cloud-starter-netflix-archaius + + + org.springframework.boot + spring-boot-starter-test + + + org.assertj + assertj-core + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + + + + + org.springframework.cloud + spring-cloud-netflix + ${spring-cloud-dependencies.version} + pom + import + + + + + + 2.0.1.RELEASE + 1.2.0 + + diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml b/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml new file mode 100644 index 0000000000..8f8ec99ad8 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + zookeeper-config + jar + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-zookeeper-config + ${cloud.zookeeper.version} + + + org.apache.zookeeper + zookeeper + + + + + org.apache.zookeeper + zookeeper + ${zookeeper.version} + + + org.slf4j + slf4j-log4j12 + + + + + + + 2.0.0.RELEASE + 3.4.13 + + diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ZookeeperConfigApplication.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ZookeeperConfigApplication.java new file mode 100644 index 0000000000..12119e3e29 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ZookeeperConfigApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ZookeeperConfigApplication { + + public static void main(String[] args) { + SpringApplication.run(ZookeeperConfigApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/config/ZookeeperConfigsInitializer.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/config/ZookeeperConfigsInitializer.java new file mode 100644 index 0000000000..59ef10aaf7 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/config/ZookeeperConfigsInitializer.java @@ -0,0 +1,58 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig.config; + +import org.apache.curator.framework.CuratorFramework; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * + * Ideally, we wouldn't need to initialize the zookeeper config values. + * Here we do it to verify that configurations are being retrieved. + * + */ +@Component +public class ZookeeperConfigsInitializer { + + private static final String CONFIG_BASE_NODE_PATH = "/config"; + private static final String APPLICATION_BASE_NODE_PATH = CONFIG_BASE_NODE_PATH + "/application"; + + @Autowired + CuratorFramework client; + + @EventListener + public void appReady(ApplicationReadyEvent event) throws Exception { + String pathOne = APPLICATION_BASE_NODE_PATH + "/baeldung.archaius.properties.one"; + String valueOne = "one FROM:zookeeper"; + String pathThree = APPLICATION_BASE_NODE_PATH + "/baeldung.archaius.properties.three"; + String valueThree = "three FROM:zookeeper"; + createBaseNodes(); + setValue(pathOne, valueOne); + setValue(pathThree, valueThree); + } + + private void setValue(String path, String value) throws Exception { + if (client.checkExists() + .forPath(path) == null) { + client.create() + .forPath(path, value.getBytes()); + } else { + client.setData() + .forPath(path, value.getBytes()); + } + } + + private void createBaseNodes() throws Exception { + if (client.checkExists() + .forPath(CONFIG_BASE_NODE_PATH) == null) { + client.create() + .forPath(CONFIG_BASE_NODE_PATH); + } + if (client.checkExists() + .forPath(APPLICATION_BASE_NODE_PATH) == null) { + client.create() + .forPath(APPLICATION_BASE_NODE_PATH); + } + } +} diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/controller/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/controller/ConfigPropertiesController.java new file mode 100644 index 0000000000..c8a5e53ee4 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/controller/ConfigPropertiesController.java @@ -0,0 +1,51 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + @Value("${baeldung.archaius.properties.one:not found!}") + private String propertyOneWithValue; + + @Value("${baeldung.archaius.properties.two:not found!}") + private String propertyTwoWithValue; + + @Value("${baeldung.archaius.properties.three:not found!}") + private String propertyThreeWithValue; + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get()); + properties.put(propertyTwoWithDynamic.getName(), propertyTwoWithDynamic.get()); + properties.put(propertyThreeWithDynamic.getName(), propertyThreeWithDynamic.get()); + return properties; + } + + @GetMapping("/properties-from-value") + public Map getPropertiesFromValue() { + Map properties = new HashMap<>(); + properties.put("baeldung.archaius.properties.one", propertyOneWithValue); + properties.put("baeldung.archaius.properties.two", propertyTwoWithValue); + properties.put("baeldung.archaius.properties.three", propertyThreeWithValue); + return properties; + } +} diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/resources/application.properties new file mode 100644 index 0000000000..91ad18a932 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port=8082 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties +spring.application.name=zookeeper-config diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ArchaiusZookeeperLiveTest.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ArchaiusZookeeperLiveTest.java new file mode 100644 index 0000000000..ff4358cb8f --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ArchaiusZookeeperLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +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.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusZookeeperLiveTest { + + private static final String BASE_URL = "http://localhost:8082"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:zookeeper"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:zookeeper"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-aws/pom.xml b/spring-cloud/spring-cloud-aws/pom.xml index d076dc5e8e..6933845173 100644 --- a/spring-cloud/spring-cloud-aws/pom.xml +++ b/spring-cloud/spring-cloud-aws/pom.xml @@ -1,19 +1,18 @@ + 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.spring.cloud spring-cloud-aws - 0.0.1-SNAPSHOT jar Spring Cloud AWS Spring Cloud AWS Examples - org.springframework.boot - spring-boot-starter-parent - 1.5.8.RELEASE - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-1 @@ -44,7 +43,6 @@ org.postgresql postgresql - @@ -59,27 +57,8 @@ - - - - maven-surefire-plugin - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - - - com.baeldung.spring.cloud.aws.SpringCloudAwsApplication - UTF-8 - UTF-8 - 1.8 Dalston.SR4 - diff --git a/spring-cloud/spring-cloud-aws/src/main/resources/logback.xml b/spring-cloud/spring-cloud-aws/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-aws/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..fcba9c4132 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.aws.InstanceProfileAwsApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = InstanceProfileAwsApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/README.MD b/spring-cloud/spring-cloud-bootstrap/README.MD index 164219c185..5185200469 100644 --- a/spring-cloud/spring-cloud-bootstrap/README.MD +++ b/spring-cloud/spring-cloud-bootstrap/README.MD @@ -11,5 +11,5 @@ - git add . - git commit -m "First commit" - start the config server - - start the discover server + - start the discovery server - start all the other servers in any order (gateway, svc-book, svc-rating, zipkin) diff --git a/spring-cloud/spring-cloud-bootstrap/config/src/main/resources/logback.xml b/spring-cloud/spring-cloud-bootstrap/config/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/config/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/config/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6016788eab --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/config/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.bootstrap.config.ConfigApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ConfigApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/discovery/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6016788eab --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/discovery/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.bootstrap.config.ConfigApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ConfigApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/main/resources/logback.xml b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..1e2db33395 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/discovery/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.bootstrap.discovery.DiscoveryApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = DiscoveryApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/logback.xml b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ef3bb5ef95 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.bootstrap.gateway.GatewayApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = GatewayApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/pom.xml b/spring-cloud/spring-cloud-bootstrap/pom.xml index 68606d9058..74801159eb 100644 --- a/spring-cloud/spring-cloud-bootstrap/pom.xml +++ b/spring-cloud/spring-cloud-bootstrap/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-cloud-bootstrap 1.0.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/resources/logback.xml b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..0ffc2410e3 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.bootstrap.svcbook.BookServiceApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BookServiceApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/resources/logback.xml b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..3589666f17 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.bootstrap.svcrating.RatingServiceApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = RatingServiceApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-bootstrap/zipkin/src/main/resources/logback.xml b/spring-cloud/spring-cloud-bootstrap/zipkin/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/zipkin/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..4403d9e93b --- /dev/null +++ b/spring-cloud/spring-cloud-bootstrap/zipkin/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.bootstrap.zipkin.ZipkinApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ZipkinApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-config/client/pom.xml b/spring-cloud/spring-cloud-config/client/pom.xml index bd8c817256..800a496a82 100644 --- a/spring-cloud/spring-cloud-config/client/pom.xml +++ b/spring-cloud/spring-cloud-config/client/pom.xml @@ -15,18 +15,15 @@ org.springframework.cloud spring-cloud-starter-config - ${spring-cloud-starter-config.version} - + org.springframework.boot spring-boot-starter-web - ${org.springframework.boot.version} - + org.springframework.boot spring-boot-starter-test - ${org.springframework.boot.version} test @@ -40,8 +37,4 @@ - - 1.2.2.RELEASE - 1.4.2.RELEASE - diff --git a/spring-cloud/spring-cloud-config/client/src/test/java/com/baeldung/spring/cloud/config/client/ConfigClientLiveTest.java b/spring-cloud/spring-cloud-config/client/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 76% rename from spring-cloud/spring-cloud-config/client/src/test/java/com/baeldung/spring/cloud/config/client/ConfigClientLiveTest.java rename to spring-cloud/spring-cloud-config/client/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 9bca369c64..d727772cf9 100644 --- a/spring-cloud/spring-cloud-config/client/src/test/java/com/baeldung/spring/cloud/config/client/ConfigClientLiveTest.java +++ b/spring-cloud/spring-cloud-config/client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.spring.cloud.config.client; +package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; @@ -6,10 +6,12 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; +import com.baeldung.spring.cloud.config.client.ConfigClient; + @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = ConfigClient.class) @WebAppConfiguration -public class ConfigClientLiveTest { +public class SpringContextIntegrationTest { @Test public void contextLoads() { } diff --git a/spring-cloud/spring-cloud-config/pom.xml b/spring-cloud/spring-cloud-config/pom.xml index 0a8f4f9dc3..b28828bf37 100644 --- a/spring-cloud/spring-cloud-config/pom.xml +++ b/spring-cloud/spring-cloud-config/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung.spring.cloud spring-cloud-config diff --git a/spring-cloud/spring-cloud-config/server/pom.xml b/spring-cloud/spring-cloud-config/server/pom.xml index 61b27244b6..7bbb903cf9 100644 --- a/spring-cloud/spring-cloud-config/server/pom.xml +++ b/spring-cloud/spring-cloud-config/server/pom.xml @@ -15,23 +15,19 @@ org.springframework.cloud spring-cloud-config-server - ${spring-cloud-config-server.version} - + org.springframework.boot spring-boot-starter-security - ${org.springframework.boot.version} - + org.springframework.boot spring-boot-starter-web - ${org.springframework.boot.version} - + org.springframework.boot spring-boot-starter-test - ${org.springframework.boot.version} test @@ -41,14 +37,8 @@ org.springframework.boot spring-boot-maven-plugin - ${org.springframework.boot.version} - + - - 1.2.2.RELEASE - 1.4.2.RELEASE - - diff --git a/spring-cloud/spring-cloud-config/server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-config/server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..cd30392d4f --- /dev/null +++ b/spring-cloud/spring-cloud-config/server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.spring.cloud.config.server.ConfigServer; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = ConfigServer.class) +@WebAppConfiguration +public class SpringContextIntegrationTest { + @Test + public void contextLoads() { + } +} diff --git a/spring-cloud/spring-cloud-connectors-heroku/pom.xml b/spring-cloud/spring-cloud-connectors-heroku/pom.xml index 0363962c95..f00c9eb1fc 100644 --- a/spring-cloud/spring-cloud-connectors-heroku/pom.xml +++ b/spring-cloud/spring-cloud-connectors-heroku/pom.xml @@ -1,16 +1,16 @@ + 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.spring.cloud spring-cloud-connectors-heroku 1.0.0-SNAPSHOT - spring-boot-starter-parent - org.springframework.boot - 1.4.4.RELEASE - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-1 @@ -33,8 +33,7 @@ org.postgresql postgresql - ${postgresql.version} - + com.h2database h2 @@ -54,33 +53,8 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/JdbcTest.java - **/*LiveTest.java - - true - - - - - Brixton.SR7 - 2.19.1 9.4-1201-jdbc4 - \ No newline at end of file diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/logback.xml b/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-connectors-heroku/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..a705f18bc6 --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.connectors.heroku.ConnectorsHerokuApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ConnectorsHerokuApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-consul/pom.xml b/spring-cloud/spring-cloud-consul/pom.xml index d440da8e0c..2a2714d597 100644 --- a/spring-cloud/spring-cloud-consul/pom.xml +++ b/spring-cloud/spring-cloud-consul/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 org.baeldung spring-cloud-consul @@ -18,19 +17,25 @@ org.springframework.cloud spring-cloud-starter-consul-all - 1.3.0.RELEASE + ${spring-cloud-starter-consul.version} org.springframework.cloud spring-cloud-starter-consul-config - 1.3.0.RELEASE + ${spring-cloud-starter-consul.version} + + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test - UTF-8 - 3.7.0 + 1.3.0.RELEASE diff --git a/spring-cloud/spring-cloud-consul/src/main/resources/logback.xml b/spring-cloud/spring-cloud-consul/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-consul/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-consul/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6290ccc03e --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.consul.discovery.DiscoveryClientApplication; +import com.baeldung.spring.cloud.consul.health.ServiceDiscoveryApplication; +import com.baeldung.spring.cloud.consul.properties.DistributedPropertiesApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { DiscoveryClientApplication.class, ServiceDiscoveryApplication.class, + DistributedPropertiesApplication.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-contract/pom.xml b/spring-cloud/spring-cloud-contract/pom.xml index f1d5f6f262..5dde6a7a99 100644 --- a/spring-cloud/spring-cloud-contract/pom.xml +++ b/spring-cloud/spring-cloud-contract/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 pom com.baeldung.spring.cloud diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/resources/logback.xml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..1c1192cc3f --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.springcloudcontractconsumer.SpringCloudContractConsumerApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringCloudContractConsumerApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/resources/logback.xml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2b6703ae5c --- /dev/null +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.springcloudcontractproducer.SpringCloudContractProducerApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringCloudContractProducerApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-eureka/pom.xml b/spring-cloud/spring-cloud-eureka/pom.xml index 9392f17325..37571bc29a 100644 --- a/spring-cloud/spring-cloud-eureka/pom.xml +++ b/spring-cloud/spring-cloud-eureka/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung.spring.cloud spring-cloud-eureka @@ -24,8 +23,6 @@ - UTF-8 - 3.7.0 1.4.2.RELEASE diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml index 70379fbc65..8bc51adcab 100644 --- a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 spring-cloud-eureka-client @@ -29,6 +28,24 @@ spring-boot-starter-web ${spring-boot-starter-web.version} + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + + + org.springframework.boot + spring-boot-test + 1.5.10.RELEASE + test + + + org.springframework + spring-test + 4.0.5.RELEASE + test + @@ -43,9 +60,4 @@ - - Brixton.SR7 - 1.2.3.RELEASE - 1.4.2.RELEASE - diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/src/main/resources/logback.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml index 22b0e7b899..4552c458ec 100644 --- a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 spring-cloud-eureka-feign-client 1.0.0-SNAPSHOT @@ -20,7 +19,7 @@ com.baeldung.spring.cloud spring-cloud-eureka-client - 1.0.0-SNAPSHOT + ${spring-cloud-eureka-client.version} org.springframework.cloud @@ -52,9 +51,6 @@ - Brixton.SR7 - 1.2.3.RELEASE - 1.2.3.RELEASE - 1.4.2.RELEASE + 1.0.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/src/main/resources/logback.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-feign-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml index 4ea9748c14..8082b30c33 100644 --- a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/pom.xml @@ -1,13 +1,10 @@ - + 4.0.0 - spring-cloud-eureka-server 1.0.0-SNAPSHOT jar - Spring Cloud Eureka Server Spring Cloud Eureka Server Demo @@ -38,8 +35,4 @@ - - Brixton.SR7 - 1.2.3.RELEASE - diff --git a/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/src/main/resources/logback.xml b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-eureka/spring-cloud-eureka-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-functions/README.MD b/spring-cloud/spring-cloud-functions/README.MD new file mode 100644 index 0000000000..c766dd1dc6 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/README.MD @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Serverless Functions with Spring Cloud Function](https://www.baeldung.com/spring-cloud-function) diff --git a/spring-cloud/spring-cloud-functions/pom.xml b/spring-cloud/spring-cloud-functions/pom.xml new file mode 100644 index 0000000000..8b2b0ad385 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + com.baeldung.spring + cloudfunction-aws + 0.0.1-SNAPSHOT + jar + + cloudfunction-aws + Demo project for Spring Cloud Function + + + org.springframework.boot + spring-boot-starter-parent + 2.0.4.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + 1.0.1.RELEASE + 2.0.2 + + + + + org.springframework.cloud + spring-cloud-function-adapter-aws + ${spring-cloud-function.version} + + + + + org.springframework.cloud + spring-cloud-starter-function-web + 1.0.1.RELEASE + + + com.amazonaws + aws-lambda-java-events + ${aws-lambda-events.version} + provided + + + com.amazonaws + aws-lambda-java-core + 1.1.0 + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.springframework.boot.experimental + spring-boot-thin-layout + 1.0.10.RELEASE + + + + + org.apache.maven.plugins + maven-shade-plugin + + false + true + aws + + + + + + diff --git a/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionAwsApplication.java b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionAwsApplication.java new file mode 100644 index 0000000000..34e97d3b6c --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionAwsApplication.java @@ -0,0 +1,23 @@ +package com.baeldung.spring.cloudfunction.aws; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +@SpringBootApplication +public class CloudFunctionAwsApplication { + + public static void main(String[] args) { + SpringApplication.run(CloudFunctionAwsApplication.class, args); + } + + @Bean + public Function reverseString() { + return value -> new StringBuilder(value).reverse().toString(); + } + +} diff --git a/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/StringReverseHandler.java b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/StringReverseHandler.java new file mode 100644 index 0000000000..52514dcd12 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/StringReverseHandler.java @@ -0,0 +1,7 @@ +package com.baeldung.spring.cloudfunction.aws; + +import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler; + +public class StringReverseHandler extends SpringBootRequestHandler { + +} diff --git a/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/functions/Greeter.java b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/functions/Greeter.java new file mode 100644 index 0000000000..c443b98c18 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/functions/Greeter.java @@ -0,0 +1,11 @@ +package com.baeldung.spring.cloudfunction.functions.aws; + +import java.util.function.Function; + +public class Greeter implements Function { + + @Override + public String apply(String s) { + return "Hello " + s + ", and welcome to Spring Cloud Function!!!"; + } +} diff --git a/spring-cloud/spring-cloud-functions/src/main/resources/application.properties b/spring-cloud/spring-cloud-functions/src/main/resources/application.properties new file mode 100644 index 0000000000..b445bfa4ed --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.cloud.function.scan.packages: com.baeldung.spring.cloudfunction.functions.aws \ No newline at end of file diff --git a/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionApplicationTests.java b/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionApplicationTests.java new file mode 100644 index 0000000000..6039debe3f --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionApplicationTests.java @@ -0,0 +1,33 @@ +package com.baeldung.spring.cloudfunction.aws; + +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.test.context.junit4.SpringRunner; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CloudFunctionApplicationTests { + + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Test + public void givenAString_whenReverseStringCloudFunctionInvoked_thenStringIsReversed() { + assertThat(this.testRestTemplate.getForObject("http://localhost:" + port + "/reverseString/HelloWorld", String.class)).isEqualTo("dlroWolleH"); + } + + @Test + public void givenAString_whenGreeterCloudFunctionInvoked_thenPrintsGreeting() { + assertThat(this.testRestTemplate.getForObject("http://localhost:" + port + "/greeter/BaeldungUser", String.class)).isEqualTo("Hello BaeldungUser, and welcome to Spring Cloud Function!!!"); + } + +} diff --git a/spring-cloud/spring-cloud-gateway/pom.xml b/spring-cloud/spring-cloud-gateway/pom.xml index aa523ec604..4d8b57d4cf 100644 --- a/spring-cloud/spring-cloud-gateway/pom.xml +++ b/spring-cloud/spring-cloud-gateway/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 spring-cloud-gateway jar @@ -14,7 +13,7 @@ .. - + org.springframework.cloud @@ -29,7 +28,7 @@ org.springframework.cloud - spring-cloud-starter-gateway + spring-cloud-starter org.springframework.boot @@ -39,11 +38,16 @@ org.springframework.boot spring-boot-starter-webflux + + org.springframework.boot + spring-boot-starter-test + test + org.hibernate hibernate-validator-cdi - 6.0.2.Final + ${hibernate-validator.version} javax.validation @@ -55,31 +59,9 @@ - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - UTF-8 - 3.7.0 - 2.0.0.RELEASE - 2.0.0.RELEASE - 2.0.0.RC2 + 2.0.1.RELEASE + 6.0.2.Final diff --git a/spring-cloud/spring-cloud-gateway/src/main/resources/logback.xml b/spring-cloud/spring-cloud-gateway/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-gateway/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..f2addf5c1a --- /dev/null +++ b/spring-cloud/spring-cloud-gateway/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.GatewayApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = GatewayApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-hystrix/feign-rest-consumer/pom.xml b/spring-cloud/spring-cloud-hystrix/feign-rest-consumer/pom.xml index 700357d673..11b9275b46 100644 --- a/spring-cloud/spring-cloud-hystrix/feign-rest-consumer/pom.xml +++ b/spring-cloud/spring-cloud-hystrix/feign-rest-consumer/pom.xml @@ -19,38 +19,37 @@ com.baeldung.spring.cloud rest-producer - 1.0.0-SNAPSHOT + ${rest-producer.version} org.springframework.cloud spring-cloud-starter-hystrix - ${spring-cloud-starter-hystrix.version} org.springframework.cloud spring-cloud-starter-hystrix-dashboard - ${spring-cloud-starter-hystrix.version} org.springframework.cloud spring-cloud-starter-feign - ${spring-cloud-starter-feign.version} org.springframework.boot spring-boot-starter-web - ${spring-boot-starter-web.version} org.springframework.boot spring-boot-starter-thymeleaf - ${spring-boot-starter-web.version} org.springframework.boot spring-boot-starter-actuator - ${spring-boot-starter-web.version} + + org.springframework.boot + spring-boot-starter-test + test + @@ -66,8 +65,6 @@ - 1.2.3.RELEASE - 1.2.3.RELEASE - 1.4.2.RELEASE + 1.0.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-hystrix/feign-rest-consumer/src/main/resources/logback.xml b/spring-cloud/spring-cloud-hystrix/feign-rest-consumer/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-hystrix/feign-rest-consumer/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-hystrix/pom.xml b/spring-cloud/spring-cloud-hystrix/pom.xml index e7b635a441..266644b4c3 100644 --- a/spring-cloud/spring-cloud-hystrix/pom.xml +++ b/spring-cloud/spring-cloud-hystrix/pom.xml @@ -22,10 +22,4 @@ feign-rest-consumer - - UTF-8 - 3.7.0 - 1.4.2.RELEASE - - diff --git a/spring-cloud/spring-cloud-hystrix/rest-consumer/pom.xml b/spring-cloud/spring-cloud-hystrix/rest-consumer/pom.xml index 81fb442ad7..651f80fc92 100644 --- a/spring-cloud/spring-cloud-hystrix/rest-consumer/pom.xml +++ b/spring-cloud/spring-cloud-hystrix/rest-consumer/pom.xml @@ -1,13 +1,11 @@ - + 4.0.0 rest-consumer 1.0.0-SNAPSHOT jar - rest-consumer @@ -57,9 +55,4 @@ - - Brixton.SR7 - 1.2.3.RELEASE - 1.4.2.RELEASE - diff --git a/spring-cloud/spring-cloud-hystrix/rest-consumer/src/main/resources/logback.xml b/spring-cloud/spring-cloud-hystrix/rest-consumer/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-hystrix/rest-consumer/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-hystrix/rest-producer/pom.xml b/spring-cloud/spring-cloud-hystrix/rest-producer/pom.xml index f96d8e1768..8437ac6833 100644 --- a/spring-cloud/spring-cloud-hystrix/rest-producer/pom.xml +++ b/spring-cloud/spring-cloud-hystrix/rest-producer/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 rest-producer @@ -25,7 +24,4 @@ - - Brixton.SR7 - diff --git a/spring-cloud/spring-cloud-hystrix/rest-producer/src/main/resources/logback.xml b/spring-cloud/spring-cloud-hystrix/rest-producer/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-hystrix/rest-producer/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes/demo-backend/pom.xml b/spring-cloud/spring-cloud-kubernetes/demo-backend/pom.xml index 109953ea42..308a81fd74 100644 --- a/spring-cloud/spring-cloud-kubernetes/demo-backend/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/demo-backend/pom.xml @@ -1,21 +1,14 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + demo-backend com.baeldung.spring.cloud spring-cloud-kubernetes 1.0-SNAPSHOT - demo-backend - - - - UTF-8 - UTF-8 - 1.8 - @@ -39,5 +32,4 @@ - diff --git a/spring-cloud/spring-cloud-kubernetes/demo-backend/src/main/resources/logback.xml b/spring-cloud/spring-cloud-kubernetes/demo-backend/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-kubernetes/demo-backend/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes/demo-backend/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-kubernetes/demo-backend/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ce57cf5052 --- /dev/null +++ b/spring-cloud/spring-cloud-kubernetes/demo-backend/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.kubernetes.backend.KubernetesBackendApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = KubernetesBackendApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud/spring-cloud-kubernetes/demo-frontend/pom.xml b/spring-cloud/spring-cloud-kubernetes/demo-frontend/pom.xml index 32fa900f39..968529c648 100644 --- a/spring-cloud/spring-cloud-kubernetes/demo-frontend/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/demo-frontend/pom.xml @@ -1,21 +1,14 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + demo-frontend com.baeldung.spring.cloud spring-cloud-kubernetes 1.0-SNAPSHOT - demo-frontend - - - - UTF-8 - UTF-8 - 1.8 - @@ -39,5 +32,4 @@ - diff --git a/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/main/resources/logback.xml b/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/test/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplicationIntegrationTest.java b/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/test/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplicationIntegrationTest.java deleted file mode 100644 index 19ad9676cb..0000000000 --- a/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/test/java/com/baeldung/spring/cloud/kubernetes/frontend/KubernetesFrontendApplicationIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.spring.cloud.kubernetes.frontend; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class KubernetesFrontendApplicationIntegrationTest { - - @Test - public void contextLoads() { - } - -} diff --git a/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..f7e9e35540 --- /dev/null +++ b/spring-cloud/spring-cloud-kubernetes/demo-frontend/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.kubernetes.frontend.KubernetesFrontendApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = KubernetesFrontendApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud/spring-cloud-kubernetes/pom.xml b/spring-cloud/spring-cloud-kubernetes/pom.xml index 61fd84ca27..fd9f7b5876 100644 --- a/spring-cloud/spring-cloud-kubernetes/pom.xml +++ b/spring-cloud/spring-cloud-kubernetes/pom.xml @@ -1,7 +1,7 @@ - + + 4.0.0 com.baeldung.spring.cloud spring-cloud-kubernetes @@ -19,7 +19,5 @@ 0.0.1-SNAPSHOT ../../parent-boot-1 - 4.0.0 - \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/pom.xml b/spring-cloud/spring-cloud-rest/pom.xml index bf0dbd7ee6..f78f58caa0 100644 --- a/spring-cloud/spring-cloud-rest/pom.xml +++ b/spring-cloud/spring-cloud-rest/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 org.baeldung spring-cloud-rest @@ -44,8 +43,6 @@ - UTF-8 - 3.7.0 1.4.2.RELEASE 1.8 1.8 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 664ab96576..d1139b1fa4 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 @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung spring-cloud-rest-books-api diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/resources/logback.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/BooksApiIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/BooksApiIntegrationTest.java index d6b0ee1694..15056e110c 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/BooksApiIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/BooksApiIntegrationTest.java @@ -2,7 +2,14 @@ package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @@ -13,4 +20,24 @@ public class BooksApiIntegrationTest { public void contextLoads() { } + @EnableRedisHttpSession + @Configuration + static class Config { + + @Bean + @SuppressWarnings("unchecked") + public RedisSerializer defaultRedisSerializer() { + return Mockito.mock(RedisSerializer.class); + } + + @Bean + public RedisConnectionFactory connectionFactory() { + + RedisConnectionFactory factory = Mockito.mock(RedisConnectionFactory.class); + RedisConnection connection = Mockito.mock(RedisConnection.class); + Mockito.when(factory.getConnection()).thenReturn(connection); + + return factory; + } + } } diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..24e758ff82 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-books-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BooksApiApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} 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 814f5edfcb..a43829666c 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 @@ -1,13 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.baeldung spring-cloud-rest-config-server 0.0.1-SNAPSHOT jar - spring-cloud-rest-config-server Spring Cloud REST configuration server @@ -18,10 +16,6 @@ ../../../parent-boot-1 - - Camden.SR4 - - org.springframework.cloud @@ -49,4 +43,8 @@ + + Camden.SR4 + + diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/resources/logback.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-bootstrap/src/test/java/org/baeldung/SpringBootBootstrapApplicationIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 72% rename from spring-boot-bootstrap/src/test/java/org/baeldung/SpringBootBootstrapApplicationIntegrationTest.java rename to spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 7c54288665..28c6e67377 100644 --- a/spring-boot-bootstrap/src/test/java/org/baeldung/SpringBootBootstrapApplicationIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-config-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -6,10 +6,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest -public class SpringBootBootstrapApplicationIntegrationTest { - +@SpringBootTest(classes = SpringCloudRestConfigApplication.class) +public class SpringContextIntegrationTest { @Test public void contextLoads() { } + } 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 f3ce213540..5b656d4342 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 @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung spring-cloud-rest-discovery-server @@ -52,7 +52,7 @@ - Camden.SR4 + Edgware.SR4 diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/resources/logback.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java index e077c42a96..14597d5c2f 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringCloudRestServerIntegrationTest.java @@ -2,7 +2,14 @@ package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @@ -11,5 +18,25 @@ public class SpringCloudRestServerIntegrationTest { @Test public void contextLoads() { } + + @EnableRedisHttpSession + @Configuration + static class Config { + + @Bean + @SuppressWarnings("unchecked") + public RedisSerializer defaultRedisSerializer() { + return Mockito.mock(RedisSerializer.class); + } -} + @Bean + public RedisConnectionFactory connectionFactory() { + + RedisConnectionFactory factory = Mockito.mock(RedisConnectionFactory.class); + RedisConnection connection = Mockito.mock(RedisConnection.class); + Mockito.when(factory.getConnection()).thenReturn(connection); + + return factory; + } + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..e22359a016 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-discovery-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringCloudRestServerApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} 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 27e327110a..ef969e04e5 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 @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung spring-cloud-rest-reviews-api @@ -16,10 +16,6 @@ ../../../parent-boot-1 - - 3.0.1 - - org.springframework.cloud @@ -57,6 +53,11 @@ org.springframework.boot spring-boot-starter-data-redis + + com.github.kstyrc + embedded-redis + ${embedded-redis.version} + @@ -71,4 +72,9 @@ + + 3.0.1 + 0.6 + + diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/resources/logback.xml b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java index d25e0bee20..c63b4ebb08 100644 --- a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/BookReviewsApiIntegrationTest.java @@ -2,7 +2,14 @@ package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @@ -13,4 +20,24 @@ public class BookReviewsApiIntegrationTest { public void contextLoads() { } + @EnableRedisHttpSession + @Configuration + static class Config { + + @Bean + @SuppressWarnings("unchecked") + public RedisSerializer defaultRedisSerializer() { + return Mockito.mock(RedisSerializer.class); + } + + @Bean + public RedisConnectionFactory connectionFactory() { + + RedisConnectionFactory factory = Mockito.mock(RedisConnectionFactory.class); + RedisConnection connection = Mockito.mock(RedisConnection.class); + Mockito.when(factory.getConnection()).thenReturn(connection); + + return factory; + } + } } diff --git a/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..07d7db0505 --- /dev/null +++ b/spring-cloud/spring-cloud-rest/spring-cloud-rest-reviews-api/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BookReviewsApiApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-ribbon-client/pom.xml b/spring-cloud/spring-cloud-ribbon-client/pom.xml index 64682c6173..12125f4cf3 100644 --- a/spring-cloud/spring-cloud-ribbon-client/pom.xml +++ b/spring-cloud/spring-cloud-ribbon-client/pom.xml @@ -1,8 +1,8 @@ + 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 - spring-cloud-ribbon + spring-cloud-ribbon-client 0.0.1-SNAPSHOT jar spring-cloud-ribbon-client @@ -38,25 +38,6 @@ - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - Brixton.SR7 diff --git a/spring-cloud/spring-cloud-ribbon-client/src/main/resources/logback.xml b/spring-cloud/spring-cloud-ribbon-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-ribbon-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-ribbon-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-ribbon-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..baa1b12eff --- /dev/null +++ b/spring-cloud/spring-cloud-ribbon-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.ribbon.client.ServerLocationApp; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ServerLocationApp.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-security/README.md b/spring-cloud/spring-cloud-security/README.md deleted file mode 100644 index 39af52c077..0000000000 --- a/spring-cloud/spring-cloud-security/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# README # - -This README would normally document whatever steps are necessary to get your application up and running. - -### What is this repository for? ### - -* Quick summary -* Version -* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo) - -### How do I get set up? ### - -* Summary of set up -* Configuration -* Dependencies -* Database configuration -* How to run tests -* Deployment instructions - -### Contribution guidelines ### - -* Writing tests -* Code review -* Other guidelines - -### Who do I talk to? ### - -* Repo owner or admin -* Other community or team contact \ No newline at end of file diff --git a/spring-cloud/spring-cloud-security/auth-client/pom.xml b/spring-cloud/spring-cloud-security/auth-client/pom.xml index 1f6c22e2e1..340c276c2d 100644 --- a/spring-cloud/spring-cloud-security/auth-client/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-client/pom.xml @@ -1,41 +1,18 @@ + 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 auth-client - 0.0.1-SNAPSHOT jar - auth-client - Demo project for Spring Boot - + Spring Cloud Security APP Client Module + - org.springframework.boot - spring-boot-starter-parent - 1.5.9.RELEASE - + spring-cloud-security + com.baeldung + 1.0.0-SNAPSHOT - - - - org.springframework.cloud - spring-cloud-dependencies - Dalston.SR4 - pom - import - - - - - - - UTF-8 - UTF-8 - 1.8 - - org.springframework.boot @@ -66,7 +43,6 @@ org.webjars webjars-locator - org.springframework.boot spring-boot-starter-security @@ -74,20 +50,17 @@ org.webjars js-cookie - 2.1.0 + ${js-cookie.version} - org.springframework.boot spring-boot-devtools true - org.springframework.boot spring-boot-starter-thymeleaf - @@ -98,4 +71,22 @@ + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + 2.1.0 + Dalston.SR4 + + diff --git a/spring-cloud/spring-cloud-security/auth-client/src/main/resources/logback.xml b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java b/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationIntegrationTest.java similarity index 69% rename from spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java rename to spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationIntegrationTest.java index 5fa51a61c3..37cff095db 100644 --- a/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java +++ b/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationIntegrationTest.java @@ -5,9 +5,11 @@ import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.CloudSite; + @RunWith(SpringRunner.class) -@SpringBootTest -public class Springoath2ApplicationTests { +@SpringBootTest(classes = CloudSite.class) +public class Springoath2ApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringCloudConfigServerApplicationTests.java b/spring-cloud/spring-cloud-security/auth-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 64% rename from spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringCloudConfigServerApplicationTests.java rename to spring-cloud/spring-cloud-security/auth-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 3969c7ba2d..60a208d6f4 100644 --- a/spring-cloud-bus/spring-cloud-config-server/src/test/java/com/baeldung/SpringCloudConfigServerApplicationTests.java +++ b/spring-cloud/spring-cloud-security/auth-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,13 +1,15 @@ -package com.baeldung; +package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.CloudSite; + @RunWith(SpringRunner.class) -@SpringBootTest -public class SpringCloudConfigServerApplicationTests { +@SpringBootTest(classes = CloudSite.class) +public class SpringContextIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud/spring-cloud-security/auth-resource/pom.xml b/spring-cloud/spring-cloud-security/auth-resource/pom.xml index 3813cd3a52..09474b2a4d 100644 --- a/spring-cloud/spring-cloud-security/auth-resource/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-resource/pom.xml @@ -3,28 +3,18 @@ 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 auth-resource - 0.0.1-SNAPSHOT jar auth-resource - Demo project for Spring Boot + Spring Cloud Security APP Resource Module - org.springframework.boot - spring-boot-starter-parent - 1.5.9.RELEASE - + spring-cloud-security + com.baeldung + 1.0.0-SNAPSHOT - - - UTF-8 - UTF-8 - 1.8 - Edgware.RELEASE - - + org.springframework.security.oauth @@ -66,5 +56,8 @@ + + Edgware.RELEASE + diff --git a/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/logback.xml b/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java b/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationIntegrationTest.java similarity index 85% rename from spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java rename to spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationIntegrationTest.java index e0fe7006d9..3caa06ba4d 100644 --- a/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java +++ b/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class PersonserviceApplicationTests { +public class PersonserviceApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud/spring-cloud-security/auth-resource/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-security/auth-resource/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..4d4c312bce --- /dev/null +++ b/spring-cloud/spring-cloud-security/auth-resource/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud/spring-cloud-security/auth-server/pom.xml b/spring-cloud/spring-cloud-security/auth-server/pom.xml index 82141c1015..92f92808f6 100644 --- a/spring-cloud/spring-cloud-security/auth-server/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-server/pom.xml @@ -1,20 +1,16 @@ + 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 auth-server - 0.0.1-SNAPSHOT - - + Spring Cloud Security APP Server Module + - org.springframework.boot - spring-boot-starter-parent - 1.5.9.RELEASE + spring-cloud-security + com.baeldung + 1.0.0-SNAPSHOT - org.springframework.boot @@ -36,7 +32,12 @@ org.springframework.cloud spring-cloud-starter-oauth2 - 1.1.2.RELEASE + ${spring-cloud-starter-oauth2.version} + + + 1.1.2.RELEASE + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-security/auth-server/src/main/resources/logback.xml b/spring-cloud/spring-cloud-security/auth-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-security/auth-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/spring/cloud/TimeProcessorApplicationIntegrationTest.java b/spring-cloud/spring-cloud-security/auth-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 64% rename from spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/spring/cloud/TimeProcessorApplicationIntegrationTest.java rename to spring-cloud/spring-cloud-security/auth-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 9bd0fd8c24..63a89ac45c 100644 --- a/spring-cloud-data-flow/time-processor/src/test/java/org/baeldung/spring/cloud/TimeProcessorApplicationIntegrationTest.java +++ b/spring-cloud/spring-cloud-security/auth-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,13 +1,15 @@ -package org.baeldung.spring.cloud; +package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import com.baeldung.AuthServer; + @RunWith(SpringRunner.class) -@SpringBootTest -public class TimeProcessorApplicationIntegrationTest { +@SpringBootTest(classes = AuthServer.class) +public class SpringContextIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud/spring-cloud-security/pom.xml b/spring-cloud/spring-cloud-security/pom.xml new file mode 100644 index 0000000000..1cf8751548 --- /dev/null +++ b/spring-cloud/spring-cloud-security/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + spring-cloud-security + pom + 1.0.0-SNAPSHOT + spring-cloud-security + + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-1 + + + + auth-client + auth-resource + auth-server + + + diff --git a/spring-cloud/spring-cloud-stream-starters/boot/.gitignore b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/.gitignore similarity index 100% rename from spring-cloud/spring-cloud-stream-starters/boot/.gitignore rename to spring-cloud/spring-cloud-stream-starters/twitterhdfs/.gitignore diff --git a/spring-cloud/spring-cloud-stream-starters/boot/pom.xml b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml similarity index 61% rename from spring-cloud/spring-cloud-stream-starters/boot/pom.xml rename to spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml index 3e6bc134e3..6f582576d8 100644 --- a/spring-cloud/spring-cloud-stream-starters/boot/pom.xml +++ b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/pom.xml @@ -1,25 +1,18 @@ - - + + 4.0.0 com.baeldung.twitterhdfs twitterhdfs jar - 1.0.0 - + 1.0.0-SNAPSHOT twitterhdfs - - UTF-8 - UTF-8 - 1.8 - - - org.springframework.boot - spring-boot-starter-parent - 1.5.8.RELEASE + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../../parent-boot-1 @@ -27,20 +20,18 @@ org.springframework.cloud.stream.app spring-cloud-starter-stream-source-twitterstream - 1.3.1.RELEASE + ${spring-cloud-starter-stream.version} org.springframework.cloud.stream.app spring-cloud-starter-stream-sink-hdfs - 1.3.1.RELEASE + ${spring-cloud-starter-stream.version} - javax.servlet jstl - @@ -52,4 +43,9 @@ twitterhdfs + + + 1.3.1.RELEASE + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-stream-starters/boot/src/main/java/com/baeldung/twitterhdfs/aggregate/AggregateApp.java b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/java/com/baeldung/twitterhdfs/aggregate/AggregateApp.java similarity index 100% rename from spring-cloud/spring-cloud-stream-starters/boot/src/main/java/com/baeldung/twitterhdfs/aggregate/AggregateApp.java rename to spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/java/com/baeldung/twitterhdfs/aggregate/AggregateApp.java diff --git a/spring-cloud/spring-cloud-stream-starters/boot/src/main/java/com/baeldung/twitterhdfs/processor/ProcessorApp.java b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/java/com/baeldung/twitterhdfs/processor/ProcessorApp.java similarity index 100% rename from spring-cloud/spring-cloud-stream-starters/boot/src/main/java/com/baeldung/twitterhdfs/processor/ProcessorApp.java rename to spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/java/com/baeldung/twitterhdfs/processor/ProcessorApp.java diff --git a/spring-cloud/spring-cloud-stream-starters/boot/src/main/java/com/baeldung/twitterhdfs/sink/SinkApp.java b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/java/com/baeldung/twitterhdfs/sink/SinkApp.java similarity index 100% rename from spring-cloud/spring-cloud-stream-starters/boot/src/main/java/com/baeldung/twitterhdfs/sink/SinkApp.java rename to spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/java/com/baeldung/twitterhdfs/sink/SinkApp.java diff --git a/spring-cloud/spring-cloud-stream-starters/boot/src/main/java/com/baeldung/twitterhdfs/source/SourceApp.java b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/java/com/baeldung/twitterhdfs/source/SourceApp.java similarity index 100% rename from spring-cloud/spring-cloud-stream-starters/boot/src/main/java/com/baeldung/twitterhdfs/source/SourceApp.java rename to spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/java/com/baeldung/twitterhdfs/source/SourceApp.java diff --git a/spring-cloud/spring-cloud-stream-starters/boot/src/main/resources/application.properties b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/resources/application.properties similarity index 100% rename from spring-cloud/spring-cloud-stream-starters/boot/src/main/resources/application.properties rename to spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/resources/application.properties diff --git a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/resources/logback.xml b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..3d370e7b48 --- /dev/null +++ b/spring-cloud/spring-cloud-stream-starters/twitterhdfs/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.twitterhdfs.aggregate.AggregateApp; +import com.baeldung.twitterhdfs.processor.ProcessorApp; +import com.baeldung.twitterhdfs.sink.SinkApp; +import com.baeldung.twitterhdfs.source.SourceApp; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {AggregateApp.class, ProcessorApp.class, SinkApp.class, SourceApp.class}) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-stream/pom.xml b/spring-cloud/spring-cloud-stream/pom.xml index ef691fbeea..d62b959131 100644 --- a/spring-cloud/spring-cloud-stream/pom.xml +++ b/spring-cloud/spring-cloud-stream/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 org.baeldung spring-cloud-stream @@ -39,9 +38,4 @@ - - UTF-8 - 3.7.0 - - diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/logback.xml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..70c5f46aa1 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.stream.rabbit.MultipleOutputsServiceApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = MultipleOutputsServiceApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-task/pom.xml b/spring-cloud/spring-cloud-task/pom.xml new file mode 100644 index 0000000000..ef76d464bc --- /dev/null +++ b/spring-cloud/spring-cloud-task/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + com.baeldung.spring.cloud + spring-cloud-task + 1.0.0-SNAPSHOT + pom + + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-1 + + + + springcloudtaskbatch + springcloudtasksink + + + + + + org.springframework.cloud + spring-cloud-task-dependencies + ${spring-cloud-task.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud-dependencies.version} + pom + import + + + + + + Brixton.SR7 + 1.2.2.RELEASE + + + diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml b/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml index 1bb3d98efb..89c9318c4e 100644 --- a/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml +++ b/spring-cloud/spring-cloud-task/springcloudtaskbatch/pom.xml @@ -1,26 +1,16 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.cloud - springcloudtask - 0.0.1-SNAPSHOT + springcloudtaskbatch + springcloudtaskbatch - org.springframework.boot - spring-boot-starter-parent - 1.5.10.RELEASE - + spring-cloud-task + com.baeldung.spring.cloud + 1.0.0-SNAPSHOT - - com.baeldung.TaskDemo - UTF-8 - UTF-8 - 1.8 - 1.2.2.RELEASE - - - org.springframework.boot @@ -55,19 +45,6 @@ - - - - org.springframework.cloud - spring-cloud-task-dependencies - ${spring-cloud-task.version} - pom - import - - - - - @@ -77,4 +54,8 @@ + + com.baeldung.TaskDemo + + diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/main/resources/logback.xml b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..4b5aff2db8 --- /dev/null +++ b/spring-cloud/spring-cloud-task/springcloudtaskbatch/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.task.JobConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = JobConfiguration.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-task/springcloudtasksink/pom.xml b/spring-cloud/spring-cloud-task/springcloudtasksink/pom.xml index 3aa038b3f3..ca0de342a9 100644 --- a/spring-cloud/spring-cloud-task/springcloudtasksink/pom.xml +++ b/spring-cloud/spring-cloud-task/springcloudtasksink/pom.xml @@ -1,31 +1,18 @@ + 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 SpringCloudTaskSink - 0.0.1-SNAPSHOT jar - SpringCloudTaskSink Demo project for Spring Boot - - org.springframework.boot - spring-boot-starter-parent - 1.5.10.RELEASE - + + spring-cloud-task + com.baeldung.spring.cloud + 1.0.0-SNAPSHOT - - UTF-8 - UTF-8 - 1.8 - 1.2.2.RELEASE - Edgware.SR2 - - org.springframework.cloud @@ -45,38 +32,14 @@ spring-boot-starter-test test - - org.springframework.boot - spring-boot-starter-test - test - org.springframework.cloud spring-cloud-deployer-local - 1.3.0.RELEASE + ${spring-cloud-deployer.version} - - - - org.springframework.cloud - spring-cloud-task-dependencies - ${spring-cloud-task.version} - pom - import - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - @@ -85,4 +48,10 @@ + + + 1.2.2.RELEASE + 1.3.0.RELEASE + + diff --git a/spring-cloud/spring-cloud-task/springcloudtasksink/src/main/resources/logback.xml b/spring-cloud/spring-cloud-task/springcloudtasksink/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-task/springcloudtasksink/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringCloudTaskFinal/SpringCloudTaskSinkApplicationTests.java b/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringCloudTaskFinal/SpringCloudTaskSinkApplicationIntegrationTest.java similarity index 97% rename from spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringCloudTaskFinal/SpringCloudTaskSinkApplicationTests.java rename to spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringCloudTaskFinal/SpringCloudTaskSinkApplicationIntegrationTest.java index 1f47eada14..104c04138e 100644 --- a/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringCloudTaskFinal/SpringCloudTaskSinkApplicationTests.java +++ b/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringCloudTaskFinal/SpringCloudTaskSinkApplicationIntegrationTest.java @@ -24,7 +24,7 @@ import static org.mockito.Mockito.verify; @RunWith(SpringRunner.class) @SpringBootTest( classes = SpringCloudTaskSinkApplication.class) -public class SpringCloudTaskSinkApplicationTests { +public class SpringCloudTaskSinkApplicationIntegrationTest { @Autowired ApplicationContext context; diff --git a/spring-cloud/spring-cloud-task/springcloudtasksink/src/main/java/com/baeldung/SpringCloudTaskFinal/TaskSinkConfiguration.java b/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringCloudTaskFinal/TaskSinkConfiguration.java similarity index 100% rename from spring-cloud/spring-cloud-task/springcloudtasksink/src/main/java/com/baeldung/SpringCloudTaskFinal/TaskSinkConfiguration.java rename to spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/com/baeldung/SpringCloudTaskFinal/TaskSinkConfiguration.java diff --git a/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..b8dd03d65f --- /dev/null +++ b/spring-cloud/spring-cloud-task/springcloudtasksink/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.SpringCloudTaskFinal.SpringCloudTaskSinkApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringCloudTaskSinkApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-vault/.gitignore b/spring-cloud/spring-cloud-vault/.gitignore new file mode 100644 index 0000000000..e6237b6f81 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/.gitignore @@ -0,0 +1,29 @@ +/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/ + +## Extra +/vault-data/ +*.log diff --git a/spring-cloud/spring-cloud-vault/database-setup.sql b/spring-cloud/spring-cloud-vault/database-setup.sql new file mode 100644 index 0000000000..4bb1293f74 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/database-setup.sql @@ -0,0 +1,20 @@ +-- +-- Sample schema for testing vault database secrets +-- +create schema fakebank; +use fakebank; +create table account( + id decimal(16,0), + name varchar(30), + branch_id decimal(16,0), + customer_id decimal(16,0), + primary key (id)); + +-- +-- MySQL user that will be used by Vault to create other users on demand +-- +create user 'fakebank-admin'@'%' identified by 'Sup&rSecre7!' +grant all privileges on fakebank.* to 'fakebank-admin'@'%' with grant option; +grant create user on *.* to 'fakebank-admin' with grant option; + +flush privileges; diff --git a/spring-cloud/spring-cloud-vault/pom.xml b/spring-cloud/spring-cloud-vault/pom.xml new file mode 100644 index 0000000000..68b8e44875 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + org.baeldung.spring.cloud + spring-cloud-vault + jar + + spring-cloud-vault + Demo project for Spring Boot + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + + UTF-8 + UTF-8 + 1.8 + Finchley.SR1 + + + + + + + + + org.springframework.cloud + spring-cloud-starter-vault-config + + + + org.springframework.cloud + spring-cloud-vault-config-databases + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + mysql + mysql-connector-java + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-cloud/spring-cloud-vault/sample-policy.hcl b/spring-cloud/spring-cloud-vault/sample-policy.hcl new file mode 100644 index 0000000000..554888661e --- /dev/null +++ b/spring-cloud/spring-cloud-vault/sample-policy.hcl @@ -0,0 +1,6 @@ +path "secret/fakebank" { + capabilities = ["read"] + allowed_parameters = { + "api_key" = [] + } +} diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java new file mode 100644 index 0000000000..81ece1ca4c --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java @@ -0,0 +1,12 @@ +package org.baeldung.spring.cloud.vaultsample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class VaultSampleApplication { + + public static void main(String[] args) { + SpringApplication.run(VaultSampleApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/application.yml b/spring-cloud/spring-cloud-vault/src/main/resources/application.yml new file mode 100644 index 0000000000..3d347ec855 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/resources/application.yml @@ -0,0 +1,6 @@ +spring: + application: + name: fakebank + + datasource: + url: jdbc:mysql://localhost:3306/fakebank diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml b/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000..1e837c4920 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml @@ -0,0 +1,37 @@ +spring: + cloud: + vault: + uri: https://localhost:8200 + connection-timeout: 5000 + read-timeout: 15000 + config: + order: -10 + + ssl: + trust-store: classpath:/vault.jks + trust-store-password: changeit + + generic: + enabled: true + application-name: fakebank + + kv: + enabled: false + backend: kv + application-name: fakebank + + database: + enabled: true + role: fakebank-accounts-rw +# backend: database +# username-property: spring.datasource.username +# password-property: spring.datasource.password + + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/vault.jks b/spring-cloud/spring-cloud-vault/src/main/resources/vault.jks new file mode 100644 index 0000000000..7090707543 Binary files /dev/null and b/spring-cloud/spring-cloud-vault/src/main/resources/vault.jks differ diff --git a/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java b/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java new file mode 100644 index 0000000000..7a9c5ba11a --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java @@ -0,0 +1,66 @@ +package org.baeldung.spring.cloud.vaultsample; + +import static org.junit.Assert.assertEquals; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; + +import javax.sql.DataSource; + +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.core.env.Environment; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class VaultSampleApplicationLiveTest { + + @Autowired + Environment env; + + @Autowired + DataSource datasource; + + + @Test + public void whenGenericBackendEnabled_thenEnvHasAccessToVaultSecrets() { + + String fooValue = env.getProperty("foo"); + assertEquals("test-bar", fooValue); + + } + + @Test + public void whenKvBackendEnabled_thenEnvHasAccessToVaultSecrets() { + + String fooValue = env.getProperty("foo.versioned"); + assertEquals("bar1", fooValue); + + + } + + + @Test + public void whenDatabaseBackendEnabled_thenDatasourceUsesVaultCredentials() { + + try (Connection c = datasource.getConnection()) { + + ResultSet rs = c.createStatement() + .executeQuery("select 1"); + + rs.next(); + Long value = rs.getLong(1); + + assertEquals(Long.valueOf(1), value); + + } catch (SQLException sex) { + throw new RuntimeException(sex); + } + + } + +} diff --git a/spring-cloud/spring-cloud-vault/src/test/resources/bootstrap.properties b/spring-cloud/spring-cloud-vault/src/test/resources/bootstrap.properties new file mode 100644 index 0000000000..8c54227dda --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/resources/bootstrap.properties @@ -0,0 +1,3 @@ +spring.cloud.vault.token=b93d1b0d-15b5-f69e-d311-352a65fa7bc8 + +logging.level.org.springframework=INFO \ No newline at end of file diff --git a/spring-cloud/spring-cloud-vault/src/test/resources/vault.jks b/spring-cloud/spring-cloud-vault/src/test/resources/vault.jks new file mode 100644 index 0000000000..7090707543 Binary files /dev/null and b/spring-cloud/spring-cloud-vault/src/test/resources/vault.jks differ diff --git a/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.cert b/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.cert new file mode 100644 index 0000000000..6a598df419 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.cert @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+zCCAeOgAwIBAgIJAKoy5OBgOKYwMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV +BAMMCWxvY2FsaG9zdDAeFw0xODA4MDkwMTM1MzJaFw0yODA4MDYwMTM1MzJaMBQx +EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMXiHqB5dYdxJ1+abSG55gb3NNo3fzNbkjp/tAIl1FUeyCyyP/yERrkUkhFj +4gg/q1YHUO/ftc0PdL/JBaVBTKnzsxgp7hY/dUEkZqXZ649X0UrJIRd13w5N71cL +P1+PjCrqokMVceU18kK7CyaOmiTKYFmt/RTJQLmFQspmJXNSiq7zUvAgyvoY5TzJ +n7MuSobHXq17pnlm+XbnAgDJUt9yR6BC2dFF20iZU4uTXy2VRngfLey3p+6in0TO +jD4cEMJqwgUbjiI8m/hESCketVkq0W0qkkVfWBNzz5qqGHNRbhZBwT7SM0MuXum+ +qEY7n7jcQAk5BDb613liVQjQ0tkCAwEAAaNQME4wHQYDVR0OBBYEFHYjQ0/HJgXd +BnqM4jLPjmygfi8fMB8GA1UdIwQYMBaAFHYjQ0/HJgXdBnqM4jLPjmygfi8fMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABSf++sinLT9dFnC+B6ut5Zp +haTL7PA1/CdmhTdE2vlFPGGw2BD4c/gphBsHKSNHE96irTqFXI/kl6labQpZ5P8G +JORLfaAyl58UT1FayxL4ISzwsp+UrqO60vxkYyLkbEJjuaxIv11oOoFDIp5oBTqe +BVoCfcTjYtTr+IwwlypLPrVTnDNGX5oPIBbTUFvR0t5RaLZgmXLT78ERhWOLINqh +Yi6j7fYaRm/C5IQ8N/TASot7V0SMH2Rt6PrzJb5SLV8r+yozg2BSfU6hZUyKwABR +N3zppKvKzdhlVo9OuSW3x4Tb3V+CVE/8CmTwRfhab9SCmvmaa2FxI+8/2OPVWDU= +-----END CERTIFICATE----- diff --git a/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.key b/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.key new file mode 100644 index 0000000000..eba611823a --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAxeIeoHl1h3EnX5ptIbnmBvc02jd/M1uSOn+0AiXUVR7ILLI/ +/IRGuRSSEWPiCD+rVgdQ79+1zQ90v8kFpUFMqfOzGCnuFj91QSRmpdnrj1fRSskh +F3XfDk3vVws/X4+MKuqiQxVx5TXyQrsLJo6aJMpgWa39FMlAuYVCymYlc1KKrvNS +8CDK+hjlPMmfsy5KhsderXumeWb5ducCAMlS33JHoELZ0UXbSJlTi5NfLZVGeB8t +7Len7qKfRM6MPhwQwmrCBRuOIjyb+ERIKR61WSrRbSqSRV9YE3PPmqoYc1FuFkHB +PtIzQy5e6b6oRjufuNxACTkENvrXeWJVCNDS2QIDAQABAoIBACEyB5VACtlHwCUn +kLshplbwzWr1+F6zM9qgZaAenHoTCd2FoXpI7lxJ+R71tItRsvphi9BRpPvbZehu +XoYUaDnyac7Z6djNmGvvIVEdN4j6YF+9UdHPsjWCGW5uspjjSc5BQisiw9KBtDxB +iGNVdMJLONKSf2wnPrZgho3RiOLJX/poPyGTkMHuhBVvo4oy7Ax3XalaAcufgqwm +YBQJ1Tka+33EUiLkxzJTXxNbIAI2scP8jhGn6mokS0V4gZPxJKUZEyydXRWwi6ex +ua/7q76ELJS5b+xKRYfGsvavFDx8R+LqX8oegALD33ki3rm1MQW7GmikRL98+EVW +Q9mQsqECgYEA/IrP8vycbJOgn1vriNItFcZtczSBlrXCRF0up2cqKMs9c+T5i51x +ZKXK5lo3DfMT+YDM+iiGZ9+vM0UA2VxbFD3XV9mQDBaNC+Duknqxx+OLmWva9YwR +nMaevqVV9LCn+GgUcK+IygEnpzpdP4q8YcXAfGAnZgnihN/AUYAaB70CgYEAyJe4 +yO0S9gAH5aoDdooL0YXrH/Dzd+fAgNsawLhoOltcoZqZFWeAllM0GsrCpfTRltuy +dn9ca3YK0GlWl7h5rDle1HO3nhp1FcpeG1oxmkeQta3PG66uUuMccTAljCLFrEe3 +DguH8+qdjhLk+ZnUB9AVkS79pzdwuEHVljCK600CgYB6mMygkh9B2lzkX9Q0xItc +gcqKXdf3GN9pHq9SVxOxYBDCHUtDirgMeyvHrc4COJneyrc3TcsJzB4aToo9+sbA +SdErdZOnOp9YP+axN1zsw7r2TNSr1UaLjCRuOodC1SuFvMkHdz95iRv946h2+1u+ +PyjVeDxIHc5YYOLU7dI1JQKBgQDF5KDBYNm25brkwcCe3nvgXfzjyyN25KUOupn/ +DS6Oe/m72Lgz3KOIKleaIvS7IvbunJnIu8dioNb0Wye5kJ5A4WyDrhG1IabnM3l6 +BJYw/W9vPSS4y7FhRnuV0wkH4nofh7S5X3jlk02Sj2NkN3Vtq8TLMY++uzwyG4jq +ncM/dQKBgQC+6mA5OfbVN4lRn+zrSiIH5gpvZYPh9wXeTnDWHa13sJsu3e8AQxtk +TfE0W13UV5jhGL8Wvyyxn+doGFTdcZapOlwuoQ6RcgHcVQm2sOl60GAa4idmm0A6 +TcgnIOTyVRlNBoWLCfN83BlGz4gcDpnuZZ/0JuguixgLS323hQlLvg== +-----END RSA PRIVATE KEY----- diff --git a/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl b/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl new file mode 100644 index 0000000000..c880f2d744 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl @@ -0,0 +1,20 @@ +/* + * Sample configuration file for tests + */ + +// Enable UI +ui = true + +// Filesystem storage +storage "file" { + path = "./vault-data" +} + +// TCP Listener using a self-signed certificate +listener "tcp" { + address = "127.0.0.1:8200" + tls_cert_file = "./src/test/vault-config/localhost.cert" + tls_key_file = "./src/test/vault-config/localhost.key" +} + + diff --git a/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt b/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt new file mode 100644 index 0000000000..b965a95321 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt @@ -0,0 +1,82 @@ +== Vault server bootstrap + +1. Run vaul-start in one shell + +2. Open another shell and execute the command below: +> vault operator init + +Vault will output the unseal keys and root token: STORE THEM SAFELY !!! + +Example output: +Unseal Key 1: OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o +Unseal Key 2: iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT +Unseal Key 3: K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF +Unseal Key 4: +5zhysLAO4hIdZs0kiZpkrRovw11uQacfloiBwnZBJA/ +Unseal Key 5: GDwSq18lXV3Cw4MoHsKIH137kuI0mdl36UiD9WxOdulc + +Initial Root Token: d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 + +... + +== Admin token setup + +1. Set the VAULT_TOKEN environment variable with the root token value +export VAULT_TOKEN=d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 (Linux) +set VAULT_TOKEN=d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 (Windows) + +2. Create another admin token + +>vault token create -display-name=admin +Key Value +--- ----- +token 3779c3ca-9f5e-1d8f-3842-efa96d88de43 <=== this is the new root token +token_accessor 2dfa4031-973b-cf88-c749-ee6f520ecaea +token_duration ∞ +token_renewable false +token_policies ["root"] +identity_policies [] +policies ["root"] + +3. Create ~/.vault-secret with your root token +4. Unset the VAULT_TOKEN environment variable ! + +=== Test DB setup (MySQL only, for now) + +1. Create test db +2. Create admin account used to create dynamic accounts: + +create schema fakebank; +create user 'fakebank-admin'@'%' identified by 'Sup&rSecre7!' +grant all privileges on fakebank.* to 'fakebank-admin'@'%' with grant option; +grant create user on *.* to 'fakebank-admin' with grant option; +flush privileges; + + +=== Database secret backend setup +> vault secrets enable database + +==== Create db configuration +> vault write database/config/mysql-fakebank ^ + plugin_name=mysql-legacy-database-plugin ^ + connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/fakebank" ^ + allowed_roles="*" ^ + username="fakebank-admin" ^ + password="Sup&rSecre7!" + +==== Create roles +> vault write database/roles/fakebank-accounts-ro ^ + db_name=mysql-fakebank ^ + creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON fakebank.* TO '{{name}}'@'%';" ^ + default_ttl="1h" ^ + max_ttl="24h" + +> vault write database/roles/fakebank-accounts-rw ^ + db_name=mysql-fakebank ^ + creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT,INSERT,UPDATE ON fakebank.* TO '{{name}}'@'%';" ^ + default_ttl="1m" ^ + max_ttl="2m" + +=== Get credentials +> vault read database/creds/fakebank-accounts-rw + + diff --git a/spring-cloud/spring-cloud-vault/vault-env.bat b/spring-cloud/spring-cloud-vault/vault-env.bat new file mode 100644 index 0000000000..d7aa5da215 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-env.bat @@ -0,0 +1,5 @@ +@echo off +echo Setting environment variables to access local vault.. +set VAULT_ADDR=https://localhost:8200 +set VAULT_CACERT=%~dp0%/src/test/vault-config/localhost.cert +rem set VAULT_TLS_SERVER_NAME=localhost diff --git a/spring-cloud/spring-cloud-vault/vault-env.sh b/spring-cloud/spring-cloud-vault/vault-env.sh new file mode 100644 index 0000000000..06077cee2e --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-env.sh @@ -0,0 +1,6 @@ +#!/bin/bash +echo Setting environment variables to access local vault.. +SCRIPTPATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd ) +export VAULT_ADDR=https://localhost:8200 +export VAULT_CACERT=$SCRIPTPATH/src/test/vault-config/localhost.cert +export VAULT_TLS_SERVER_NAME=localhost diff --git a/spring-cloud/spring-cloud-vault/vault-start.bat b/spring-cloud/spring-cloud-vault/vault-start.bat new file mode 100644 index 0000000000..e8f6ce4c9f --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-start.bat @@ -0,0 +1,3 @@ +echo Starting vault server... +pushd %~dp0% +vault server -config %~dp0%/src/test/vault-config/vault-test.hcl diff --git a/spring-cloud/spring-cloud-vault/vault-start.sh b/spring-cloud/spring-cloud-vault/vault-start.sh new file mode 100644 index 0000000000..d5af7cfee6 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-start.sh @@ -0,0 +1,5 @@ +#!/bin/bash +SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" +pushd $SCRIPTPATH +echo Starting vault server... +vault server -config $SCRIPTPATH/src/test/vault-config/vault-test.hcl diff --git a/spring-cloud/spring-cloud-vault/vault-unseal.bat b/spring-cloud/spring-cloud-vault/vault-unseal.bat new file mode 100644 index 0000000000..8133f90892 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-unseal.bat @@ -0,0 +1,7 @@ + +call %~dp0%/vault-env.bat + +vault operator unseal OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o +vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT +vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT +vault operator unseal K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF diff --git a/spring-cloud/spring-cloud-vault/vault-unseal.sh b/spring-cloud/spring-cloud-vault/vault-unseal.sh new file mode 100644 index 0000000000..699b383801 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-unseal.sh @@ -0,0 +1,8 @@ +#!/bin/bash +SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" +. $SCRIPTPATH/vault-env.sh + +# Please replace the unseal keys below for your own +vault operator unseal OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o +vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT +vault operator unseal K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF diff --git a/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml b/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml index e7fa972f07..9243766b77 100644 --- a/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml +++ b/spring-cloud/spring-cloud-zookeeper/Greeting/pom.xml @@ -1,7 +1,10 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + Greeting + jar + Greeting com.baeldung.spring.cloud @@ -9,24 +12,21 @@ 1.0.0-SNAPSHOT - Greeting - jar - org.springframework.boot spring-boot-starter - 1.5.2.RELEASE + ${spring-boot.version} org.springframework spring-web - 4.3.7.RELEASE + ${springframework.version} org.springframework.cloud spring-cloud-starter-zookeeper-discovery - 1.0.3.RELEASE + ${spring-cloud-starter-zookeeper-discovery.version} commons-logging @@ -37,17 +37,17 @@ org.springframework.boot spring-boot-starter-actuator - 1.5.2.RELEASE + ${spring-boot.version} org.springframework.cloud spring-cloud-starter-feign - 1.2.5.RELEASE + ${spring-cloud-starter-feign.version} org.hamcrest hamcrest-core - 1.3 + ${hamcrest.version} test @@ -57,13 +57,16 @@ org.springframework.cloud spring-cloud-dependencies - Brixton.SR7 + ${spring-cloud-dependencies.version} pom import - Greeting + + 1.2.5.RELEASE + 1.3 + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zookeeper/Greeting/src/main/resources/logback.xml b/spring-cloud/spring-cloud-zookeeper/Greeting/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-zookeeper/Greeting/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zookeeper/Greeting/src/test/baeldung/SpringContextIntegrationTest.java b/spring-cloud/spring-cloud-zookeeper/Greeting/src/test/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..0f544b3ed1 --- /dev/null +++ b/spring-cloud/spring-cloud-zookeeper/Greeting/src/test/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.cloud.ribbon.client.ServerLocationApp; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = GreetingApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-zookeeper/HelloWorld/pom.xml b/spring-cloud/spring-cloud-zookeeper/HelloWorld/pom.xml index a5b7776438..262b059544 100644 --- a/spring-cloud/spring-cloud-zookeeper/HelloWorld/pom.xml +++ b/spring-cloud/spring-cloud-zookeeper/HelloWorld/pom.xml @@ -1,29 +1,32 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + HelloWorld + jar + HelloWorld + com.baeldung.spring.cloud spring-cloud-zookeeper 1.0.0-SNAPSHOT - HelloWorld - jar + org.springframework.boot spring-boot-starter - 1.5.2.RELEASE + ${spring-boot.version} org.springframework spring-web - 4.3.7.RELEASE + ${springframework.version} org.springframework.cloud spring-cloud-starter-zookeeper-discovery - 1.0.3.RELEASE + ${spring-cloud-starter-zookeeper-discovery.version} commons-logging @@ -38,7 +41,7 @@ org.springframework.cloud spring-cloud-dependencies - Brixton.SR7 + ${spring-cloud-dependencies.version} pom import @@ -53,5 +56,5 @@ - HelloWorld + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zookeeper/HelloWorld/src/main/resources/logback.xml b/spring-cloud/spring-cloud-zookeeper/HelloWorld/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-zookeeper/HelloWorld/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zookeeper/pom.xml b/spring-cloud/spring-cloud-zookeeper/pom.xml index 091b8c4987..4535c2072d 100644 --- a/spring-cloud/spring-cloud-zookeeper/pom.xml +++ b/spring-cloud/spring-cloud-zookeeper/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-cloud-zookeeper pom @@ -16,4 +16,10 @@ HelloWorld + + 1.5.2.RELEASE + 4.3.7.RELEASE + 1.0.3.RELEASE + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/bin/eureka-client/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/bin/eureka-client/pom.xml index 876279262c..6a00b279c8 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/bin/eureka-client/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/bin/eureka-client/pom.xml @@ -1,9 +1,7 @@ - + 4.0.0 - eureka-client 1.0.0-SNAPSHOT jar @@ -42,9 +40,4 @@ - - Brixton.SR7 - 1.2.3.RELEASE - 1.4.2.RELEASE - diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/bin/eureka-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/bin/eureka-server/pom.xml index 8bf8a0da46..9db3204f64 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/bin/eureka-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/bin/eureka-server/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 eureka-server @@ -42,8 +41,5 @@ - - Brixton.SR7 - 1.2.3.RELEASE - + diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/bin/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/bin/pom.xml index b8e3c867e3..7e864499d4 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/bin/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/bin/pom.xml @@ -1,15 +1,12 @@ - + 4.0.0 - + com.baeldung.spring.cloud spring-cloud-zuul-eureka-integration 1.0.0-SNAPSHOT - pom - Spring Cloud Zuul and Eureka Integration Spring Cloud Zuul and Eureka Integration diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml index 3d1bd412c0..9c27affb8b 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 eureka-client 1.0.0-SNAPSHOT @@ -40,9 +39,4 @@ - - Brixton.SR7 - 1.2.3.RELEASE - 1.4.2.RELEASE - diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/resources/logback.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml index 902232c843..d694c9058b 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 eureka-server 1.0.0-SNAPSHOT @@ -41,8 +40,4 @@ - - Brixton.SR7 - 1.2.3.RELEASE - diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/src/main/resources/logback.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/eureka-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/pom.xml index ef16a6a885..f4166c7d34 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/pom.xml @@ -24,8 +24,6 @@ - UTF-8 - 3.7.0 1.4.2.RELEASE 1.10 1.2.10 diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml index 19cb2ea5b8..103b8334d3 100644 --- a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/pom.xml @@ -1,12 +1,14 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + zuul-server + com.baeldung.spring.cloud spring-cloud-zuul-eureka-integration 1.0.0-SNAPSHOT - zuul-server + org.springframework.boot @@ -35,6 +37,7 @@ spring-boot-starter-security + @@ -46,4 +49,5 @@ + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/src/main/resources/logback.xml b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cloud/spring-cloud-zuul-eureka-integration/zuul-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-core/README.md b/spring-core/README.md index 3684c7f6e9..e5c359c11b 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -16,3 +16,9 @@ - [@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) +- [Access a File from the Classpath in a Spring Application](http://www.baeldung.com/spring-classpath-file-access) +- [Controlling Bean Creation Order with @DependsOn Annotation](http://www.baeldung.com/spring-depends-on) +- [Spring Autowiring of Generic Types](https://www.baeldung.com/spring-autowire-generics) +- [Spring Application Context Events](https://www.baeldung.com/spring-context-events) +- [Unsatisfied Dependency in Spring](https://www.baeldung.com/spring-unsatisfied-dependency) +- [What is a Spring Bean?](https://www.baeldung.com/spring-bean) diff --git a/spring-core/pom.xml b/spring-core/pom.xml index 032f2214d2..60f3262f08 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -1,103 +1,90 @@ - + - 4.0.0 - com.baeldung - spring-core - 0.0.1-SNAPSHOT - war - spring-core + 4.0.0 + com.baeldung + spring-core + 0.0.1-SNAPSHOT + war + spring-core - - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + - - - org.mockito - mockito-all - ${mockito.version} - - - org.springframework - spring-test - ${spring.version} - - - org.springframework - spring-beans - ${spring.version} - - - org.springframework - spring-context - ${spring.version} - - - javax.inject - javax.inject - ${javax.inject.version} - - - com.google.guava - guava - ${guava.version} - - - org.projectlombok - lombok - ${lombok.version} - - - org.springframework.boot - spring-boot-starter - 1.5.2.RELEASE - - - org.springframework.boot - spring-boot-test - ${mockito.spring.boot.version} - test - - - commons-io - commons-io - ${commons.io.version} - - + + + org.springframework + spring-test + ${spring.version} + + + org.springframework + spring-beans + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + javax.inject + javax.inject + ${javax.inject.version} + + + com.google.guava + guava + ${guava.version} + + + org.projectlombok + lombok + ${lombok.version} + + + org.springframework.boot + spring-boot-starter + ${spring-boot.version} + + + org.springframework.boot + spring-boot-test + ${mockito.spring.boot.version} + test + + + commons-io + commons-io + ${commons.io.version} + + - - - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - false - - - - + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + false + + + + - - 1.10.19 - 1.4.4.RELEASE - 1 - 20.0 - 2.6 - 1.16.12 - 2.5 - - - - - java.net - https://maven.java.net/content/repositories/releases/ - - + + 1.4.4.RELEASE + 1 + 20.0 + 2.6 + 1.16.12 + 2.5 + 1.5.2.RELEASE + \ No newline at end of file diff --git a/spring-core/src/main/java/com/baeldung/config/scope/AppConfigFunctionBean.java b/spring-core/src/main/java/com/baeldung/config/scope/AppConfigFunctionBean.java new file mode 100644 index 0000000000..a3c5445698 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/config/scope/AppConfigFunctionBean.java @@ -0,0 +1,31 @@ +package com.baeldung.config.scope; + +import java.util.function.Function; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +import com.baeldung.scope.prototype.PrototypeBean; +import com.baeldung.scope.singletone.SingletonFunctionBean; + +@Configuration +public class AppConfigFunctionBean { + + @Bean + public Function beanFactory() { + return name -> prototypeBeanWithParam(name); + } + + @Bean + @Scope(value = "prototype") + public PrototypeBean prototypeBeanWithParam(String name) { + return new PrototypeBean(name); + } + + @Bean + public SingletonFunctionBean singletonFunctionBean() { + return new SingletonFunctionBean(); + } + +} diff --git a/spring-core/src/main/java/com/baeldung/definition/Config.java b/spring-core/src/main/java/com/baeldung/definition/Config.java new file mode 100644 index 0000000000..126e6259ca --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/definition/Config.java @@ -0,0 +1,16 @@ +package com.baeldung.definition; + +import com.baeldung.definition.domain.Address; +import com.baeldung.definition.domain.Company; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackageClasses = Company.class) +public class Config { + @Bean + public Address getAddress() { + return new Address("High Street", 1000); + } +} diff --git a/spring-core/src/main/java/com/baeldung/definition/domain/Address.java b/spring-core/src/main/java/com/baeldung/definition/domain/Address.java new file mode 100644 index 0000000000..91be18398e --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/definition/domain/Address.java @@ -0,0 +1,14 @@ +package com.baeldung.definition.domain; + +import lombok.Data; + +@Data +public class Address { + private String street; + private int number; + + public Address(String street, int number) { + this.street = street; + this.number = number; + } +} diff --git a/spring-core/src/main/java/com/baeldung/definition/domain/Company.java b/spring-core/src/main/java/com/baeldung/definition/domain/Company.java new file mode 100644 index 0000000000..eabde8afdf --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/definition/domain/Company.java @@ -0,0 +1,14 @@ +package com.baeldung.definition.domain; + +import lombok.Data; +import org.springframework.stereotype.Component; + +@Data +@Component +public class Company { + private Address address; + + public Company(Address address) { + this.address = address; + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/app/PurchaseDeptService.java b/spring-core/src/main/java/com/baeldung/dependency/exception/app/PurchaseDeptService.java new file mode 100644 index 0000000000..e0fe01acdd --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/app/PurchaseDeptService.java @@ -0,0 +1,14 @@ +package com.baeldung.dependency.exception.app; + +import com.baeldung.dependency.exception.repository.InventoryRepository; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +public class PurchaseDeptService { + private InventoryRepository repository; + + public PurchaseDeptService(@Qualifier("dresses") InventoryRepository repository) { + this.repository = repository; + } +} \ No newline at end of file diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/app/SpringDependenciesExampleApplication.java b/spring-core/src/main/java/com/baeldung/dependency/exception/app/SpringDependenciesExampleApplication.java new file mode 100644 index 0000000000..e45438a9fe --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/app/SpringDependenciesExampleApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.dependency.exception.app; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = "com.baeldung.dependency.exception") +public class SpringDependenciesExampleApplication { + public static void main(String[] args) { + SpringApplication.run(SpringDependenciesExampleApplication.class, args); + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/repository/DressRepository.java b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/DressRepository.java new file mode 100644 index 0000000000..5a1371ce04 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/DressRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.dependency.exception.repository; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Repository; + +@Qualifier("dresses") +@Repository +public class DressRepository implements InventoryRepository { +} diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/repository/InventoryRepository.java b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/InventoryRepository.java new file mode 100644 index 0000000000..ccb2ad9c32 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/InventoryRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.dependency.exception.repository; + +import org.springframework.stereotype.Repository; + +@Repository +public interface InventoryRepository { +} diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/repository/ShoeRepository.java b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/ShoeRepository.java new file mode 100644 index 0000000000..227d8934b6 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/ShoeRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.dependency.exception.repository; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Repository; + +@Qualifier("shoes") +@Repository +public class ShoeRepository implements InventoryRepository { +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/annotation/CarQualifier.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/annotation/CarQualifier.java new file mode 100644 index 0000000000..cd7f81c0fb --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/annotation/CarQualifier.java @@ -0,0 +1,15 @@ +package com.baeldung.dependencyinjectiontypes.annotation; + +import org.springframework.beans.factory.annotation.Qualifier; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.FIELD, ElementType.METHOD, + ElementType.TYPE, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Qualifier +public @interface CarQualifier { +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/app/CustomConfiguration.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/app/CustomConfiguration.java new file mode 100644 index 0000000000..841a8d4656 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/app/CustomConfiguration.java @@ -0,0 +1,39 @@ +package com.baeldung.dependencyinjectiontypes.app; + +import com.baeldung.dependencyinjectiontypes.annotation.CarQualifier; +import com.baeldung.dependencyinjectiontypes.model.Car; +import com.baeldung.dependencyinjectiontypes.model.CarHandler; +import com.baeldung.dependencyinjectiontypes.model.Motorcycle; +import com.baeldung.dependencyinjectiontypes.model.Vehicle; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan("com.baeldung.dependencyinjectiontypes.model") +public class CustomConfiguration { + @Bean + @CarQualifier + public Car getMercedes() { + return new Car("E280", "Mercedes", "Diesel"); + } + + public static void main(String[] args) throws NoSuchFieldException { + ConfigurableApplicationContext context = SpringApplication.run(CustomConfiguration.class, args); + CarHandler carHandler = context.getBean(CarHandler.class); + carHandler.getVehicles().forEach(System.out::println); + } + + @Bean + @CarQualifier + public Car getBmw() { + return new Car("M5", "BMW", "Petrol"); + } + + @Bean + public Motorcycle getSuzuki() { + return new Motorcycle("Yamaguchi", "Suzuki", true); + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Car.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Car.java new file mode 100644 index 0000000000..a09d89248b --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Car.java @@ -0,0 +1,25 @@ +package com.baeldung.dependencyinjectiontypes.model; + +public class Car extends Vehicle { + private String engineType; + + public Car(String name, String manufacturer, String engineType) { + super(name, manufacturer); + this.engineType = engineType; + } + + public String getEngineType() { + return engineType; + } + + public void setEngineType(String engineType) { + this.engineType = engineType; + } + + @Override + public String toString() { + return "Car{" + + "engineType='" + engineType + '\'' + + '}'; + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/CarHandler.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/CarHandler.java new file mode 100644 index 0000000000..f5d581ef0a --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/CarHandler.java @@ -0,0 +1,26 @@ +package com.baeldung.dependencyinjectiontypes.model; + +import com.baeldung.dependencyinjectiontypes.annotation.CarQualifier; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.ResolvableType; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class CarHandler { + + @Autowired + @CarQualifier + private List vehicles; + + public List getVehicles() throws NoSuchFieldException { + ResolvableType vehiclesType = ResolvableType.forField(getClass().getDeclaredField("vehicles")); + System.out.println(vehiclesType); + ResolvableType type = vehiclesType.getGeneric(); + System.out.println(type); + Class aClass = type.resolve(); + System.out.println(aClass); + return this.vehicles; + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Motorcycle.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Motorcycle.java new file mode 100644 index 0000000000..ce5e97fb6d --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Motorcycle.java @@ -0,0 +1,25 @@ +package com.baeldung.dependencyinjectiontypes.model; + +public class Motorcycle extends Vehicle { + private boolean twoWheeler; + + public Motorcycle(String name, String manufacturer, boolean twoWheeler) { + super(name, manufacturer); + this.twoWheeler = true; + } + + public boolean isTwoWheeler() { + return twoWheeler; + } + + public void setTwoWheeler(boolean twoWheeler) { + this.twoWheeler = twoWheeler; + } + + @Override + public String toString() { + return "Motorcycle{" + + "twoWheeler=" + twoWheeler + + '}'; + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Vehicle.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Vehicle.java new file mode 100644 index 0000000000..cb3dca764e --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/model/Vehicle.java @@ -0,0 +1,28 @@ +package com.baeldung.dependencyinjectiontypes.model; + +public abstract class Vehicle { + private String name; + private String manufacturer; + + + public Vehicle(String name, String manufacturer) { + this.name = name; + this.manufacturer = manufacturer; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getManufacturer() { + return manufacturer; + } + + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } +} \ No newline at end of file diff --git a/spring-core/src/main/java/com/baeldung/event/listener/ContextEventListener.java b/spring-core/src/main/java/com/baeldung/event/listener/ContextEventListener.java new file mode 100644 index 0000000000..a2603bb95c --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/event/listener/ContextEventListener.java @@ -0,0 +1,24 @@ +package com.baeldung.event.listener; + +import org.springframework.context.event.ContextStartedEvent; +import org.springframework.context.event.ContextStoppedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +@Component +public class ContextEventListener { + + @Order(2) + @EventListener + public void handleContextRefreshEvent(ContextStartedEvent ctxStartEvt) { + System.out.println("Context Start Event received."); + } + + @Order(1) + @EventListener(classes = { ContextStartedEvent.class, ContextStoppedEvent.class }) + public void handleMultipleEvents() { + System.out.println("Multi-event listener invoked"); + } + +} diff --git a/spring-core/src/main/java/com/baeldung/event/listener/EventConfig.java b/spring-core/src/main/java/com/baeldung/event/listener/EventConfig.java new file mode 100644 index 0000000000..f2a3af7640 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/event/listener/EventConfig.java @@ -0,0 +1,10 @@ +package com.baeldung.event.listener; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = "com.baeldung.event.listener") +public class EventConfig { + +} diff --git a/spring-core/src/main/java/com/baeldung/event/listener/SpringRunner.java b/spring-core/src/main/java/com/baeldung/event/listener/SpringRunner.java new file mode 100644 index 0000000000..bbe4693900 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/event/listener/SpringRunner.java @@ -0,0 +1,12 @@ +package com.baeldung.event.listener; + +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class SpringRunner { + + public static void main(String[] args) { + ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(EventConfig.class); + ctx.start(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/AppConfig.java b/spring-core/src/main/java/com/baeldung/scope/AppConfig.java index 5c8c539e7a..33a9c5c21e 100644 --- a/spring-core/src/main/java/com/baeldung/scope/AppConfig.java +++ b/spring-core/src/main/java/com/baeldung/scope/AppConfig.java @@ -40,4 +40,5 @@ public class AppConfig { public SingletonObjectFactoryBean singletonObjectFactoryBean() { return new SingletonObjectFactoryBean(); } + } diff --git a/spring-core/src/main/java/com/baeldung/scope/AppProxyScopeConfig.java b/spring-core/src/main/java/com/baeldung/scope/AppProxyScopeConfig.java index fc7a30471c..9f1874375e 100644 --- a/spring-core/src/main/java/com/baeldung/scope/AppProxyScopeConfig.java +++ b/spring-core/src/main/java/com/baeldung/scope/AppProxyScopeConfig.java @@ -2,6 +2,7 @@ package com.baeldung.scope; import com.baeldung.scope.prototype.PrototypeBean; import com.baeldung.scope.singletone.SingletonBean; + import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.*; @@ -19,4 +20,5 @@ public class AppProxyScopeConfig { public SingletonBean singletonBean() { return new SingletonBean(); } + } diff --git a/spring-core/src/main/java/com/baeldung/scope/prototype/PrototypeBean.java b/spring-core/src/main/java/com/baeldung/scope/prototype/PrototypeBean.java index cfccb62e45..c87c7a8d44 100644 --- a/spring-core/src/main/java/com/baeldung/scope/prototype/PrototypeBean.java +++ b/spring-core/src/main/java/com/baeldung/scope/prototype/PrototypeBean.java @@ -9,4 +9,20 @@ public class PrototypeBean { public PrototypeBean() { logger.info("Prototype instance created"); } + + private String name; + + public PrototypeBean(String name) { + this.name = name; + logger.info("Prototype instance " + name + " created"); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } diff --git a/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonFunctionBean.java b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonFunctionBean.java new file mode 100644 index 0000000000..8cdc56a6fa --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonFunctionBean.java @@ -0,0 +1,19 @@ +package com.baeldung.scope.singletone; + +import java.util.function.Function; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.baeldung.scope.prototype.PrototypeBean; + +public class SingletonFunctionBean { + + @Autowired + private Function beanFactory; + + public PrototypeBean getPrototypeInstance(String name) { + PrototypeBean bean = beanFactory.apply(name); + return bean; + } + +} diff --git a/spring-core/src/main/resources/logback.xml b/spring-core/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-core/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/test/java/com/baeldung/definition/SpringBeanIntegrationTest.java b/spring-core/src/test/java/com/baeldung/definition/SpringBeanIntegrationTest.java new file mode 100644 index 0000000000..0057611308 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/definition/SpringBeanIntegrationTest.java @@ -0,0 +1,18 @@ +package com.baeldung.definition; + +import com.baeldung.definition.domain.Company; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.Assert.assertEquals; + +public class SpringBeanIntegrationTest { + @Test + public void whenUsingIoC_thenDependenciesAreInjected() { + ApplicationContext context = new AnnotationConfigApplicationContext(Config.class); + Company company = context.getBean("company", Company.class); + assertEquals("High Street", company.getAddress().getStreet()); + assertEquals(1000, company.getAddress().getNumber()); + } +} 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 index 11d9daf3bf..5de53192df 100644 --- a/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java +++ b/spring-core/src/test/java/com/baeldung/dependson/processor/FileProcessorIntegrationTest.java @@ -5,7 +5,6 @@ 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; @@ -30,7 +29,7 @@ public class FileProcessorIntegrationTest { assertTrue(file.getText().endsWith("processed")); } - @Test(expected=NoSuchBeanDefinitionException.class) + @Test(expected=BeanCreationException.class) public void whenDependentBeanNotAvailable_ThrowsNoSuchBeanDefinitionException(){ context.getBean("dummyFileProcessor"); } diff --git a/spring-core/src/test/java/com/baeldung/scope/PrototypeBeanInjectionIntegrationTest.java b/spring-core/src/test/java/com/baeldung/scope/PrototypeBeanInjectionIntegrationTest.java index 1c05bb3e8e..d0c2733765 100644 --- a/spring-core/src/test/java/com/baeldung/scope/PrototypeBeanInjectionIntegrationTest.java +++ b/spring-core/src/test/java/com/baeldung/scope/PrototypeBeanInjectionIntegrationTest.java @@ -1,6 +1,7 @@ package com.baeldung.scope; import com.baeldung.scope.prototype.PrototypeBean; +import com.baeldung.scope.singletone.SingletonFunctionBean; import com.baeldung.scope.singletone.SingletonLookupBean; import com.baeldung.scope.singletone.SingletonObjectFactoryBean; import com.baeldung.scope.singletone.SingletonProviderBean; @@ -58,4 +59,5 @@ public class PrototypeBeanInjectionIntegrationTest { Assert.assertTrue("New instance expected", firstInstance != secondInstance); } + } diff --git a/spring-core/src/test/java/com/baeldung/scope/PrototypeFunctionBeanIntegrationTest.java b/spring-core/src/test/java/com/baeldung/scope/PrototypeFunctionBeanIntegrationTest.java new file mode 100644 index 0000000000..1e3c652599 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/scope/PrototypeFunctionBeanIntegrationTest.java @@ -0,0 +1,34 @@ +package com.baeldung.scope; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.config.scope.AppConfigFunctionBean; +import com.baeldung.scope.prototype.PrototypeBean; +import com.baeldung.scope.singletone.SingletonFunctionBean; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = AppConfigFunctionBean.class) +public class PrototypeFunctionBeanIntegrationTest { + + @Test + public void givenPrototypeInjection_WhenFunction_ThenNewInstanceReturn() { + + AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfigFunctionBean.class); + + SingletonFunctionBean firstContext = context.getBean(SingletonFunctionBean.class); + SingletonFunctionBean secondContext = context.getBean(SingletonFunctionBean.class); + + PrototypeBean firstInstance = firstContext.getPrototypeInstance("instance1"); + PrototypeBean secondInstance = secondContext.getPrototypeInstance("instance2"); + + Assert.assertTrue("New instance expected", firstInstance != secondInstance); + } + +} diff --git a/spring-cucumber/pom.xml b/spring-cucumber/pom.xml index 1da4c8a124..64b543bb6c 100644 --- a/spring-cucumber/pom.xml +++ b/spring-cucumber/pom.xml @@ -1,6 +1,6 @@ + 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 spring-cucumber diff --git a/spring-cucumber/src/main/resources/logback.xml b/spring-cucumber/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-cucumber/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java index 56eb810c09..f48ab410ca 100644 --- a/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java +++ b/spring-cucumber/src/test/java/com/baeldung/CucumberIntegrationTest.java @@ -1,10 +1,11 @@ package com.baeldung; +import org.junit.runner.RunWith; + import cucumber.api.CucumberOptions; import cucumber.api.junit.Cucumber; -import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions(features = "src/test/resources") -public class CucumberIntegrationTest { +public class CucumberIntegrationTest extends SpringIntegrationTest{ } \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java index f4d47d7871..8655a02469 100644 --- a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java +++ b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java @@ -5,16 +5,17 @@ import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpResponse; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestTemplate; //@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = SpringDemoApplication.class) -@WebAppConfiguration +@SpringBootTest(classes = SpringDemoApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) +@ContextConfiguration public class SpringIntegrationTest { static ResponseResults latestResponse = null; diff --git a/spring-cucumber/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-cucumber/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..80efd86f13 --- /dev/null +++ b/spring-cucumber/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.SpringDemoApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringDemoApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-custom-aop/pom.xml b/spring-custom-aop/pom.xml index 4e95d175e7..f0b1dbb5ac 100644 --- a/spring-custom-aop/pom.xml +++ b/spring-custom-aop/pom.xml @@ -1,5 +1,5 @@ + 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 spring-custom-aop @@ -101,7 +101,7 @@ com.google.guava guava - 18.0 + ${guava.version} @@ -148,6 +148,8 @@ 3.3.7-1 3.1.7 8.5.11 + 18.0 + 8.0.43 diff --git a/spring-custom-aop/src/main/resources/logback.xml b/spring-custom-aop/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-custom-aop/src/main/resources/logback.xml +++ b/spring-custom-aop/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-custom-aop/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..0384c67e26 --- /dev/null +++ b/spring-custom-aop/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,25 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.annotation.servletcomponentscan.SpringBootAnnotatedApp; +import com.baeldung.annotation.servletcomponentscan.SpringBootPlainApp; +import com.baeldung.git.CommitIdApplication; +import com.baeldung.internationalization.InternationalizationApp; +import com.baeldung.intro.App; +import com.baeldung.servlets.ApplicationMain; +import com.baeldung.webjar.WebjarsdemoApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { SpringBootAnnotatedApp.class, SpringBootPlainApp.class, CommitIdApplication.class, + InternationalizationApp.class, App.class, ApplicationMain.class, Application.class, + WebjarsdemoApplication.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-data-couchbase-2/pom.xml b/spring-data-couchbase-2/pom.xml index 10afff76e7..6c7d7a9d11 100644 --- a/spring-data-couchbase-2/pom.xml +++ b/spring-data-couchbase-2/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung spring-data-couchbase-2 @@ -61,9 +61,7 @@ - 1.8 - UTF-8 - 4.3.4.RELEASE + 4.3.4.RELEASE 2.1.5.RELEASE 5.3.3.Final 2.9.6 diff --git a/spring-data-couchbase-2/src/main/resources/logback.xml b/spring-data-couchbase-2/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-data-couchbase-2/src/main/resources/logback.xml +++ b/spring-data-couchbase-2/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-data-couchbase-2/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-data-couchbase-2/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..9c9d58dd0b --- /dev/null +++ b/spring-data-couchbase-2/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import org.baeldung.spring.data.couchbase2b.MultiBucketCouchbaseConfig; +import org.baeldung.spring.data.couchbase2b.MultiBucketIntegrationTestConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { MultiBucketCouchbaseConfig.class, MultiBucketIntegrationTestConfig.class }) +@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-data-couchbase-2/src/test/resources/logback.xml b/spring-data-couchbase-2/src/test/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-data-couchbase-2/src/test/resources/logback.xml +++ b/spring-data-couchbase-2/src/test/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-data-elasticsearch/pom.xml b/spring-data-elasticsearch/pom.xml index 386bd54ee8..99d8a70807 100644 --- a/spring-data-elasticsearch/pom.xml +++ b/spring-data-elasticsearch/pom.xml @@ -1,5 +1,5 @@ + 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 spring-data-elasticsearch @@ -9,9 +9,9 @@ com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 @@ -19,50 +19,20 @@ org.springframework spring-core ${spring.version} - - - commons-logging - commons-logging - - + + + org.springframework + spring-context + ${spring.version} + + org.springframework.data spring-data-elasticsearch ${spring-data-elasticsearch.version} - - com.spatial4j - spatial4j - ${spatial4j.version} - - - - com.vividsolutions - jts - ${jts.version} - - - xerces - xercesImpl - - - - - - org.springframework - spring-test - ${spring.version} - test - - - net.java.dev.jna - jna - ${jna.version} - test - - org.elasticsearch elasticsearch @@ -73,19 +43,62 @@ fastjson ${fastjson.version} + + + org.locationtech.spatial4j + spatial4j + ${spatial4j.version} + + + + com.vividsolutions + jts + ${jts.version} + + + xerces + xercesImpl + + + + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + + org.elasticsearch.client + transport + ${elasticsearch.version} + + + + org.springframework + spring-test + ${spring.version} + test + + + + net.java.dev.jna + jna + ${jna.version} + test + - - UTF-8 1.8 1.8 - 2.0.5.RELEASE - 4.2.2 - 2.4.2 - 1.2.21 - 0.4.1 + 3.0.8.RELEASE + 4.5.2 + 5.6.0 + 1.2.47 + 0.6 1.13 + 2.9.1 \ No newline at end of file diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/config/Config.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/config/Config.java index 37e9fd46eb..e6ce795b45 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/config/Config.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/config/Config.java @@ -1,15 +1,13 @@ package com.baeldung.spring.data.es.config; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.net.InetAddress; +import java.net.UnknownHostException; import org.elasticsearch.client.Client; +import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.node.NodeBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.elasticsearch.common.transport.InetSocketTransportAddress; +import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -23,35 +21,26 @@ import org.springframework.data.elasticsearch.repository.config.EnableElasticsea @ComponentScan(basePackages = { "com.baeldung.spring.data.es.service" }) public class Config { - @Value("${elasticsearch.home:/usr/local/Cellar/elasticsearch/2.3.2}") + @Value("${elasticsearch.home:/usr/local/Cellar/elasticsearch/5.6.0}") private String elasticsearchHome; - private static Logger logger = LoggerFactory.getLogger(Config.class); + @Value("${elasticsearch.cluster.name:elasticsearch}") + private String clusterName; @Bean public Client client() { + TransportClient client = null; try { - final Path tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")), "elasticsearch_data"); - logger.debug(tmpDir.toAbsolutePath().toString()); - - // @formatter:off - - final Settings.Builder elasticsearchSettings = - Settings.settingsBuilder().put("http.enabled", "false") - .put("path.data", tmpDir.toAbsolutePath().toString()) - .put("path.home", elasticsearchHome); - - return new NodeBuilder() - .local(true) - .settings(elasticsearchSettings) - .node() - .client(); - - // @formatter:on - } catch (final IOException ioex) { - logger.error("Cannot create temp dir", ioex); - throw new RuntimeException(); + final Settings elasticsearchSettings = Settings.builder() + .put("client.transport.sniff", true) + .put("path.home", elasticsearchHome) + .put("cluster.name", clusterName).build(); + client = new PreBuiltTransportClient(elasticsearchSettings); + client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); + } catch (UnknownHostException e) { + e.printStackTrace(); } + return client; } @Bean diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Article.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Article.java index 01330a6c9c..e901d0d0ed 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Article.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/model/Article.java @@ -1,8 +1,8 @@ package com.baeldung.spring.data.es.model; -import static org.springframework.data.elasticsearch.annotations.FieldIndex.not_analyzed; +import static org.springframework.data.elasticsearch.annotations.FieldType.Keyword; import static org.springframework.data.elasticsearch.annotations.FieldType.Nested; -import static org.springframework.data.elasticsearch.annotations.FieldType.String; +import static org.springframework.data.elasticsearch.annotations.FieldType.Text; import java.util.Arrays; import java.util.List; @@ -19,13 +19,13 @@ public class Article { @Id private String id; - @MultiField(mainField = @Field(type = String), otherFields = { @InnerField(index = not_analyzed, suffix = "verbatim", type = String) }) + @MultiField(mainField = @Field(type = Text, fielddata = true), otherFields = { @InnerField(suffix = "verbatim", type = Keyword) }) private String title; - @Field(type = Nested) + @Field(type = Nested, includeInParent = true) private List authors; - @Field(type = String, index = not_analyzed) + @Field(type = Keyword) private String[] tags; public Article() { diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleService.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleService.java index 63e2d91fa7..a0f72aa5f7 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleService.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleService.java @@ -1,5 +1,7 @@ package com.baeldung.spring.data.es.service; +import java.util.Optional; + import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -8,7 +10,7 @@ import com.baeldung.spring.data.es.model.Article; public interface ArticleService { Article save(Article article); - Article findOne(String id); + Optional
    findOne(String id); Iterable
    findAll(); diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleServiceImpl.java b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleServiceImpl.java index 0908ffa70e..5064f16508 100644 --- a/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleServiceImpl.java +++ b/spring-data-elasticsearch/src/main/java/com/baeldung/spring/data/es/service/ArticleServiceImpl.java @@ -1,5 +1,7 @@ package com.baeldung.spring.data.es.service; +import java.util.Optional; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -24,8 +26,8 @@ public class ArticleServiceImpl implements ArticleService { } @Override - public Article findOne(String id) { - return articleRepository.findOne(id); + public Optional
    findOne(String id) { + return articleRepository.findById(id); } @Override diff --git a/spring-data-elasticsearch/src/main/resources/log4j2.properties b/spring-data-elasticsearch/src/main/resources/log4j2.properties new file mode 100644 index 0000000000..fced116e6b --- /dev/null +++ b/spring-data-elasticsearch/src/main/resources/log4j2.properties @@ -0,0 +1,6 @@ +appender.console.type = Console +appender.console.name = console +appender.console.layout.type = PatternLayout + +rootLogger.level = info +rootLogger.appenderRef.console.ref = console \ No newline at end of file diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java index 285c164869..fbf4e5ab99 100644 --- a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java +++ b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java @@ -1,45 +1,49 @@ package com.baeldung.elasticsearch; -import com.alibaba.fastjson.JSON; -import org.elasticsearch.action.delete.DeleteResponse; -import org.elasticsearch.action.index.IndexResponse; -import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.search.SearchType; -import org.elasticsearch.client.Client; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.node.Node; -import org.elasticsearch.search.SearchHit; -import org.junit.Before; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.stream.Collectors; -import static org.elasticsearch.node.NodeBuilder.nodeBuilder; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.elasticsearch.action.DocWriteResponse.Result; +import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.client.Client; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.InetSocketTransportAddress; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.transport.client.PreBuiltTransportClient; +import org.junit.Before; +import org.junit.Test; + +import com.alibaba.fastjson.JSON; public class ElasticSearchManualTest { private List listOfPersons = new ArrayList<>(); private Client client = null; @Before - public void setUp() { + public void setUp() throws UnknownHostException { Person person1 = new Person(10, "John Doe", new Date()); Person person2 = new Person(25, "Janette Doe", new Date()); listOfPersons.add(person1); listOfPersons.add(person2); - Node node = nodeBuilder() - .clusterName("elasticsearch") - .client(true) - .node(); - client = node.client(); + + client = new PreBuiltTransportClient(Settings.builder().put("client.transport.sniff", true) + .put("cluster.name","elasticsearch").build()) + .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); } @Test @@ -47,11 +51,12 @@ public class ElasticSearchManualTest { String jsonObject = "{\"age\":20,\"dateOfBirth\":1471466076564,\"fullName\":\"John Doe\"}"; IndexResponse response = client .prepareIndex("people", "Doe") - .setSource(jsonObject) + .setSource(jsonObject, XContentType.JSON) .get(); String index = response.getIndex(); String type = response.getType(); - assertTrue(response.isCreated()); + + assertEquals(Result.CREATED, response.getResult()); assertEquals(index, "people"); assertEquals(type, "Doe"); } @@ -61,13 +66,14 @@ public class ElasticSearchManualTest { String jsonObject = "{\"age\":10,\"dateOfBirth\":1471455886564,\"fullName\":\"Johan Doe\"}"; IndexResponse response = client .prepareIndex("people", "Doe") - .setSource(jsonObject) + .setSource(jsonObject, XContentType.JSON) .get(); String id = response.getId(); DeleteResponse deleteResponse = client .prepareDelete("people", "Doe", id) .get(); - assertTrue(deleteResponse.isFound()); + + assertEquals(Result.DELETED,deleteResponse.getResult()); } @Test @@ -142,6 +148,7 @@ public class ElasticSearchManualTest { .prepareIndex("people", "Doe") .setSource(builder) .get(); - assertTrue(response.isCreated()); + + assertEquals(Result.CREATED, response.getResult()); } } diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesIntegrationTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesIntegrationTest.java index 304cf2e62d..1f55379418 100644 --- a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesIntegrationTest.java +++ b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesIntegrationTest.java @@ -1,13 +1,21 @@ package com.baeldung.elasticsearch; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; -import com.baeldung.spring.data.es.config.Config; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Client; +import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.ShapeRelation; -import org.elasticsearch.common.geo.builders.ShapeBuilder; +import org.elasticsearch.common.geo.builders.ShapeBuilders; import org.elasticsearch.common.unit.DistanceUnit; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; @@ -20,11 +28,8 @@ import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.Assert.assertTrue; +import com.baeldung.spring.data.es.config.Config; +import com.vividsolutions.jts.geom.Coordinate; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = Config.class) @@ -43,7 +48,7 @@ public class GeoQueriesIntegrationTest { public void setUp() { String jsonObject = "{\"Wonders\":{\"properties\":{\"name\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"region\":{\"type\":\"geo_shape\",\"tree\":\"quadtree\",\"precision\":\"1m\"},\"location\":{\"type\":\"geo_point\"}}}}"; CreateIndexRequest req = new CreateIndexRequest(WONDERS_OF_WORLD); - req.mapping(WONDERS, jsonObject); + req.mapping(WONDERS, jsonObject, XContentType.JSON); client.admin() .indices() .create(req) @@ -51,31 +56,36 @@ public class GeoQueriesIntegrationTest { } @Test - public void givenGeoShapeData_whenExecutedGeoShapeQuery_thenResultNonEmpty() { - String jsonObject = "{\"name\":\"Agra\",\"region\":{\"type\":\"envelope\",\"coordinates\":[[75,25],[80.1,30.2]]}}"; + public void givenGeoShapeData_whenExecutedGeoShapeQuery_thenResultNonEmpty() throws IOException{ + String jsonObject = "{\"name\":\"Agra\",\"region\":{\"type\":\"envelope\",\"coordinates\":[[75,30.2],[80.1, 25]]}}"; IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS) - .setSource(jsonObject) + .setSource(jsonObject, XContentType.JSON) .get(); + String tajMahalId = response.getId(); client.admin() .indices() .prepareRefresh(WONDERS_OF_WORLD) .get(); - QueryBuilder qb = QueryBuilders.geoShapeQuery("region", ShapeBuilder.newEnvelope() - .topLeft(74.00, 24.0) - .bottomRight(81.1, 31.2)) - .relation(ShapeRelation.WITHIN); + Coordinate topLeft =new Coordinate(74, 31.2); + Coordinate bottomRight =new Coordinate(81.1, 24); + QueryBuilder qb = QueryBuilders + .geoShapeQuery("region", ShapeBuilders.newEnvelope(topLeft, bottomRight)) + .relation(ShapeRelation.WITHIN); + SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD) .setTypes(WONDERS) .setQuery(qb) .execute() .actionGet(); + List ids = Arrays.stream(searchResponse.getHits() .getHits()) .map(SearchHit::getId) .collect(Collectors.toList()); + assertTrue(ids.contains(tajMahalId)); } @@ -83,7 +93,7 @@ public class GeoQueriesIntegrationTest { public void givenGeoPointData_whenExecutedGeoBoundingBoxQuery_thenResultNonEmpty() { String jsonObject = "{\"name\":\"Pyramids of Giza\",\"location\":[31.131302,29.976480]}"; IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS) - .setSource(jsonObject) + .setSource(jsonObject, XContentType.JSON) .get(); String pyramidsOfGizaId = response.getId(); client.admin() @@ -92,9 +102,8 @@ public class GeoQueriesIntegrationTest { .get(); QueryBuilder qb = QueryBuilders.geoBoundingBoxQuery("location") - .bottomLeft(28, 30) - .topRight(31, 32); - + .setCorners(31,30,28,32); + SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD) .setTypes(WONDERS) .setQuery(qb) @@ -111,7 +120,7 @@ public class GeoQueriesIntegrationTest { public void givenGeoPointData_whenExecutedGeoDistanceQuery_thenResultNonEmpty() { String jsonObject = "{\"name\":\"Lighthouse of alexandria\",\"location\":[31.131302,29.976480]}"; IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS) - .setSource(jsonObject) + .setSource(jsonObject, XContentType.JSON) .get(); String lighthouseOfAlexandriaId = response.getId(); client.admin() @@ -139,7 +148,7 @@ public class GeoQueriesIntegrationTest { public void givenGeoPointData_whenExecutedGeoPolygonQuery_thenResultNonEmpty() { String jsonObject = "{\"name\":\"The Great Rann of Kutch\",\"location\":[69.859741,23.733732]}"; IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS) - .setSource(jsonObject) + .setSource(jsonObject, XContentType.JSON) .get(); String greatRannOfKutchid = response.getId(); client.admin() @@ -147,10 +156,11 @@ public class GeoQueriesIntegrationTest { .prepareRefresh(WONDERS_OF_WORLD) .get(); - QueryBuilder qb = QueryBuilders.geoPolygonQuery("location") - .addPoint(22.733, 68.859) - .addPoint(24.733, 68.859) - .addPoint(23, 70.859); + List allPoints = new ArrayList(); + allPoints.add(new GeoPoint(22.733, 68.859)); + allPoints.add(new GeoPoint(24.733, 68.859)); + allPoints.add(new GeoPoint(23, 70.859)); + QueryBuilder qb = QueryBuilders.geoPolygonQuery("location", allPoints); SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD) .setTypes(WONDERS) diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchIntegrationTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchIntegrationTest.java index 60871e5eee..6ecb11cdbe 100644 --- a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchIntegrationTest.java +++ b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchIntegrationTest.java @@ -1,9 +1,15 @@ package com.baeldung.spring.data.es; -import com.baeldung.spring.data.es.config.Config; -import com.baeldung.spring.data.es.model.Article; -import com.baeldung.spring.data.es.model.Author; -import com.baeldung.spring.data.es.service.ArticleService; +import static java.util.Arrays.asList; +import static org.elasticsearch.index.query.Operator.AND; +import static org.elasticsearch.index.query.QueryBuilders.fuzzyQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchQuery; +import static org.elasticsearch.index.query.QueryBuilders.regexpQuery; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -16,15 +22,10 @@ import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.List; - -import static java.util.Arrays.asList; -import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND; -import static org.elasticsearch.index.query.QueryBuilders.fuzzyQuery; -import static org.elasticsearch.index.query.QueryBuilders.matchQuery; -import static org.elasticsearch.index.query.QueryBuilders.regexpQuery; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import com.baeldung.spring.data.es.config.Config; +import com.baeldung.spring.data.es.model.Article; +import com.baeldung.spring.data.es.model.Author; +import com.baeldung.spring.data.es.service.ArticleService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = Config.class) @@ -81,25 +82,25 @@ public class ElasticSearchIntegrationTest { public void givenPersistedArticles_whenSearchByAuthorsName_thenRightFound() { final Page
    articleByAuthorName = articleService - .findByAuthorName(johnSmith.getName(), new PageRequest(0, 10)); + .findByAuthorName(johnSmith.getName(), PageRequest.of(0, 10)); assertEquals(2L, articleByAuthorName.getTotalElements()); } @Test public void givenCustomQuery_whenSearchByAuthorsName_thenArticleIsFound() { - final Page
    articleByAuthorName = articleService.findByAuthorNameUsingCustomQuery("Smith", new PageRequest(0, 10)); + final Page
    articleByAuthorName = articleService.findByAuthorNameUsingCustomQuery("Smith", PageRequest.of(0, 10)); assertEquals(2L, articleByAuthorName.getTotalElements()); } @Test public void givenTagFilterQuery_whenSearchByTag_thenArticleIsFound() { - final Page
    articleByAuthorName = articleService.findByFilteredTagQuery("elasticsearch", new PageRequest(0, 10)); + final Page
    articleByAuthorName = articleService.findByFilteredTagQuery("elasticsearch", PageRequest.of(0, 10)); assertEquals(3L, articleByAuthorName.getTotalElements()); } @Test public void givenTagFilterQuery_whenSearchByAuthorsName_thenArticleIsFound() { - final Page
    articleByAuthorName = articleService.findByAuthorsNameAndFilteredTagQuery("Doe", "elasticsearch", new PageRequest(0, 10)); + final Page
    articleByAuthorName = articleService.findByAuthorsNameAndFilteredTagQuery("Doe", "elasticsearch", PageRequest.of(0, 10)); assertEquals(2L, articleByAuthorName.getTotalElements()); } @@ -125,7 +126,7 @@ public class ElasticSearchIntegrationTest { article.setTitle(newTitle); articleService.save(article); - assertEquals(newTitle, articleService.findOne(article.getId()).getTitle()); + assertEquals(newTitle, articleService.findOne(article.getId()).get().getTitle()); } @Test diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryIntegrationTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryIntegrationTest.java index c6af93bb62..2348c49830 100644 --- a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryIntegrationTest.java +++ b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryIntegrationTest.java @@ -1,9 +1,20 @@ package com.baeldung.spring.data.es; -import com.baeldung.spring.data.es.config.Config; -import com.baeldung.spring.data.es.model.Article; -import com.baeldung.spring.data.es.model.Author; -import com.baeldung.spring.data.es.service.ArticleService; +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toList; +import static org.elasticsearch.index.query.Operator.AND; +import static org.elasticsearch.index.query.QueryBuilders.boolQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery; +import static org.elasticsearch.index.query.QueryBuilders.matchQuery; +import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery; +import static org.elasticsearch.index.query.QueryBuilders.nestedQuery; +import static org.elasticsearch.index.query.QueryBuilders.termQuery; +import static org.junit.Assert.assertEquals; + +import java.util.List; +import java.util.Map; + +import org.apache.lucene.search.join.ScoreMode; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Client; import org.elasticsearch.common.unit.Fuzziness; @@ -14,7 +25,7 @@ import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation; import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; import org.elasticsearch.search.aggregations.bucket.terms.Terms; -import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder; +import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,20 +36,10 @@ import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static java.util.Arrays.asList; -import static java.util.stream.Collectors.toList; -import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND; -import static org.elasticsearch.index.query.QueryBuilders.boolQuery; -import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery; -import static org.elasticsearch.index.query.QueryBuilders.matchQuery; -import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery; -import static org.elasticsearch.index.query.QueryBuilders.nestedQuery; -import static org.elasticsearch.index.query.QueryBuilders.termQuery; -import static org.junit.Assert.assertEquals; +import com.baeldung.spring.data.es.config.Config; +import com.baeldung.spring.data.es.model.Article; +import com.baeldung.spring.data.es.model.Author; +import com.baeldung.spring.data.es.service.ArticleService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = Config.class) @@ -124,7 +125,7 @@ public class ElasticSearchQueryIntegrationTest { @Test public void givenNestedObject_whenQueryByAuthorsName_thenFoundArticlesByThatAuthor() { - final QueryBuilder builder = nestedQuery("authors", boolQuery().must(termQuery("authors.name", "smith"))); + final QueryBuilder builder = nestedQuery("authors", boolQuery().must(termQuery("authors.name", "smith")), ScoreMode.None); final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); final List
    articles = elasticsearchTemplate.queryForList(searchQuery, Article.class); @@ -134,7 +135,7 @@ public class ElasticSearchQueryIntegrationTest { @Test public void givenAnalyzedQuery_whenMakeAggregationOnTermCount_thenEachTokenCountsSeparately() { - final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("title"); + final TermsAggregationBuilder aggregation = AggregationBuilders.terms("top_tags").field("title"); final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation) .execute().actionGet(); @@ -150,8 +151,8 @@ public class ElasticSearchQueryIntegrationTest { @Test public void givenNotAnalyzedQuery_whenMakeAggregationOnTermCount_thenEachTermCountsIndividually() { - final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("tags") - .order(Terms.Order.aggregation("_count", false)); + final TermsAggregationBuilder aggregation = AggregationBuilders.terms("top_tags").field("tags") + .order(Terms.Order.count(false)); final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation) .execute().actionGet(); @@ -194,7 +195,7 @@ public class ElasticSearchQueryIntegrationTest { @Test public void givenBoolQuery_whenQueryByAuthorsName_thenFoundArticlesByThatAuthorAndFilteredTag() { - final QueryBuilder builder = boolQuery().must(nestedQuery("authors", boolQuery().must(termQuery("authors.name", "doe")))) + final QueryBuilder builder = boolQuery().must(nestedQuery("authors", boolQuery().must(termQuery("authors.name", "doe")), ScoreMode.None)) .filter(termQuery("tags", "elasticsearch")); final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder) diff --git a/spring-data-elasticsearch/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-data-elasticsearch/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6f45039c96 --- /dev/null +++ b/spring-data-elasticsearch/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.es.config.Config; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = Config.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-data-jpa/README.md b/spring-data-jpa/README.md new file mode 100644 index 0000000000..44ce240da3 --- /dev/null +++ b/spring-data-jpa/README.md @@ -0,0 +1,27 @@ +========= + +## Spring Data JPA Example Project + +### Relevant Articles: +- [Spring JPA – Multiple Databases](http://www.baeldung.com/spring-data-jpa-multiple-databases) +- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories) +- [Advanced Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging-advanced) +- [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) +- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations) +- [Spring Data Java 8 Support](http://www.baeldung.com/spring-data-java-8) +- [A Simple Tagging Implementation with JPA](http://www.baeldung.com/jpa-tagging) +- [Spring Data Composable Repositories](https://www.baeldung.com/spring-data-composable-repositories) +- [Auditing with JPA, Hibernate, and Spring Data JPA](https://www.baeldung.com/database-auditing-jpa) +- [Query Entities by Dates and Times with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-query-by-date) +- [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd) +- [Spring Data – CrudRepository save() Method](https://www.baeldung.com/spring-data-crud-repository-save) + +### Eclipse Config +After importing the project into Eclipse, you may see the following error: +"No persistence xml file found in project" + +This can be ignored: +- Project -> Properties -> Java Persistance -> JPA -> Error/Warnings -> Select Ignore on "No persistence xml file found in project" +Or: +- Eclipse -> Preferences - Validation - disable the "Build" execution of the JPA Validator + diff --git a/spring-data-jpa/pom.xml b/spring-data-jpa/pom.xml new file mode 100644 index 0000000000..8691ce1f09 --- /dev/null +++ b/spring-data-jpa/pom.xml @@ -0,0 +1,66 @@ + + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + 4.0.0 + + spring-data-jpa + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.hibernate + hibernate-ehcache + + + org.hibernate + hibernate-envers + + + com.h2database + h2 + + + + org.springframework.security + spring-security-test + test + + + + com.google.guava + guava + 21.0 + + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + org.junit.platform + junit-platform-launcher + ${junit-platform.version} + test + + + + \ No newline at end of file diff --git a/spring-data-jpa/src/main/java/com/baeldung/Application.java b/spring-data-jpa/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..72d29d9fa5 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/Application.java @@ -0,0 +1,17 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +import com.baeldung.dao.repositories.impl.ExtendedRepositoryImpl; + +@SpringBootApplication +@EnableJpaRepositories(repositoryBaseClass = ExtendedRepositoryImpl.class) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/config/PersistenceConfiguration.java b/spring-data-jpa/src/main/java/com/baeldung/config/PersistenceConfiguration.java new file mode 100644 index 0000000000..16407e510a --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/config/PersistenceConfiguration.java @@ -0,0 +1,102 @@ +package com.baeldung.config; + +import com.baeldung.services.IBarService; +import com.baeldung.services.impl.BarSpringDataJpaService; +import com.google.common.base.Preconditions; +import com.baeldung.dao.repositories.impl.ExtendedRepositoryImpl; +import com.baeldung.services.IFooService; +import com.baeldung.services.impl.FooService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.*; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Properties; + +@Configuration +@ComponentScan({"com.baeldung.dao", "com.baeldung.services"}) +@EnableTransactionManagement +@EnableJpaRepositories(basePackages = {"com.baeldung.dao"}, repositoryBaseClass = ExtendedRepositoryImpl.class) +@EnableJpaAuditing +@PropertySource("classpath:persistence.properties") +public class PersistenceConfiguration { + + @Autowired + private Environment env; + + public PersistenceConfiguration() { + super(); + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); + emf.setDataSource(dataSource()); + emf.setPackagesToScan("com.baeldung.domain"); + + final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + emf.setJpaVendorAdapter(vendorAdapter); + emf.setJpaProperties(hibernateProperties()); + + return emf; + } + + @Bean + public DataSource dataSource() { + final DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager transactionManager() { + final JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + @Bean + public IBarService barSpringDataJpaService() { + return new BarSpringDataJpaService(); + } + + @Bean + public IFooService fooService() { + return new FooService(); + } + + private final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + + hibernateProperties.setProperty("hibernate.show_sql", "true"); + // hibernateProperties.setProperty("hibernate.format_sql", "true"); + // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + + // Envers properties + hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix")); + + return hibernateProperties; + } + +} \ No newline at end of file diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java b/spring-data-jpa/src/main/java/com/baeldung/config/PersistenceProductConfiguration.java similarity index 84% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java rename to spring-data-jpa/src/main/java/com/baeldung/config/PersistenceProductConfiguration.java index 13f8f4b27c..207fba9bc5 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java +++ b/spring-data-jpa/src/main/java/com/baeldung/config/PersistenceProductConfiguration.java @@ -1,9 +1,6 @@ -package org.baeldung.config; - -import java.util.HashMap; - -import javax.sql.DataSource; +package com.baeldung.config; +import com.google.common.base.Preconditions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -16,16 +13,17 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; -import com.google.common.base.Preconditions; +import javax.sql.DataSource; +import java.util.HashMap; @Configuration -@PropertySource({ "classpath:persistence-multiple-db.properties" }) -@EnableJpaRepositories(basePackages = "org.baeldung.persistence.multiple.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager") -public class ProductConfig { +@PropertySource({"classpath:persistence-multiple-db.properties"}) +@EnableJpaRepositories(basePackages = "com.baeldung.dao.repositories.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager") +public class PersistenceProductConfiguration { @Autowired private Environment env; - public ProductConfig() { + public PersistenceProductConfiguration() { super(); } @@ -35,7 +33,7 @@ public class ProductConfig { public LocalContainerEntityManagerFactoryBean productEntityManager() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(productDataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.persistence.multiple.model.product" }); + em.setPackagesToScan("com.baeldung.domain.product"); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java b/spring-data-jpa/src/main/java/com/baeldung/config/PersistenceUserConfiguration.java similarity index 85% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java rename to spring-data-jpa/src/main/java/com/baeldung/config/PersistenceUserConfiguration.java index 8e85f5d8e0..dd32477755 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java +++ b/spring-data-jpa/src/main/java/com/baeldung/config/PersistenceUserConfiguration.java @@ -1,9 +1,6 @@ -package org.baeldung.config; - -import java.util.HashMap; - -import javax.sql.DataSource; +package com.baeldung.config; +import com.google.common.base.Preconditions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -17,16 +14,17 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; -import com.google.common.base.Preconditions; +import javax.sql.DataSource; +import java.util.HashMap; @Configuration -@PropertySource({ "classpath:persistence-multiple-db.properties" }) -@EnableJpaRepositories(basePackages = "org.baeldung.persistence.multiple.dao.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager") -public class UserConfig { +@PropertySource({"classpath:persistence-multiple-db.properties"}) +@EnableJpaRepositories(basePackages = "com.baeldung.dao.repositories.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager") +public class PersistenceUserConfiguration { @Autowired private Environment env; - public UserConfig() { + public PersistenceUserConfiguration() { super(); } @@ -37,7 +35,7 @@ public class UserConfig { public LocalContainerEntityManagerFactoryBean userEntityManager() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(userDataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.persistence.multiple.model.user" }); + em.setPackagesToScan("com.baeldung.domain.user"); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/IFooDao.java b/spring-data-jpa/src/main/java/com/baeldung/dao/IFooDao.java new file mode 100644 index 0000000000..bb3c229945 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/IFooDao.java @@ -0,0 +1,12 @@ +package com.baeldung.dao; + +import com.baeldung.domain.Foo; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +public interface IFooDao extends JpaRepository { + + @Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)") + Foo retrieveByName(@Param("name") String name); +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ArticleRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ArticleRepository.java new file mode 100644 index 0000000000..8402c099d9 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ArticleRepository.java @@ -0,0 +1,22 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.Article; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.Date; +import java.util.List; + +public interface ArticleRepository extends JpaRepository { + + List
    findAllByPublicationDate(Date publicationDate); + + List
    findAllByPublicationTimeBetween(Date publicationTimeStart, + Date publicationTimeEnd); + + @Query("select a from Article a where a.creationDateTime <= :creationDateTime") + List
    findAllWithCreationDateTimeBefore( + @Param("creationDateTime") Date creationDateTime); + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/CustomItemRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/CustomItemRepository.java new file mode 100644 index 0000000000..ba077ccf1f --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/CustomItemRepository.java @@ -0,0 +1,15 @@ +package com.baeldung.dao.repositories; + +import org.springframework.stereotype.Repository; + +import com.baeldung.domain.Item; + +@Repository +public interface CustomItemRepository { + + void deleteCustom(Item entity); + + Item findItemById(Long id); + + void findThenDelete(Long id); +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/CustomItemTypeRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/CustomItemTypeRepository.java new file mode 100644 index 0000000000..81ebdf3fda --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/CustomItemTypeRepository.java @@ -0,0 +1,13 @@ +package com.baeldung.dao.repositories; + +import org.springframework.stereotype.Repository; + +import com.baeldung.domain.ItemType; + +@Repository +public interface CustomItemTypeRepository { + + void deleteCustom(ItemType entity); + + void findThenDelete(Long id); +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ExtendedRepository.java similarity index 69% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java rename to spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ExtendedRepository.java index 9c9c12029a..9e82f02fa6 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ExtendedRepository.java @@ -1,4 +1,4 @@ -package org.baeldung.extended.persistence.dao; +package com.baeldung.dao.repositories; import java.io.Serializable; import java.util.List; @@ -8,5 +8,7 @@ import org.springframework.data.repository.NoRepositoryBean; @NoRepositoryBean public interface ExtendedRepository extends JpaRepository { - public List findByAttributeContainsText(String attributeName, String text); + + List findByAttributeContainsText(String attributeName, String text); + } diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ExtendedStudentRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ExtendedStudentRepository.java new file mode 100644 index 0000000000..199e4e5ff6 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ExtendedStudentRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.Student; + +public interface ExtendedStudentRepository extends ExtendedRepository { +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/IBarCrudRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/IBarCrudRepository.java new file mode 100644 index 0000000000..54a7d77691 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/IBarCrudRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.Bar; +import org.springframework.data.repository.CrudRepository; + +import java.io.Serializable; + +public interface IBarCrudRepository extends CrudRepository { + // +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InventoryRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InventoryRepository.java new file mode 100644 index 0000000000..a575f0b915 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InventoryRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.MerchandiseEntity; +import org.springframework.data.repository.CrudRepository; + +public interface InventoryRepository extends CrudRepository { +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ItemTypeRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ItemTypeRepository.java new file mode 100644 index 0000000000..2af83bc322 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ItemTypeRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.dao.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.domain.ItemType; + +@Repository +public interface ItemTypeRepository extends JpaRepository, CustomItemTypeRepository, CustomItemRepository { +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/LocationRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/LocationRepository.java new file mode 100644 index 0000000000..27bbe27af0 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/LocationRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.dao.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.domain.Location; + +@Repository +public interface LocationRepository extends JpaRepository { +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ReadOnlyLocationRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ReadOnlyLocationRepository.java new file mode 100644 index 0000000000..8f68cdbbe5 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/ReadOnlyLocationRepository.java @@ -0,0 +1,15 @@ +package com.baeldung.dao.repositories; + +import java.util.Optional; + +import org.springframework.data.repository.Repository; + +import com.baeldung.domain.Location; + +@org.springframework.stereotype.Repository +public interface ReadOnlyLocationRepository extends Repository { + + Optional findById(Long id); + + Location save(Location location); +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/StoreRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/StoreRepository.java new file mode 100644 index 0000000000..9318c32ee9 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/StoreRepository.java @@ -0,0 +1,13 @@ +package com.baeldung.dao.repositories; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.domain.Store; + +@Repository +public interface StoreRepository extends JpaRepository { + List findStoreByLocationId(Long locationId); +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/CustomItemRepositoryImpl.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/CustomItemRepositoryImpl.java new file mode 100644 index 0000000000..53def88af0 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/CustomItemRepositoryImpl.java @@ -0,0 +1,32 @@ +package com.baeldung.dao.repositories.impl; + +import javax.persistence.EntityManager; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import com.baeldung.domain.Item; +import com.baeldung.dao.repositories.CustomItemRepository; + +@Repository +public class CustomItemRepositoryImpl implements CustomItemRepository { + + @Autowired + private EntityManager entityManager; + + @Override + public void deleteCustom(Item item) { + entityManager.remove(item); + } + + @Override + public Item findItemById(Long id) { + return entityManager.find(Item.class, id); + } + + @Override + public void findThenDelete(Long id) { + final Item item = entityManager.find(Item.class, id); + entityManager.remove(item); + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/CustomItemTypeRepositoryImpl.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/CustomItemTypeRepositoryImpl.java new file mode 100644 index 0000000000..2b49f2380c --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/CustomItemTypeRepositoryImpl.java @@ -0,0 +1,31 @@ +package com.baeldung.dao.repositories.impl; + +import javax.persistence.EntityManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import com.baeldung.domain.ItemType; +import com.baeldung.dao.repositories.CustomItemTypeRepository; + +@Repository +public class CustomItemTypeRepositoryImpl implements CustomItemTypeRepository { + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomItemTypeRepositoryImpl.class); + + @Autowired + private EntityManager entityManager; + + @Override + public void deleteCustom(ItemType itemType) { + entityManager.remove(itemType); + } + + @Override + public void findThenDelete(Long id) { + ItemType itemTypeToDelete = entityManager.find(ItemType.class, id); + entityManager.remove(itemTypeToDelete); + } +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/ExtendedRepositoryImpl.java similarity index 93% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java rename to spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/ExtendedRepositoryImpl.java index 7ed652dc4d..f6f06efb51 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/impl/ExtendedRepositoryImpl.java @@ -1,4 +1,4 @@ -package org.baeldung.extended.persistence.dao; +package com.baeldung.dao.repositories.impl; import java.io.Serializable; import java.util.List; @@ -10,6 +10,7 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import javax.transaction.Transactional; +import com.baeldung.dao.repositories.ExtendedRepository; import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/product/ProductRepository.java similarity index 54% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java rename to spring-data-jpa/src/main/java/com/baeldung/dao/repositories/product/ProductRepository.java index bad0170a3a..7044d57e53 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/product/ProductRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.multiple.dao.product; +package com.baeldung.dao.repositories.product; -import org.baeldung.persistence.multiple.model.product.Product; +import com.baeldung.domain.product.Product; import org.springframework.data.jpa.repository.JpaRepository; public interface ProductRepository extends JpaRepository { diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/PossessionRepository.java similarity index 55% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java rename to spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/PossessionRepository.java index 34913632d8..f0eeb475c1 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/PossessionRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.multiple.dao.user; +package com.baeldung.dao.repositories.user; -import org.baeldung.persistence.multiple.model.user.Possession; +import com.baeldung.domain.user.Possession; import org.springframework.data.jpa.repository.JpaRepository; public interface PossessionRepository extends JpaRepository { diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/repository/UserRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java similarity index 74% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/repository/UserRepository.java rename to spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java index eadac9a0d7..5bb0232e4a 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/repository/UserRepository.java +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.repository; +package com.baeldung.dao.repositories.user; -import org.baeldung.persistence.model.User; +import com.baeldung.domain.user.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -8,24 +8,25 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.List; +import java.util.stream.Stream; -@Repository("userRepository") public interface UserRepository extends JpaRepository { + Stream findAllByName(String name); + @Query("SELECT u FROM User u WHERE u.status = 1") Collection findAllActiveUsers(); - @Query(value = "SELECT * FROM USERS u WHERE u.status = 1", nativeQuery = true) + @Query(value = "SELECT * FROM USERS.USERS u WHERE u.status = 1", nativeQuery = true) Collection findAllActiveUsersNative(); @Query("SELECT u FROM User u WHERE u.status = ?1") User findUserByStatus(Integer status); - @Query(value = "SELECT * FROM Users u WHERE u.status = ?1", nativeQuery = true) + @Query(value = "SELECT * FROM USERS.Users u WHERE u.status = ?1", nativeQuery = true) User findUserByStatusNative(Integer status); @Query("SELECT u FROM User u WHERE u.status = ?1 and u.name = ?2") @@ -34,7 +35,7 @@ public interface UserRepository extends JpaRepository { @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name") User findUserByStatusAndNameNamedParams(@Param("status") Integer status, @Param("name") String name); - @Query(value = "SELECT * FROM Users u WHERE u.status = :status AND u.name = :name", nativeQuery = true) + @Query(value = "SELECT * FROM USERS.Users u WHERE u.status = :status AND u.name = :name", nativeQuery = true) User findUserByStatusAndNameNamedParamsNative(@Param("status") Integer status, @Param("name") String name); @Query("SELECT u FROM User u WHERE u.status = :status and u.name = :name") @@ -46,7 +47,7 @@ public interface UserRepository extends JpaRepository { @Query("SELECT u FROM User u WHERE u.name like :name%") User findUserByNameLikeNamedParam(@Param("name") String name); - @Query(value = "SELECT * FROM users u WHERE u.name LIKE ?1%", nativeQuery = true) + @Query(value = "SELECT * FROM USERS.users u WHERE u.name LIKE ?1%", nativeQuery = true) User findUserByNameLikeNative(String name); @Query(value = "SELECT u FROM User u") @@ -55,7 +56,7 @@ public interface UserRepository extends JpaRepository { @Query(value = "SELECT u FROM User u ORDER BY id") Page findAllUsersWithPagination(Pageable pageable); - @Query(value = "SELECT * FROM Users ORDER BY id \n-- #pageable\n", countQuery = "SELECT count(*) FROM Users", nativeQuery = true) + @Query(value = "SELECT * FROM USERS.Users ORDER BY id", countQuery = "SELECT count(*) FROM USERS.Users", nativeQuery = true) Page findAllUsersWithPaginationNative(Pageable pageable); @Modifying @@ -63,7 +64,6 @@ public interface UserRepository extends JpaRepository { int updateUserSetStatusForName(@Param("status") Integer status, @Param("name") String name); @Modifying - @Query(value = "UPDATE Users u SET u.status = ? WHERE u.name = ?", nativeQuery = true) + @Query(value = "UPDATE USERS.Users u SET u.status = ? WHERE u.name = ?", nativeQuery = true) int updateUserSetStatusForNameNative(Integer status, String name); - } diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate.java new file mode 100644 index 0000000000..bf6ff0a0b9 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate.java @@ -0,0 +1,46 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Transient; + +import org.springframework.context.ApplicationEventPublisher; + +@Entity +class Aggregate { + @Transient + private ApplicationEventPublisher eventPublisher; + @Id + private long id; + + private Aggregate() { + } + + Aggregate(long id, ApplicationEventPublisher eventPublisher) { + this.id = id; + this.eventPublisher = eventPublisher; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "DomainEntity [id=" + id + "]"; + } + + void domainOperation() { + // some business logic + if (eventPublisher != null) { + eventPublisher.publishEvent(new DomainEvent()); + } + } + + long getId() { + return id; + } + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate2.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate2.java new file mode 100644 index 0000000000..3d2816299a --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate2.java @@ -0,0 +1,44 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import java.util.ArrayList; +import java.util.Collection; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Transient; + +import org.springframework.data.domain.AfterDomainEventPublication; +import org.springframework.data.domain.DomainEvents; + +@Entity +public class Aggregate2 { + @Transient + private final Collection domainEvents; + @Id + @GeneratedValue + private long id; + + public Aggregate2() { + domainEvents = new ArrayList<>(); + } + + @AfterDomainEventPublication + public void clearEvents() { + domainEvents.clear(); + } + + public void domainOperation() { + // some domain operation + domainEvents.add(new DomainEvent()); + } + + @DomainEvents + public Collection events() { + return domainEvents; + } + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate2Repository.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate2Repository.java new file mode 100644 index 0000000000..2a95abe347 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate2Repository.java @@ -0,0 +1,10 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import org.springframework.data.repository.CrudRepository; + +public interface Aggregate2Repository extends CrudRepository { + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate3.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate3.java new file mode 100644 index 0000000000..e0c3131b06 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate3.java @@ -0,0 +1,23 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.springframework.data.domain.AbstractAggregateRoot; + +@Entity +public class Aggregate3 extends AbstractAggregateRoot { + @Id + @GeneratedValue + private long id; + + public void domainOperation() { + // some domain operation + registerEvent(new DomainEvent()); + } + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate3Repository.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate3Repository.java new file mode 100644 index 0000000000..e442bdb210 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/Aggregate3Repository.java @@ -0,0 +1,14 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import org.springframework.data.repository.CrudRepository; + +/** + * @author goobar + * + */ +public interface Aggregate3Repository extends CrudRepository { + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/AggregateRepository.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/AggregateRepository.java new file mode 100644 index 0000000000..5a15156d03 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/AggregateRepository.java @@ -0,0 +1,10 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import org.springframework.data.repository.CrudRepository; + +public interface AggregateRepository extends CrudRepository { + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DddConfig.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DddConfig.java new file mode 100644 index 0000000000..1315b11875 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DddConfig.java @@ -0,0 +1,15 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.PropertySource; + +@SpringBootConfiguration +@EnableAutoConfiguration +@PropertySource("classpath:/ddd.properties") +public class DddConfig { + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DomainEvent.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DomainEvent.java new file mode 100644 index 0000000000..1e6479d4fc --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DomainEvent.java @@ -0,0 +1,8 @@ +/** + * + */ +package com.baeldung.ddd.event; + +class DomainEvent { + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DomainService.java b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DomainService.java new file mode 100644 index 0000000000..082c9bd88e --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/ddd/event/DomainService.java @@ -0,0 +1,31 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import javax.transaction.Transactional; + +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +@Service +public class DomainService { + private final ApplicationEventPublisher eventPublisher; + private final AggregateRepository repository; + + public DomainService(AggregateRepository repository, ApplicationEventPublisher eventPublisher) { + this.repository = repository; + this.eventPublisher = eventPublisher; + } + + @Transactional + public void serviceDomainOperation(long entityId) { + repository.findById(entityId) + .ifPresent(entity -> { + entity.domainOperation(); + repository.save(entity); + eventPublisher.publishEvent(new DomainEvent()); + }); + } + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/Article.java b/spring-data-jpa/src/main/java/com/baeldung/domain/Article.java new file mode 100644 index 0000000000..3b5a8be088 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/Article.java @@ -0,0 +1,23 @@ +package com.baeldung.domain; + +import javax.persistence.*; +import java.util.Date; + +@Entity +public class Article { + + @Id + @GeneratedValue + private Integer id; + @Temporal(TemporalType.DATE) + private Date publicationDate; + @Temporal(TemporalType.TIME) + private Date publicationTime; + @Temporal(TemporalType.TIMESTAMP) + private Date creationDateTime; + + public Integer getId() { + return id; + } + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/Bar.java b/spring-data-jpa/src/main/java/com/baeldung/domain/Bar.java new file mode 100644 index 0000000000..efd297bafc --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/Bar.java @@ -0,0 +1,220 @@ +package com.baeldung.domain; + +import com.google.common.collect.Sets; +import org.hibernate.annotations.OrderBy; +import org.hibernate.envers.Audited; +import org.jboss.logging.Logger; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.Date; +import java.util.Set; + +@Entity +@NamedQuery(name = "Bar.findAll", query = "SELECT b FROM Bar b") +@Audited +@EntityListeners(AuditingEntityListener.class) +public class Bar implements Serializable { + + private static Logger logger = Logger.getLogger(Bar.class); + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private int id; + + @Column(name = "name") + private String name; + @OneToMany(mappedBy = "bar", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @OrderBy(clause = "NAME DESC") + // @NotAudited + private Set fooSet = Sets.newHashSet(); + @Column(name = "operation") + private String operation; + @Column(name = "timestamp") + private long timestamp; + @Column(name = "created_date", updatable = false, nullable = false) + @CreatedDate + private long createdDate; + @Column(name = "modified_date") + @LastModifiedDate + private long modifiedDate; + @Column(name = "created_by") + @CreatedBy + private String createdBy; + @Column(name = "modified_by") + @LastModifiedBy + private String modifiedBy; + + public Bar() { + super(); + } + + public Bar(final String name) { + super(); + + this.name = name; + } + + public Set getFooSet() { + return fooSet; + } + + // API + + public void setFooSet(final Set fooSet) { + this.fooSet = fooSet; + } + + public int getId() { + return id; + } + + public void setId(final int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public OPERATION getOperation() { + return OPERATION.parse(operation); + } + + public void setOperation(final String operation) { + this.operation = operation; + } + + public void setOperation(final OPERATION operation) { + this.operation = operation.getValue(); + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(final long timestamp) { + this.timestamp = timestamp; + } + + public long getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(final long createdDate) { + this.createdDate = createdDate; + } + + public long getModifiedDate() { + return modifiedDate; + } + + public void setModifiedDate(final long modifiedDate) { + this.modifiedDate = modifiedDate; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(final String createdBy) { + this.createdBy = createdBy; + } + + public String getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(final String modifiedBy) { + this.modifiedBy = modifiedBy; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final Bar other = (Bar) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Bar [name=").append(name).append("]"); + return builder.toString(); + } + + @PrePersist + public void onPrePersist() { + logger.info("@PrePersist"); + audit(OPERATION.INSERT); + } + + @PreUpdate + public void onPreUpdate() { + logger.info("@PreUpdate"); + audit(OPERATION.UPDATE); + } + + @PreRemove + public void onPreRemove() { + logger.info("@PreRemove"); + audit(OPERATION.DELETE); + } + + private void audit(final OPERATION operation) { + setOperation(operation); + setTimestamp((new Date()).getTime()); + } + + public enum OPERATION { + INSERT, UPDATE, DELETE; + private String value; + + OPERATION() { + value = toString(); + } + + public static OPERATION parse(final String value) { + OPERATION operation = null; + for (final OPERATION op : OPERATION.values()) { + if (op.getValue().equals(value)) { + operation = op; + break; + } + } + return operation; + } + + public String getValue() { + return value; + } + } + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/Foo.java b/spring-data-jpa/src/main/java/com/baeldung/domain/Foo.java new file mode 100644 index 0000000000..ef88840746 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/Foo.java @@ -0,0 +1,94 @@ +package com.baeldung.domain; + +import org.hibernate.envers.Audited; + +import javax.persistence.*; +import java.io.Serializable; + +@NamedNativeQueries({@NamedNativeQuery(name = "callGetAllFoos", query = "CALL GetAllFoos()", resultClass = Foo.class), @NamedNativeQuery(name = "callGetFoosByName", query = "CALL GetFoosByName(:fooName)", resultClass = Foo.class)}) +@Entity +@Audited +// @Proxy(lazy = false) +public class Foo implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private long id; + + @Column(name = "name", nullable = false) + private String name; + + @ManyToOne(targetEntity = Bar.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "BAR_ID") + private Bar bar = new Bar(); + + public Foo() { + super(); + } + + public Foo(final String name) { + super(); + this.name = name; + } + + // + + public Bar getBar() { + return bar; + } + + public void setBar(final Bar bar) { + this.bar = bar; + } + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + // + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + final Foo other = (Foo) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Foo [name=").append(name).append("]"); + return builder.toString(); + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/Item.java b/spring-data-jpa/src/main/java/com/baeldung/domain/Item.java new file mode 100644 index 0000000000..97ce14d92d --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/Item.java @@ -0,0 +1,81 @@ +package com.baeldung.domain; + +import java.math.BigDecimal; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +@Entity +public class Item { + + private String color; + private String grade; + + @Id + private Long id; + + @ManyToOne + private ItemType itemType; + + private String name; + private BigDecimal price; + @ManyToOne + private Store store; + + public String getColor() { + return color; + } + + public String getGrade() { + return grade; + } + + public Long getId() { + return id; + } + + public ItemType getItemType() { + return itemType; + } + + public String getName() { + return name; + } + + public BigDecimal getPrice() { + return price; + } + + public Store getStore() { + return store; + } + + public void setColor(String color) { + this.color = color; + } + + public void setGrade(String grade) { + this.grade = grade; + } + + public void setId(Long id) { + this.id = id; + } + + public void setItemType(ItemType itemType) { + this.itemType = itemType; + } + + public void setName(String name) { + this.name = name; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public void setStore(Store store) { + this.store = store; + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/ItemType.java b/spring-data-jpa/src/main/java/com/baeldung/domain/ItemType.java new file mode 100644 index 0000000000..412079c2ae --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/ItemType.java @@ -0,0 +1,46 @@ +package com.baeldung.domain; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; + +@Entity +public class ItemType { + + @Id + private Long id; + @OneToMany(cascade = CascadeType.ALL) + @JoinColumn(name = "ITEM_TYPE_ID") + private List items = new ArrayList<>(); + + private String name; + + public Long getId() { + return id; + } + + public List getItems() { + return items; + } + + public String getName() { + return name; + } + + public void setId(Long id) { + this.id = id; + } + + public void setItems(List items) { + this.items = items; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/KVTag.java b/spring-data-jpa/src/main/java/com/baeldung/domain/KVTag.java new file mode 100644 index 0000000000..b3e7d78b30 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/KVTag.java @@ -0,0 +1,34 @@ +package com.baeldung.domain; + +import javax.persistence.Embeddable; + +@Embeddable +public class KVTag { + private String key; + private String value; + + public KVTag() { + } + + public KVTag(String key, String value) { + super(); + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/Location.java b/spring-data-jpa/src/main/java/com/baeldung/domain/Location.java new file mode 100644 index 0000000000..2178d378eb --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/Location.java @@ -0,0 +1,55 @@ +package com.baeldung.domain; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; + +@Entity +public class Location { + + private String city; + private String country; + @Id + private Long id; + + @OneToMany(cascade = CascadeType.ALL) + @JoinColumn(name = "LOCATION_ID") + private List stores = new ArrayList<>(); + + public String getCity() { + return city; + } + + public String getCountry() { + return country; + } + + public Long getId() { + return id; + } + + public List getStores() { + return stores; + } + + public void setCity(String city) { + this.city = city; + } + + public void setCountry(String country) { + this.country = country; + } + + public void setId(Long id) { + this.id = id; + } + + public void setStores(List stores) { + this.stores = stores; + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/MerchandiseEntity.java b/spring-data-jpa/src/main/java/com/baeldung/domain/MerchandiseEntity.java new file mode 100644 index 0000000000..bfc690e0e2 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/MerchandiseEntity.java @@ -0,0 +1,66 @@ +package com.baeldung.domain; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.math.BigDecimal; + +@Entity +public class MerchandiseEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String title; + + private BigDecimal price; + + private String brand; + + public MerchandiseEntity() { + } + + public MerchandiseEntity(String title, BigDecimal price) { + this.title = title; + this.price = price; + } + + public Long getId() { + return id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + @Override + public String toString() { + return "MerchandiseEntity{" + + "id=" + id + + ", title='" + title + '\'' + + ", price=" + price + + ", brand='" + brand + '\'' + + '}'; + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/SkillTag.java b/spring-data-jpa/src/main/java/com/baeldung/domain/SkillTag.java new file mode 100644 index 0000000000..1f2778c589 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/SkillTag.java @@ -0,0 +1,30 @@ +package com.baeldung.domain; + +import javax.persistence.Embeddable; + +@Embeddable +public class SkillTag { + private String name; + private int value; + + public SkillTag() { + } + + public SkillTag(String name, int value) { + super(); + this.name = name; + this.value = value; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public String getName() { + return name; + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/Store.java b/spring-data-jpa/src/main/java/com/baeldung/domain/Store.java new file mode 100644 index 0000000000..e04684c479 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/Store.java @@ -0,0 +1,76 @@ +package com.baeldung.domain; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +@Entity +public class Store { + + private Boolean active; + @Id + private Long id; + @OneToMany(cascade = CascadeType.ALL) + @JoinColumn(name = "STORE_ID") + private List items = new ArrayList<>(); + private Long itemsSold; + + @ManyToOne + private Location location; + + private String name; + + public Boolean getActive() { + return active; + } + + public Long getId() { + return id; + } + + public List getItems() { + return items; + } + + public Long getItemsSold() { + return itemsSold; + } + + public Location getLocation() { + return location; + } + + public String getName() { + return name; + } + + public void setActive(Boolean active) { + this.active = active; + } + + public void setId(Long id) { + this.id = id; + } + + public void setItems(List items) { + this.items = items; + } + + public void setItemsSold(Long itemsSold) { + this.itemsSold = itemsSold; + } + + public void setLocation(Location location) { + this.location = location; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/Student.java b/spring-data-jpa/src/main/java/com/baeldung/domain/Student.java new file mode 100644 index 0000000000..bd7eaeb24b --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/Student.java @@ -0,0 +1,74 @@ +package com.baeldung.domain; + +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.Id; +import java.util.ArrayList; +import java.util.List; + +@Entity +public class Student { + + @Id + private long id; + private String name; + + @ElementCollection + private List tags = new ArrayList<>(); + + @ElementCollection + private List skillTags = new ArrayList<>(); + + @ElementCollection + private List kvTags = new ArrayList<>(); + + public Student() { + } + + public Student(long id, String name) { + super(); + this.id = id; + 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 List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags.addAll(tags); + } + + public List getSkillTags() { + return skillTags; + } + + public void setSkillTags(List skillTags) { + this.skillTags.addAll(skillTags); + } + + public List getKVTags() { + return this.kvTags; + } + + public void setKVTags(List kvTags) { + this.kvTags.addAll(kvTags); + } + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java b/spring-data-jpa/src/main/java/com/baeldung/domain/product/Product.java similarity index 90% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java rename to spring-data-jpa/src/main/java/com/baeldung/domain/product/Product.java index 8490ed397d..42e6dd8f45 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/product/Product.java @@ -1,11 +1,11 @@ -package org.baeldung.persistence.multiple.model.product; +package com.baeldung.domain.product; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(schema = "spring_jpa_product") +@Table(schema = "products") public class Product { @Id diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/user/Possession.java b/spring-data-jpa/src/main/java/com/baeldung/domain/user/Possession.java new file mode 100644 index 0000000000..614e13df36 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/user/Possession.java @@ -0,0 +1,86 @@ +package com.baeldung.domain.user; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(schema = "users") +public class Possession { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String name; + + public Possession() { + super(); + } + + public Possession(final String name) { + super(); + + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(final int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = (prime * result) + (int) (id ^ (id >>> 32)); + result = (prime * result) + ((name == null) ? 0 : name.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; + } + final Possession other = (Possession) obj; + if (id != other.id) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Possesion [id=").append(id).append(", name=").append(name).append("]"); + return builder.toString(); + } + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/user/User.java b/spring-data-jpa/src/main/java/com/baeldung/domain/user/User.java new file mode 100644 index 0000000000..3a8b617d9a --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/user/User.java @@ -0,0 +1,86 @@ +package com.baeldung.domain.user; + +import javax.persistence.*; +import java.util.List; + +@Entity +@Table(name = "users", schema = "users") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + private String name; + private int age; + @Column(unique = true, nullable = false) + private String email; + private Integer status; + @OneToMany + List possessionList; + + public User() { + super(); + } + + public User(String name, String email, Integer status) { + this.name = name; + this.email = email; + this.status = status; + } + + public int getId() { + return id; + } + + public void setId(final int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(final String email) { + this.email = email; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public int getAge() { + return age; + } + + public void setAge(final int age) { + this.age = age; + } + + public List getPossessionList() { + return possessionList; + } + + public void setPossessionList(List possessionList) { + this.possessionList = possessionList; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("User [name=").append(name).append(", id=").append(id).append("]"); + return builder.toString(); + } + +} \ No newline at end of file diff --git a/spring-data-jpa/src/main/java/com/baeldung/services/IBarService.java b/spring-data-jpa/src/main/java/com/baeldung/services/IBarService.java new file mode 100644 index 0000000000..7e127488db --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/services/IBarService.java @@ -0,0 +1,7 @@ +package com.baeldung.services; + +import com.baeldung.domain.Bar; + +public interface IBarService extends IOperations { + // +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/services/IFooService.java b/spring-data-jpa/src/main/java/com/baeldung/services/IFooService.java new file mode 100644 index 0000000000..7e16ace5b6 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/services/IFooService.java @@ -0,0 +1,13 @@ +package com.baeldung.services; + +import com.baeldung.domain.Foo; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface IFooService extends IOperations { + + Foo retrieveByName(String name); + + Page findPaginated(Pageable pageable); + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/services/IOperations.java b/spring-data-jpa/src/main/java/com/baeldung/services/IOperations.java new file mode 100644 index 0000000000..d50d465639 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/services/IOperations.java @@ -0,0 +1,26 @@ +package com.baeldung.services; + +import org.springframework.data.domain.Page; + +import java.io.Serializable; +import java.util.List; + +public interface IOperations { + + T findOne(final long id); + + List findAll(); + + Page findPaginated(int page, int size); + + // write + + T create(final T entity); + + T update(final T entity); + + void delete(final T entity); + + void deleteById(final long entityId); + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/services/impl/AbstractService.java b/spring-data-jpa/src/main/java/com/baeldung/services/impl/AbstractService.java new file mode 100644 index 0000000000..708524225b --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/services/impl/AbstractService.java @@ -0,0 +1,61 @@ +package com.baeldung.services.impl; + +import com.baeldung.services.IOperations; +import com.google.common.collect.Lists; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.List; + +@Transactional +public abstract class AbstractService implements IOperations { + + // read - one + + @Override + @Transactional(readOnly = true) + public T findOne(final long id) { + return getDao().findById(id).orElse(null); + } + + // read - all + + @Override + @Transactional(readOnly = true) + public List findAll() { + return Lists.newArrayList(getDao().findAll()); + } + + @Override + public Page findPaginated(final int page, final int size) { + return getDao().findAll(new PageRequest(page, size)); + } + + // write + + @Override + public T create(final T entity) { + return getDao().save(entity); + } + + @Override + public T update(final T entity) { + return getDao().save(entity); + } + + @Override + public void delete(final T entity) { + getDao().delete(entity); + } + + @Override + public void deleteById(final long entityId) { + getDao().deleteById(entityId); + } + + protected abstract PagingAndSortingRepository getDao(); + +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/services/impl/AbstractSpringDataJpaService.java b/spring-data-jpa/src/main/java/com/baeldung/services/impl/AbstractSpringDataJpaService.java new file mode 100644 index 0000000000..28c86bee28 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/services/impl/AbstractSpringDataJpaService.java @@ -0,0 +1,45 @@ +package com.baeldung.services.impl; + +import com.baeldung.services.IOperations; +import com.google.common.collect.Lists; +import org.springframework.data.repository.CrudRepository; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.List; + +@Transactional(value = "transactionManager") +public abstract class AbstractSpringDataJpaService implements IOperations { + + @Override + public T findOne(final long id) { + return getDao().findById(id).orElse(null); + } + + @Override + public List findAll() { + return Lists.newArrayList(getDao().findAll()); + } + + @Override + public T create(final T entity) { + return getDao().save(entity); + } + + @Override + public T update(final T entity) { + return getDao().save(entity); + } + + @Override + public void delete(final T entity) { + getDao().delete(entity); + } + + @Override + public void deleteById(final long entityId) { + getDao().deleteById(entityId); + } + + protected abstract CrudRepository getDao(); +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/services/impl/BarSpringDataJpaService.java b/spring-data-jpa/src/main/java/com/baeldung/services/impl/BarSpringDataJpaService.java new file mode 100644 index 0000000000..ca3e5f868d --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/services/impl/BarSpringDataJpaService.java @@ -0,0 +1,30 @@ +package com.baeldung.services.impl; + +import com.baeldung.domain.Bar; +import com.baeldung.dao.repositories.IBarCrudRepository; +import com.baeldung.services.IBarService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.repository.CrudRepository; + +import java.io.Serializable; + +public class BarSpringDataJpaService extends AbstractSpringDataJpaService implements IBarService { + + @Autowired + private IBarCrudRepository dao; + + public BarSpringDataJpaService() { + super(); + } + + @Override + protected CrudRepository getDao() { + return dao; + } + + @Override + public Page findPaginated(int page, int size) { + throw new UnsupportedOperationException("Not implemented yet"); + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/services/impl/FooService.java b/spring-data-jpa/src/main/java/com/baeldung/services/impl/FooService.java new file mode 100644 index 0000000000..319ab3a825 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/services/impl/FooService.java @@ -0,0 +1,54 @@ +package com.baeldung.services.impl; + +import com.google.common.collect.Lists; +import com.baeldung.dao.IFooDao; +import com.baeldung.domain.Foo; +import com.baeldung.services.IFooService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional +public class FooService extends AbstractService implements IFooService { + + @Autowired + private IFooDao dao; + + public FooService() { + super(); + } + + // API + + @Override + protected PagingAndSortingRepository getDao() { + return dao; + } + + // custom methods + + @Override + public Foo retrieveByName(final String name) { + return dao.retrieveByName(name); + } + + // overridden to be secured + + @Override + @Transactional(readOnly = true) + public List findAll() { + return Lists.newArrayList(getDao().findAll()); + } + + @Override + public Page findPaginated(Pageable pageable) { + return dao.findAll(pageable); + } + +} diff --git a/spring-data-jpa/src/main/resources/application.properties b/spring-data-jpa/src/main/resources/application.properties new file mode 100644 index 0000000000..73d72bc7d6 --- /dev/null +++ b/spring-data-jpa/src/main/resources/application.properties @@ -0,0 +1,15 @@ +# spring.datasource.x +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +spring.datasource.username=sa +spring.datasource.password=sa + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=true +hibernate.cache.use_query_cache=true +hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory + +spring.datasource.data=import_entities.sql \ No newline at end of file diff --git a/spring-data-jpa/src/main/resources/ddd.properties b/spring-data-jpa/src/main/resources/ddd.properties new file mode 100644 index 0000000000..e5126b694b --- /dev/null +++ b/spring-data-jpa/src/main/resources/ddd.properties @@ -0,0 +1 @@ +spring.datasource.initialization-mode=never \ No newline at end of file diff --git a/spring-data-jpa/src/main/resources/logback.xml b/spring-data-jpa/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-data-jpa/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-data-jpa/src/main/resources/persistence-multiple-db.properties b/spring-data-jpa/src/main/resources/persistence-multiple-db.properties new file mode 100644 index 0000000000..75534e8a54 --- /dev/null +++ b/spring-data-jpa/src/main/resources/persistence-multiple-db.properties @@ -0,0 +1,13 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +user.jdbc.url=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS +product.jdbc.url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS +jdbc.user=sa +jdbc.pass=sa + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=false +hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/spring-data-jpa/src/main/resources/persistence.properties b/spring-data-jpa/src/main/resources/persistence.properties new file mode 100644 index 0000000000..3543e1b52b --- /dev/null +++ b/spring-data-jpa/src/main/resources/persistence.properties @@ -0,0 +1,16 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS +jdbc.user=sa +jdbc.pass=sa + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=true +hibernate.cache.use_query_cache=true +hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory + +# envers.X +envers.audit_table_suffix=_audit_log \ No newline at end of file diff --git a/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/ArticleRepositoryIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/ArticleRepositoryIntegrationTest.java new file mode 100644 index 0000000000..093e744003 --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/ArticleRepositoryIntegrationTest.java @@ -0,0 +1,69 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.config.PersistenceProductConfiguration; +import com.baeldung.config.PersistenceUserConfiguration; +import com.baeldung.domain.Article; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@RunWith(SpringRunner.class) +@DataJpaTest(excludeAutoConfiguration = {PersistenceConfiguration.class, PersistenceUserConfiguration.class, PersistenceProductConfiguration.class}) +public class ArticleRepositoryIntegrationTest { + + @Autowired + private ArticleRepository repository; + + @Test + public void givenImportedArticlesWhenFindAllByPublicationDateThenArticles1And2Returned() + throws Exception { + List
    result = repository.findAllByPublicationDate( + new SimpleDateFormat("yyyy-MM-dd").parse("2018-01-01") + ); + + assertEquals(2, result.size()); + assertTrue(result.stream() + .map(Article::getId) + .allMatch(id -> Arrays.asList(1, 2).contains(id)) + ); + } + + @Test + public void givenImportedArticlesWhenFindAllByPublicationTimeBetweenThenArticles2And3Returned() + throws Exception { + List
    result = repository.findAllByPublicationTimeBetween( + new SimpleDateFormat("HH:mm").parse("15:15"), + new SimpleDateFormat("HH:mm").parse("16:30") + ); + + assertEquals(2, result.size()); + assertTrue(result.stream() + .map(Article::getId) + .allMatch(id -> Arrays.asList(2, 3).contains(id)) + ); + } + + @Test + public void givenImportedArticlesWhenFindAllWithCreationDateTimeBeforeThenArticles2And3Returned() throws Exception { + List
    result = repository.findAllWithCreationDateTimeBefore( + new SimpleDateFormat("yyyy-MM-dd HH:mm").parse("2017-12-15 10:00") + ); + + assertEquals(2, result.size()); + assertTrue(result.stream() + .map(Article::getId) + .allMatch(id -> Arrays.asList(2, 3).contains(id)) + ); + } + +} diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/ExtendedStudentRepositoryIntegrationTest.java similarity index 71% rename from persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java rename to spring-data-jpa/src/test/java/com/baeldung/dao/repositories/ExtendedStudentRepositoryIntegrationTest.java index 7c6ec9b6da..b19a34df82 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java +++ b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/ExtendedStudentRepositoryIntegrationTest.java @@ -1,22 +1,22 @@ -package org.baeldung.persistence.repository; +package com.baeldung.dao.repositories; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.List; - -import javax.annotation.Resource; - -import org.baeldung.config.StudentJPAH2Config; -import org.baeldung.extended.persistence.dao.ExtendedStudentRepository; -import org.baeldung.inmemory.persistence.model.Student; +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.domain.Student; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { StudentJPAH2Config.class }) +import javax.annotation.Resource; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = {PersistenceConfiguration.class}) +@DirtiesContext public class ExtendedStudentRepositoryIntegrationTest { @Resource private ExtendedStudentRepository extendedStudentRepository; diff --git a/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/InventoryRepositoryIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/InventoryRepositoryIntegrationTest.java new file mode 100644 index 0000000000..9d6334445c --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/InventoryRepositoryIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.domain.MerchandiseEntity; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.math.BigDecimal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(SpringRunner.class) +@DataJpaTest(excludeAutoConfiguration = {PersistenceConfiguration.class}) +public class InventoryRepositoryIntegrationTest { + + private static final String ORIGINAL_TITLE = "Pair of Pants"; + private static final String UPDATED_TITLE = "Branded Luxury Pants"; + private static final String UPDATED_BRAND = "Armani"; + private static final String ORIGINAL_SHORTS_TITLE = "Pair of Shorts"; + + @Autowired + private InventoryRepository repository; + + @Test + public void shouldCreateNewEntryInDB() { + MerchandiseEntity pants = new MerchandiseEntity(ORIGINAL_TITLE, BigDecimal.ONE); + pants = repository.save(pants); + + MerchandiseEntity shorts = new MerchandiseEntity(ORIGINAL_SHORTS_TITLE, new BigDecimal(3)); + shorts = repository.save(shorts); + + assertNotNull(pants.getId()); + assertNotNull(shorts.getId()); + assertNotEquals(pants.getId(), shorts.getId()); + } + + @Test + public void shouldUpdateExistingEntryInDB() { + MerchandiseEntity pants = new MerchandiseEntity(ORIGINAL_TITLE, BigDecimal.ONE); + pants = repository.save(pants); + + Long originalId = pants.getId(); + + pants.setTitle(UPDATED_TITLE); + pants.setPrice(BigDecimal.TEN); + pants.setBrand(UPDATED_BRAND); + + MerchandiseEntity result = repository.save(pants); + + assertEquals(originalId, result.getId()); + assertEquals(UPDATED_TITLE, result.getTitle()); + assertEquals(BigDecimal.TEN, result.getPrice()); + assertEquals(UPDATED_BRAND, result.getBrand()); + } +} diff --git a/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/JpaRepositoriesIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/JpaRepositoriesIntegrationTest.java new file mode 100644 index 0000000000..01405c0b8a --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/JpaRepositoriesIntegrationTest.java @@ -0,0 +1,96 @@ +package com.baeldung.dao.repositories; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertNotNull; +import static junit.framework.TestCase.assertNull; +import static junit.framework.TestCase.assertTrue; + +import java.util.List; +import java.util.Optional; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.config.PersistenceProductConfiguration; +import com.baeldung.config.PersistenceUserConfiguration; +import com.baeldung.domain.Item; +import com.baeldung.domain.ItemType; +import com.baeldung.domain.Location; +import com.baeldung.domain.Store; + +@RunWith(SpringRunner.class) +@DataJpaTest(excludeAutoConfiguration = { PersistenceConfiguration.class, PersistenceUserConfiguration.class, PersistenceProductConfiguration.class }) +public class JpaRepositoriesIntegrationTest { + @Autowired + private LocationRepository locationRepository; + @Autowired + private StoreRepository storeRepository; + @Autowired + private ItemTypeRepository compositeRepository; + @Autowired + private ReadOnlyLocationRepository readOnlyRepository; + + @Test + public void whenSaveLocation_ThenGetSameLocation() { + Location location = new Location(); + location.setId(100L); + location.setCountry("Country H"); + location.setCity("City Hundred"); + location = locationRepository.saveAndFlush(location); + + Location otherLocation = locationRepository.getOne(location.getId()); + assertEquals("Country H", otherLocation.getCountry()); + assertEquals("City Hundred", otherLocation.getCity()); + + locationRepository.delete(otherLocation); + } + + @Test + public void givenLocationId_whenFindStores_thenGetStores() { + List stores = storeRepository.findStoreByLocationId(1L); + assertEquals(1, stores.size()); + } + + @Test + public void givenItemTypeId_whenDeleted_ThenItemTypeDeleted() { + Optional itemType = compositeRepository.findById(1L); + assertTrue(itemType.isPresent()); + compositeRepository.deleteCustom(itemType.get()); + itemType = compositeRepository.findById(1L); + assertFalse(itemType.isPresent()); + } + + @Test + public void givenItemId_whenUsingCustomRepo_ThenDeleteAppropriateEntity() { + Item item = compositeRepository.findItemById(1L); + assertNotNull(item); + compositeRepository.deleteCustom(item); + item = compositeRepository.findItemById(1L); + assertNull(item); + } + + @Test + public void givenItemAndItemType_WhenAmbiguousDeleteCalled_ThenItemTypeDeletedAndNotItem() { + Optional itemType = compositeRepository.findById(1L); + assertTrue(itemType.isPresent()); + Item item = compositeRepository.findItemById(2L); + assertNotNull(item); + + compositeRepository.findThenDelete(1L); + Optional sameItemType = compositeRepository.findById(1L); + assertFalse(sameItemType.isPresent()); + Item sameItem = compositeRepository.findItemById(2L); + assertNotNull(sameItem); + } + + @Test + public void whenCreatingReadOnlyRepo_thenHaveOnlyReadOnlyOperationsAvailable() { + Optional location = readOnlyRepository.findById(1L); + assertNotNull(location); + } +} diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/UserRepositoryIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryIntegrationTest.java similarity index 66% rename from persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/UserRepositoryIntegrationTest.java rename to spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryIntegrationTest.java index 90db9f4e74..e29161394b 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/UserRepositoryIntegrationTest.java +++ b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryIntegrationTest.java @@ -1,22 +1,25 @@ -package org.baeldung.persistence.repository; +package com.baeldung.dao.repositories; -import org.baeldung.config.PersistenceJPAConfigL2Cache; -import org.baeldung.persistence.model.User; +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.dao.repositories.user.UserRepository; +import com.baeldung.domain.user.User; import org.junit.After; 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.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.JpaSort; import org.springframework.data.mapping.PropertyReferenceException; -import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -24,31 +27,71 @@ import static org.assertj.core.api.Assertions.assertThat; * Created by adam. */ @RunWith(SpringRunner.class) -@ContextConfiguration(classes = PersistenceJPAConfigL2Cache.class) +@SpringBootTest(classes = PersistenceConfiguration.class) +@DirtiesContext public class UserRepositoryIntegrationTest { private final String USER_NAME_ADAM = "Adam"; private final String USER_NAME_PETER = "Peter"; + + private final String USER_EMAIL = "email@example.com"; + private final String USER_EMAIL2 = "email2@example.com"; + private final String USER_EMAIL3 = "email3@example.com"; + private final String USER_EMAIL4 = "email4@example.com"; + private final String USER_EMAIL5 = "email5@example.com"; + private final String USER_EMAIL6 = "email6@example.com"; + private final Integer INACTIVE_STATUS = 0; private final Integer ACTIVE_STATUS = 1; @Autowired private UserRepository userRepository; + @Test + @Transactional + public void givenUsersWithSameNameInDBWhenFindAllByNameThenReturnStreamOfUsers() { + User user1 = new User(); + user1.setName(USER_NAME_ADAM); + user1.setEmail(USER_EMAIL); + userRepository.save(user1); + + User user2 = new User(); + user2.setName(USER_NAME_ADAM); + user2.setEmail(USER_EMAIL2); + userRepository.save(user2); + + User user3 = new User(); + user3.setName(USER_NAME_ADAM); + user3.setEmail(USER_EMAIL3); + userRepository.save(user3); + + User user4 = new User(); + user4.setName("SAMPLE"); + user4.setEmail(USER_EMAIL4); + userRepository.save(user4); + + try (Stream foundUsersStream = userRepository.findAllByName(USER_NAME_ADAM)) { + assertThat(foundUsersStream.count()).isEqualTo(3l); + } + } + @Test public void givenUsersInDBWhenFindAllWithQueryAnnotationThenReturnCollectionWithActiveUsers() { User user1 = new User(); user1.setName(USER_NAME_ADAM); + user1.setEmail(USER_EMAIL); user1.setStatus(ACTIVE_STATUS); userRepository.save(user1); User user2 = new User(); user2.setName(USER_NAME_ADAM); + user2.setEmail(USER_EMAIL2); user2.setStatus(ACTIVE_STATUS); userRepository.save(user2); User user3 = new User(); user3.setName(USER_NAME_ADAM); + user3.setEmail(USER_EMAIL3); user3.setStatus(INACTIVE_STATUS); userRepository.save(user3); @@ -61,16 +104,19 @@ public class UserRepositoryIntegrationTest { public void givenUsersInDBWhenFindAllWithQueryAnnotationNativeThenReturnCollectionWithActiveUsers() { User user1 = new User(); user1.setName(USER_NAME_ADAM); + user1.setEmail(USER_EMAIL); user1.setStatus(ACTIVE_STATUS); userRepository.save(user1); User user2 = new User(); user2.setName(USER_NAME_ADAM); + user2.setEmail(USER_EMAIL2); user2.setStatus(ACTIVE_STATUS); userRepository.save(user2); User user3 = new User(); user3.setName(USER_NAME_ADAM); + user3.setEmail(USER_EMAIL3); user3.setStatus(INACTIVE_STATUS); userRepository.save(user3); @@ -83,6 +129,7 @@ public class UserRepositoryIntegrationTest { public void givenUserInDBWhenFindUserByStatusWithQueryAnnotationThenReturnActiveUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); @@ -95,6 +142,7 @@ public class UserRepositoryIntegrationTest { public void givenUserInDBWhenFindUserByStatusWithQueryAnnotationNativeThenReturnActiveUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); @@ -107,11 +155,13 @@ public class UserRepositoryIntegrationTest { public void givenUsersInDBWhenFindUserByStatusAndNameWithQueryAnnotationIndexedParamsThenReturnOneUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); User user2 = new User(); user2.setName(USER_NAME_PETER); + user2.setEmail(USER_EMAIL2); user2.setStatus(ACTIVE_STATUS); userRepository.save(user2); @@ -124,11 +174,13 @@ public class UserRepositoryIntegrationTest { public void givenUsersInDBWhenFindUserByStatusAndNameWithQueryAnnotationNamedParamsThenReturnOneUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); User user2 = new User(); user2.setName(USER_NAME_PETER); + user2.setEmail(USER_EMAIL2); user2.setStatus(ACTIVE_STATUS); userRepository.save(user2); @@ -141,11 +193,13 @@ public class UserRepositoryIntegrationTest { public void givenUsersInDBWhenFindUserByStatusAndNameWithQueryAnnotationNativeNamedParamsThenReturnOneUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); User user2 = new User(); user2.setName(USER_NAME_PETER); + user2.setEmail(USER_EMAIL2); user2.setStatus(ACTIVE_STATUS); userRepository.save(user2); @@ -158,11 +212,13 @@ public class UserRepositoryIntegrationTest { public void givenUsersInDBWhenFindUserByStatusAndNameWithQueryAnnotationNamedParamsCustomNamesThenReturnOneUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); User user2 = new User(); user2.setName(USER_NAME_PETER); + user2.setEmail(USER_EMAIL2); user2.setStatus(ACTIVE_STATUS); userRepository.save(user2); @@ -175,6 +231,7 @@ public class UserRepositoryIntegrationTest { public void givenUsersInDBWhenFindUserByNameLikeWithQueryAnnotationIndexedParamsThenReturnUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); @@ -187,6 +244,7 @@ public class UserRepositoryIntegrationTest { public void givenUsersInDBWhenFindUserByNameLikeWithQueryAnnotationNamedParamsThenReturnUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); @@ -199,6 +257,7 @@ public class UserRepositoryIntegrationTest { public void givenUsersInDBWhenFindUserByNameLikeWithQueryAnnotationNativeThenReturnUser() { User user = new User(); user.setName(USER_NAME_ADAM); + user.setEmail(USER_EMAIL); user.setStatus(ACTIVE_STATUS); userRepository.save(user); @@ -209,9 +268,9 @@ public class UserRepositoryIntegrationTest { @Test public void givenUsersInDBWhenFindAllWithSortByNameThenReturnUsersSorted() { - userRepository.save(new User(USER_NAME_ADAM, ACTIVE_STATUS)); - userRepository.save(new User(USER_NAME_PETER, ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE", INACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_ADAM, USER_EMAIL, ACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_PETER, USER_EMAIL2, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL3, INACTIVE_STATUS)); List usersSortByName = userRepository.findAll(new Sort(Sort.Direction.ASC, "name")); @@ -222,9 +281,9 @@ public class UserRepositoryIntegrationTest { @Test(expected = PropertyReferenceException.class) public void givenUsersInDBWhenFindAllSortWithFunctionThenThrowException() { - userRepository.save(new User(USER_NAME_ADAM, ACTIVE_STATUS)); - userRepository.save(new User(USER_NAME_PETER, ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE", INACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_ADAM, USER_EMAIL, ACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_PETER, USER_EMAIL2, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL3, INACTIVE_STATUS)); userRepository.findAll(new Sort(Sort.Direction.ASC, "name")); @@ -237,9 +296,9 @@ public class UserRepositoryIntegrationTest { @Test public void givenUsersInDBWhenFindAllSortWithFunctionQueryAnnotationJPQLThenReturnUsersSorted() { - userRepository.save(new User(USER_NAME_ADAM, ACTIVE_STATUS)); - userRepository.save(new User(USER_NAME_PETER, ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE", INACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_ADAM, USER_EMAIL, ACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_PETER, USER_EMAIL2, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL3, INACTIVE_STATUS)); userRepository.findAllUsers(new Sort("name")); @@ -252,12 +311,12 @@ public class UserRepositoryIntegrationTest { @Test public void givenUsersInDBWhenFindAllWithPageRequestQueryAnnotationJPQLThenReturnPageOfUsers() { - userRepository.save(new User(USER_NAME_ADAM, ACTIVE_STATUS)); - userRepository.save(new User(USER_NAME_PETER, ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE", INACTIVE_STATUS)); - userRepository.save(new User("SAMPLE1", INACTIVE_STATUS)); - userRepository.save(new User("SAMPLE2", INACTIVE_STATUS)); - userRepository.save(new User("SAMPLE3", INACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_ADAM, USER_EMAIL, ACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_PETER, USER_EMAIL2, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL3, INACTIVE_STATUS)); + userRepository.save(new User("SAMPLE1", USER_EMAIL4, INACTIVE_STATUS)); + userRepository.save(new User("SAMPLE2", USER_EMAIL5, INACTIVE_STATUS)); + userRepository.save(new User("SAMPLE3", USER_EMAIL6, INACTIVE_STATUS)); Page usersPage = userRepository.findAllUsersWithPagination(new PageRequest(1, 3)); @@ -269,12 +328,12 @@ public class UserRepositoryIntegrationTest { @Test public void givenUsersInDBWhenFindAllWithPageRequestQueryAnnotationNativeThenReturnPageOfUsers() { - userRepository.save(new User(USER_NAME_ADAM, ACTIVE_STATUS)); - userRepository.save(new User(USER_NAME_PETER, ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE", INACTIVE_STATUS)); - userRepository.save(new User("SAMPLE1", INACTIVE_STATUS)); - userRepository.save(new User("SAMPLE2", INACTIVE_STATUS)); - userRepository.save(new User("SAMPLE3", INACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_ADAM, USER_EMAIL, ACTIVE_STATUS)); + userRepository.save(new User(USER_NAME_PETER, USER_EMAIL2, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL3, INACTIVE_STATUS)); + userRepository.save(new User("SAMPLE1", USER_EMAIL4, INACTIVE_STATUS)); + userRepository.save(new User("SAMPLE2", USER_EMAIL5, INACTIVE_STATUS)); + userRepository.save(new User("SAMPLE3", USER_EMAIL6, INACTIVE_STATUS)); Page usersSortByNameLength = userRepository.findAllUsersWithPaginationNative(new PageRequest(1, 3)); @@ -287,10 +346,10 @@ public class UserRepositoryIntegrationTest { @Test @Transactional public void givenUsersInDBWhenUpdateStatusForNameModifyingQueryAnnotationJPQLThenModifyMatchingUsers() { - userRepository.save(new User("SAMPLE", ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE1", ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE", ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE3", ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE1", USER_EMAIL2, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL3, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE3", USER_EMAIL4, ACTIVE_STATUS)); int updatedUsersSize = userRepository.updateUserSetStatusForName(INACTIVE_STATUS, "SAMPLE"); @@ -300,10 +359,10 @@ public class UserRepositoryIntegrationTest { @Test @Transactional public void givenUsersInDBWhenUpdateStatusForNameModifyingQueryAnnotationNativeThenModifyMatchingUsers() { - userRepository.save(new User("SAMPLE", ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE1", ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE", ACTIVE_STATUS)); - userRepository.save(new User("SAMPLE3", ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE1", USER_EMAIL2, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE", USER_EMAIL3, ACTIVE_STATUS)); + userRepository.save(new User("SAMPLE3", USER_EMAIL4, ACTIVE_STATUS)); userRepository.flush(); int updatedUsersSize = userRepository.updateUserSetStatusForNameNative(INACTIVE_STATUS, "SAMPLE"); diff --git a/spring-data-jpa/src/test/java/com/baeldung/ddd/event/Aggregate2EventsIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/ddd/event/Aggregate2EventsIntegrationTest.java new file mode 100644 index 0000000000..3f650d4d63 --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/ddd/event/Aggregate2EventsIntegrationTest.java @@ -0,0 +1,68 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +@SpringJUnitConfig +@SpringBootTest +class Aggregate2EventsIntegrationTest { + @MockBean + private TestEventHandler eventHandler; + @Autowired + private Aggregate2Repository repository; + + // @formatter:off + @DisplayName("given aggregate with @AfterDomainEventPublication," + + " when do domain operation and save twice," + + " then an event is published only for the first time") + // @formatter:on + @Test + void afterDomainEvents() { + // given + Aggregate2 aggregate = new Aggregate2(); + + // when + aggregate.domainOperation(); + repository.save(aggregate); + repository.save(aggregate); + + // then + verify(eventHandler, times(1)).handleEvent(any(DomainEvent.class)); + } + + @BeforeEach + void beforeEach() { + repository.deleteAll(); + } + + // @formatter:off + @DisplayName("given aggregate with @DomainEvents," + + " when do domain operation and save," + + " then an event is published") + // @formatter:on + @Test + void domainEvents() { + // given + Aggregate2 aggregate = new Aggregate2(); + + // when + aggregate.domainOperation(); + repository.save(aggregate); + + // then + verify(eventHandler, times(1)).handleEvent(any(DomainEvent.class)); + } + +} diff --git a/spring-data-jpa/src/test/java/com/baeldung/ddd/event/Aggregate3EventsIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/ddd/event/Aggregate3EventsIntegrationTest.java new file mode 100644 index 0000000000..893dcac3f8 --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/ddd/event/Aggregate3EventsIntegrationTest.java @@ -0,0 +1,63 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +@SpringJUnitConfig +@SpringBootTest +class Aggregate3EventsIntegrationTest { + + @MockBean + private TestEventHandler eventHandler; + @Autowired + private Aggregate3Repository repository; + + // @formatter:off + @DisplayName("given aggregate extending AbstractAggregateRoot," + + " when do domain operation and save twice," + + " then an event is published only for the first time") + // @formatter:on + @Test + void afterDomainEvents() { + // given + Aggregate3 aggregate = new Aggregate3(); + + // when + aggregate.domainOperation(); + repository.save(aggregate); + repository.save(aggregate); + + // then + verify(eventHandler, times(1)).handleEvent(any(DomainEvent.class)); + } + + // @formatter:off + @DisplayName("given aggregate extending AbstractAggregateRoot," + + " when do domain operation and save," + + " then an event is published") + // @formatter:on + @Test + void domainEvents() { + // given + Aggregate3 aggregate = new Aggregate3(); + + // when + aggregate.domainOperation(); + repository.save(aggregate); + + // then + verify(eventHandler, times(1)).handleEvent(any(DomainEvent.class)); + } + +} diff --git a/spring-data-jpa/src/test/java/com/baeldung/ddd/event/AggregateEventsIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/ddd/event/AggregateEventsIntegrationTest.java new file mode 100644 index 0000000000..f0e1147245 --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/ddd/event/AggregateEventsIntegrationTest.java @@ -0,0 +1,82 @@ +package com.baeldung.ddd.event; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +@SpringJUnitConfig +@SpringBootTest +class AggregateEventsIntegrationTest { + + @Autowired + private DomainService domainService; + + @MockBean + private TestEventHandler eventHandler; + @Autowired + private ApplicationEventPublisher eventPublisher; + @Autowired + private AggregateRepository repository; + + // @formatter:off + @DisplayName("given existing aggregate," + + " when do domain operation directly on aggregate," + + " then domain event is NOT published") + // @formatter:on + @Test + void aggregateEventsTest() { + Aggregate existingDomainEntity = new Aggregate(0, eventPublisher); + repository.save(existingDomainEntity); + + // when + repository.findById(existingDomainEntity.getId()) + .get() + .domainOperation(); + + // then + verifyZeroInteractions(eventHandler); + } + + @BeforeEach + void beforeEach() { + repository.deleteAll(); + } + + // @formatter:off + @DisplayName("given existing aggregate," + + " when do domain operation on service," + + " then domain event is published") + // @formatter:on + @Test + void serviceEventsTest() { + Aggregate existingDomainEntity = new Aggregate(1, eventPublisher); + repository.save(existingDomainEntity); + + // when + domainService.serviceDomainOperation(existingDomainEntity.getId()); + + // then + verify(eventHandler, times(1)).handleEvent(any(DomainEvent.class)); + } + + @TestConfiguration + public static class TestConfig { + @Bean + public DomainService domainService(AggregateRepository repository, ApplicationEventPublisher eventPublisher) { + return new DomainService(repository, eventPublisher); + } + } + +} diff --git a/spring-data-jpa/src/test/java/com/baeldung/ddd/event/TestEventHandler.java b/spring-data-jpa/src/test/java/com/baeldung/ddd/event/TestEventHandler.java new file mode 100644 index 0000000000..721402c17a --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/ddd/event/TestEventHandler.java @@ -0,0 +1,12 @@ +/** + * + */ +package com.baeldung.ddd.event; + +import org.springframework.transaction.event.TransactionalEventListener; + +interface TestEventHandler { + @TransactionalEventListener + void handleEvent(DomainEvent event); + +} diff --git a/spring-data-jpa/src/test/java/com/baeldung/services/AbstractServicePersistenceIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/services/AbstractServicePersistenceIntegrationTest.java new file mode 100644 index 0000000000..acac66f2f7 --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/services/AbstractServicePersistenceIntegrationTest.java @@ -0,0 +1,251 @@ +package com.baeldung.services; + +import com.baeldung.domain.Foo; +import com.baeldung.util.IDUtil; +import org.hamcrest.Matchers; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.dao.DataAccessException; + +import java.io.Serializable; +import java.util.List; + +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.*; + +public abstract class AbstractServicePersistenceIntegrationTest { + + // tests + + // find - one + + @Test + /**/public final void givenResourceDoesNotExist_whenResourceIsRetrieved_thenNoResourceIsReceived() { + // When + final Foo createdResource = getApi().findOne(IDUtil.randomPositiveLong()); + + // Then + assertNull(createdResource); + } + + @Test + public void givenResourceExists_whenResourceIsRetrieved_thenNoExceptions() { + final Foo existingResource = persistNewEntity(); + getApi().findOne(existingResource.getId()); + } + + @Test + public void givenResourceDoesNotExist_whenResourceIsRetrieved_thenNoExceptions() { + getApi().findOne(IDUtil.randomPositiveLong()); + } + + @Test + public void givenResourceExists_whenResourceIsRetrieved_thenTheResultIsNotNull() { + final Foo existingResource = persistNewEntity(); + final Foo retrievedResource = getApi().findOne(existingResource.getId()); + assertNotNull(retrievedResource); + } + + @Test + public void givenResourceExists_whenResourceIsRetrieved_thenResourceIsRetrievedCorrectly() { + final Foo existingResource = persistNewEntity(); + final Foo retrievedResource = getApi().findOne(existingResource.getId()); + assertEquals(existingResource, retrievedResource); + } + + // find - one - by name + + // find - all + + @Test + /**/public void whenAllResourcesAreRetrieved_thenNoExceptions() { + getApi().findAll(); + } + + @Test + /**/public void whenAllResourcesAreRetrieved_thenTheResultIsNotNull() { + final List resources = getApi().findAll(); + + assertNotNull(resources); + } + + @Test + /**/public void givenAtLeastOneResourceExists_whenAllResourcesAreRetrieved_thenRetrievedResourcesAreNotEmpty() { + persistNewEntity(); + + // When + final List allResources = getApi().findAll(); + + // Then + assertThat(allResources, not(Matchers. empty())); + } + + @Test + /**/public void givenAnResourceExists_whenAllResourcesAreRetrieved_thenTheExistingResourceIsIndeedAmongThem() { + final Foo existingResource = persistNewEntity(); + + final List resources = getApi().findAll(); + + assertThat(resources, hasItem(existingResource)); + } + + @Test + /**/public void whenAllResourcesAreRetrieved_thenResourcesHaveIds() { + persistNewEntity(); + + // When + final List allResources = getApi().findAll(); + + // Then + for (final Foo resource : allResources) { + assertNotNull(resource.getId()); + } + } + + // create + + @Test(expected = RuntimeException.class) + /**/public void whenNullResourceIsCreated_thenException() { + getApi().create(null); + } + + @Test + /**/public void whenResourceIsCreated_thenNoExceptions() { + persistNewEntity(); + } + + @Test + /**/public void whenResourceIsCreated_thenResourceIsRetrievable() { + final Foo existingResource = persistNewEntity(); + + assertNotNull(getApi().findOne(existingResource.getId())); + } + + @Test + /**/public void whenResourceIsCreated_thenSavedResourceIsEqualToOriginalResource() { + final Foo originalResource = createNewEntity(); + final Foo savedResource = getApi().create(originalResource); + + assertEquals(originalResource, savedResource); + } + + @Test(expected = RuntimeException.class) + public void whenResourceWithFailedConstraintsIsCreated_thenException() { + final Foo invalidResource = createNewEntity(); + invalidate(invalidResource); + + getApi().create(invalidResource); + } + + /** + * -- specific to the persistence engine + */ + @Test(expected = DataAccessException.class) + @Ignore("Hibernate simply ignores the id silently and still saved (tracking this)") + public void whenResourceWithIdIsCreated_thenDataAccessException() { + final Foo resourceWithId = createNewEntity(); + resourceWithId.setId(IDUtil.randomPositiveLong()); + + getApi().create(resourceWithId); + } + + // update + + @Test(expected = RuntimeException.class) + /**/public void whenNullResourceIsUpdated_thenException() { + getApi().update(null); + } + + @Test + /**/public void givenResourceExists_whenResourceIsUpdated_thenNoExceptions() { + // Given + final Foo existingResource = persistNewEntity(); + + // When + getApi().update(existingResource); + } + + /** + * - can also be the ConstraintViolationException which now occurs on the update operation will not be translated; as a consequence, it will be a TransactionSystemException + */ + @Test(expected = RuntimeException.class) + public void whenResourceIsUpdatedWithFailedConstraints_thenException() { + final Foo existingResource = persistNewEntity(); + invalidate(existingResource); + + getApi().update(existingResource); + } + + @Test + /**/public void givenResourceExists_whenResourceIsUpdated_thenUpdatesArePersisted() { + // Given + final Foo existingResource = persistNewEntity(); + + // When + change(existingResource); + getApi().update(existingResource); + + final Foo updatedResource = getApi().findOne(existingResource.getId()); + + // Then + assertEquals(existingResource, updatedResource); + } + + // delete + + // @Test(expected = RuntimeException.class) + // public void givenResourceDoesNotExists_whenResourceIsDeleted_thenException() { + // // When + // getApi().delete(IDUtil.randomPositiveLong()); + // } + // + // @Test(expected = RuntimeException.class) + // public void whenResourceIsDeletedByNegativeId_thenException() { + // // When + // getApi().delete(IDUtil.randomNegativeLong()); + // } + // + // @Test + // public void givenResourceExists_whenResourceIsDeleted_thenNoExceptions() { + // // Given + // final Foo existingResource = persistNewEntity(); + // + // // When + // getApi().delete(existingResource.getId()); + // } + // + // @Test + // /**/public final void givenResourceExists_whenResourceIsDeleted_thenResourceNoLongerExists() { + // // Given + // final Foo existingResource = persistNewEntity(); + // + // // When + // getApi().delete(existingResource.getId()); + // + // // Then + // assertNull(getApi().findOne(existingResource.getId())); + // } + + // template method + + protected Foo createNewEntity() { + return new Foo(randomAlphabetic(6)); + } + + protected abstract IOperations getApi(); + + private final void invalidate(final Foo entity) { + entity.setName(null); + } + + private final void change(final Foo entity) { + entity.setName(randomAlphabetic(6)); + } + + protected Foo persistNewEntity() { + return getApi().create(createNewEntity()); + } + +} diff --git a/spring-data-jpa/src/test/java/com/baeldung/services/FooServicePersistenceIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/services/FooServicePersistenceIntegrationTest.java new file mode 100644 index 0000000000..fd17d033e1 --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/services/FooServicePersistenceIntegrationTest.java @@ -0,0 +1,75 @@ +package com.baeldung.services; + +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.domain.Foo; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import static org.junit.Assert.assertNotNull; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = {PersistenceConfiguration.class}, loader = AnnotationConfigContextLoader.class) +public class FooServicePersistenceIntegrationTest extends AbstractServicePersistenceIntegrationTest { + + @Autowired + private IFooService service; + + // tests + + @Test + public final void whenContextIsBootstrapped_thenNoExceptions() { + // + } + + @Test + public final void whenEntityIsCreated_thenNoExceptions() { + service.create(new Foo(randomAlphabetic(6))); + } + + @Test(expected = DataIntegrityViolationException.class) + public final void whenInvalidEntityIsCreated_thenDataException() { + service.create(new Foo()); + } + + @Test(expected = DataIntegrityViolationException.class) + public final void whenEntityWithLongNameIsCreated_thenDataException() { + service.create(new Foo(randomAlphabetic(2048))); + } + + // custom Query method + + @Test + public final void givenUsingCustomQuery_whenRetrievingEntity_thenFound() { + final String name = randomAlphabetic(6); + service.create(new Foo(name)); + + final Foo retrievedByName = service.retrieveByName(name); + assertNotNull(retrievedByName); + } + + // work in progress + + @Test(expected = InvalidDataAccessApiUsageException.class) + @Ignore("Right now, persist has saveOrUpdate semantics, so this will no longer fail") + public final void whenSameEntityIsCreatedTwice_thenDataException() { + final Foo entity = new Foo(randomAlphabetic(8)); + service.create(entity); + service.create(entity); + } + + // API + + @Override + protected final IOperations getApi() { + return service; + } + +} diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/services/JpaMultipleDBIntegrationTest.java similarity index 63% rename from persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java rename to spring-data-jpa/src/test/java/com/baeldung/services/JpaMultipleDBIntegrationTest.java index f20af34057..71a3fb0b44 100644 --- a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java +++ b/spring-data-jpa/src/test/java/com/baeldung/services/JpaMultipleDBIntegrationTest.java @@ -1,31 +1,35 @@ -package org.baeldung.persistence.service; +package com.baeldung.services; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.Arrays; +import java.util.Collections; +import java.util.Optional; -import org.baeldung.config.ProductConfig; -import org.baeldung.config.UserConfig; -import org.baeldung.persistence.multiple.dao.product.ProductRepository; -import org.baeldung.persistence.multiple.dao.user.PossessionRepository; -import org.baeldung.persistence.multiple.dao.user.UserRepository; -import org.baeldung.persistence.multiple.model.product.Product; -import org.baeldung.persistence.multiple.model.user.Possession; -import org.baeldung.persistence.multiple.model.user.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Transactional; -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { UserConfig.class, ProductConfig.class }) +import com.baeldung.config.PersistenceProductConfiguration; +import com.baeldung.config.PersistenceUserConfiguration; +import com.baeldung.dao.repositories.product.ProductRepository; +import com.baeldung.dao.repositories.user.PossessionRepository; +import com.baeldung.dao.repositories.user.UserRepository; +import com.baeldung.domain.product.Product; +import com.baeldung.domain.user.Possession; +import com.baeldung.domain.user.User; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = { PersistenceUserConfiguration.class, PersistenceProductConfiguration.class }) @EnableTransactionManagement +@DirtiesContext public class JpaMultipleDBIntegrationTest { @Autowired @@ -48,12 +52,12 @@ public class JpaMultipleDBIntegrationTest { user.setAge(20); Possession p = new Possession("sample"); p = possessionRepository.save(p); - user.setPossessionList(Arrays.asList(p)); + user.setPossessionList(Collections.singletonList(p)); user = userRepository.save(user); - final User result = userRepository.findOne(user.getId()); - assertNotNull(result); - System.out.println(result.getPossessionList()); - assertTrue(result.getPossessionList().size() == 1); + final Optional result = userRepository.findById(user.getId()); + assertTrue(result.isPresent()); + System.out.println(result.get().getPossessionList()); + assertEquals(1, result.get().getPossessionList().size()); } @Test @@ -64,7 +68,7 @@ public class JpaMultipleDBIntegrationTest { user1.setEmail("john@test.com"); user1.setAge(20); user1 = userRepository.save(user1); - assertNotNull(userRepository.findOne(user1.getId())); + assertTrue(userRepository.findById(user1.getId()).isPresent()); User user2 = new User(); user2.setName("Tom"); @@ -90,7 +94,7 @@ public class JpaMultipleDBIntegrationTest { product.setPrice(20); product = productRepository.save(product); - assertNotNull(productRepository.findOne(product.getId())); + assertTrue(productRepository.findById(product.getId()).isPresent()); } } diff --git a/spring-data-jpa/src/test/java/com/baeldung/services/SpringDataJPABarAuditIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/services/SpringDataJPABarAuditIntegrationTest.java new file mode 100644 index 0000000000..f3b857c73d --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/services/SpringDataJPABarAuditIntegrationTest.java @@ -0,0 +1,76 @@ +package com.baeldung.services; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.domain.Bar; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = { PersistenceConfiguration.class }, loader = AnnotationConfigContextLoader.class) +public class SpringDataJPABarAuditIntegrationTest { + + private static Logger logger = LoggerFactory.getLogger(SpringDataJPABarAuditIntegrationTest.class); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + logger.info("setUpBeforeClass()"); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + logger.info("tearDownAfterClass()"); + } + + @Autowired + @Qualifier("barSpringDataJpaService") + private IBarService barService; + + @Autowired + private EntityManagerFactory entityManagerFactory; + + private EntityManager em; + + @Before + public void setUp() throws Exception { + logger.info("setUp()"); + em = entityManagerFactory.createEntityManager(); + } + + @After + public void tearDown() throws Exception { + logger.info("tearDown()"); + em.close(); + } + + @Test + @WithMockUser(username = "tutorialuser") + public final void whenBarsModified_thenBarsAudited() { + Bar bar = new Bar("BAR1"); + barService.create(bar); + assertEquals(bar.getCreatedDate(), bar.getModifiedDate()); + assertEquals("tutorialuser", bar.getCreatedBy(), bar.getModifiedBy()); + bar.setName("BAR2"); + bar = barService.update(bar); + assertTrue(bar.getCreatedDate() < bar.getModifiedDate()); + assertEquals("tutorialuser", bar.getCreatedBy(), bar.getModifiedBy()); + } +} diff --git a/spring-data-jpa/src/test/java/com/baeldung/util/IDUtil.java b/spring-data-jpa/src/test/java/com/baeldung/util/IDUtil.java new file mode 100644 index 0000000000..45e72e046d --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/util/IDUtil.java @@ -0,0 +1,33 @@ +package com.baeldung.util; + +import java.util.Random; + +public final class IDUtil { + + private IDUtil() { + throw new AssertionError(); + } + + // API + + public static String randomPositiveLongAsString() { + return Long.toString(randomPositiveLong()); + } + + public static String randomNegativeLongAsString() { + return Long.toString(randomNegativeLong()); + } + + public static long randomPositiveLong() { + long id = new Random().nextLong() * 10000; + id = (id < 0) ? (-1 * id) : id; + return id; + } + + private static long randomNegativeLong() { + long id = new Random().nextLong() * 10000; + id = (id > 0) ? (-1 * id) : id; + return id; + } + +} diff --git a/spring-data-jpa/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-data-jpa/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..0a60412813 --- /dev/null +++ b/spring-data-jpa/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,22 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.Application; +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.config.PersistenceProductConfiguration; +import com.baeldung.config.PersistenceUserConfiguration; + +@RunWith(SpringRunner.class) +@DataJpaTest(excludeAutoConfiguration = {PersistenceConfiguration.class, PersistenceUserConfiguration.class, PersistenceProductConfiguration.class}) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-data-jpa/src/test/resources/import_entities.sql b/spring-data-jpa/src/test/resources/import_entities.sql new file mode 100644 index 0000000000..deb9d07f05 --- /dev/null +++ b/spring-data-jpa/src/test/resources/import_entities.sql @@ -0,0 +1,21 @@ +insert into Article(id, publication_date, publication_time, creation_date_time) values(1, TO_DATE('01/01/2018', 'DD/MM/YYYY'), TO_DATE('15:00', 'HH24:MI'), TO_DATE('31/12/2017 07:30', 'DD/MM/YYYY HH24:MI')); +insert into Article(id, publication_date, publication_time, creation_date_time) values(2, TO_DATE('01/01/2018', 'DD/MM/YYYY'), TO_DATE('15:30', 'HH24:MI'), TO_DATE('15/12/2017 08:00', 'DD/MM/YYYY HH24:MI')); +insert into Article(id, publication_date, publication_time, creation_date_time) values(3, TO_DATE('15/12/2017', 'DD/MM/YYYY'), TO_DATE('16:00', 'HH24:MI'), TO_DATE('01/12/2017 13:45', 'DD/MM/YYYY HH24:MI')); + +insert into location (id, country, city) values (1, 'Country X', 'City One'); +insert into location (id, country, city) values (2, 'Country X', 'City Two'); +insert into location (id, country, city) values (3, 'Country X', 'City Three'); + +insert into store (id, name, location_id, items_sold, active) values (1, 'Store One', 3, 130000, true); +insert into store (id, name, location_id, items_sold, active) values (2, 'Store Two', 1, 170000, false); + +insert into item_type (id, name) values (1, 'Food'); +insert into item_type (id, name) values (2, 'Furniture'); +insert into item_type (id, name) values (3, 'Electronics'); + +insert into item (id, name, store_id, item_type_id, price, grade, color) values (1, 'Food Item One', 1, 1, 100, 'A', 'Color x'); +insert into item (id, name, store_id, item_type_id, price, grade, color) values (2, 'Furniture Item One', 1, 2, 2500, 'B', 'Color y'); +insert into item (id, name, store_id, item_type_id, price, grade, color) values (3, 'Food Item Two', 1, 1, 35, 'A', 'Color z'); +insert into item (id, name, store_id, item_type_id, price, grade, color) values (5, 'Furniture Item Two', 2, 2, 1600, 'A', 'Color w'); +insert into item (id, name, store_id, item_type_id, price, grade, color) values (6, 'Food Item Three', 2, 1, 5, 'B', 'Color a'); +insert into item (id, name, store_id, item_type_id, price, grade, color) values (7, 'Electronics Item One', 2, 3, 999, 'B', 'Color b'); diff --git a/spring-data-keyvalue/pom.xml b/spring-data-keyvalue/pom.xml index e90f18948f..edd8967b97 100644 --- a/spring-data-keyvalue/pom.xml +++ b/spring-data-keyvalue/pom.xml @@ -1,37 +1,30 @@ - 4.0.0 - com.baeldung - spring-data-keyvalue - 1.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + spring-data-keyvalue - - org.springframework.boot - spring-boot-starter-parent - 2.0.1.RELEASE - - + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + - - 2.0.3.RELEASE - + + + org.springframework.boot + spring-boot-starter + - + + org.springframework.data + spring-data-keyvalue + - - org.springframework.boot - spring-boot-starter - - - - org.springframework.data - spring-data-keyvalue - - - - org.springframework.boot - spring-boot-starter-test - - + + org.springframework.boot + spring-boot-starter-test + + \ No newline at end of file diff --git a/spring-data-keyvalue/src/main/resources/logback.xml b/spring-data-keyvalue/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-data-keyvalue/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-data-keyvalue/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-data-keyvalue/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..d28bdcbc89 --- /dev/null +++ b/spring-data-keyvalue/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.data.keyvalue.SpringDataKeyValueApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringDataKeyValueApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index c3d1f74b4b..072ed7a2ac 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -1,5 +1,5 @@ + 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 spring-data-mongodb @@ -8,9 +8,9 @@ com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 @@ -19,6 +19,34 @@ spring-data-mongodb ${org.springframework.data.version} + + + org.springframework.data + spring-data-releasetrain + Lovelace-M3 + pom + import + + + + org.mongodb + mongodb-driver-reactivestreams + ${mongodb-reactivestreams.version} + + + + io.projectreactor + reactor-core + ${projectreactor.version} + + + + io.projectreactor + reactor-test + ${projectreactor.version} + test + + org.springframework spring-core @@ -48,6 +76,17 @@ + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + @@ -70,11 +109,13 @@ - UTF-8 - 1.10.4.RELEASE - 2.9.0 + 2.1.0.RELEASE 4.1.4 1.1.3 + 5.1.0.RELEASE + 1.9.2 + 3.2.0.RELEASE + diff --git a/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java index 551a9142a6..f1048fa145 100644 --- a/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java +++ b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java @@ -1,21 +1,23 @@ package com.baeldung.config; -import com.mongodb.Mongo; -import com.mongodb.MongoClient; -import com.baeldung.converter.UserWriterConverter; -import com.baeldung.event.CascadeSaveMongoEventListener; -import com.baeldung.event.UserCascadeSaveMongoEventListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.convert.converter.Converter; -import org.springframework.data.mongodb.config.AbstractMongoConfiguration; -import org.springframework.data.mongodb.core.convert.CustomConversions; -import org.springframework.data.mongodb.gridfs.GridFsTemplate; -import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; - import java.util.ArrayList; import java.util.List; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.MongoTransactionManager; +import org.springframework.data.mongodb.config.AbstractMongoConfiguration; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; +import org.springframework.data.mongodb.gridfs.GridFsTemplate; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +import com.baeldung.converter.UserWriterConverter; +import com.baeldung.event.CascadeSaveMongoEventListener; +import com.baeldung.event.UserCascadeSaveMongoEventListener; +import com.mongodb.MongoClient; + @Configuration @EnableMongoRepositories(basePackages = "com.baeldung.repository") public class MongoConfig extends AbstractMongoConfiguration { @@ -28,7 +30,7 @@ public class MongoConfig extends AbstractMongoConfiguration { } @Override - public Mongo mongo() throws Exception { + public MongoClient mongoClient() { return new MongoClient("127.0.0.1", 27017); } @@ -48,13 +50,19 @@ public class MongoConfig extends AbstractMongoConfiguration { } @Override - public CustomConversions customConversions() { + public MongoCustomConversions customConversions() { converters.add(new UserWriterConverter()); - return new CustomConversions(converters); + return new MongoCustomConversions(converters); } @Bean public GridFsTemplate gridFsTemplate() throws Exception { return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter()); } + + @Bean + MongoTransactionManager transactionManager(MongoDbFactory dbFactory) { + return new MongoTransactionManager(dbFactory); + } + } diff --git a/spring-data-mongodb/src/main/java/com/baeldung/config/MongoReactiveConfig.java b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoReactiveConfig.java new file mode 100644 index 0000000000..b4042b5550 --- /dev/null +++ b/spring-data-mongodb/src/main/java/com/baeldung/config/MongoReactiveConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration; +import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; + +import com.mongodb.reactivestreams.client.MongoClient; +import com.mongodb.reactivestreams.client.MongoClients; + +@Configuration +@EnableReactiveMongoRepositories(basePackages = "com.baeldung.reactive.repository") +public class MongoReactiveConfig extends AbstractReactiveMongoConfiguration { + + @Override + public MongoClient reactiveMongoClient() { + return MongoClients.create(); + } + + @Override + protected String getDatabaseName() { + return "reactive"; + } +} diff --git a/spring-data-mongodb/src/main/java/com/baeldung/config/SimpleMongoConfig.java b/spring-data-mongodb/src/main/java/com/baeldung/config/SimpleMongoConfig.java index 95f192811f..c3ddad5a82 100644 --- a/spring-data-mongodb/src/main/java/com/baeldung/config/SimpleMongoConfig.java +++ b/spring-data-mongodb/src/main/java/com/baeldung/config/SimpleMongoConfig.java @@ -1,18 +1,18 @@ package com.baeldung.config; -import com.mongodb.Mongo; -import com.mongodb.MongoClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import com.mongodb.MongoClient; + @Configuration @EnableMongoRepositories(basePackages = "com.baeldung.repository") public class SimpleMongoConfig { @Bean - public Mongo mongo() throws Exception { + public MongoClient mongo() throws Exception { return new MongoClient("localhost"); } diff --git a/spring-data-mongodb/src/main/java/com/baeldung/reactive/repository/UserRepository.java b/spring-data-mongodb/src/main/java/com/baeldung/reactive/repository/UserRepository.java new file mode 100644 index 0000000000..7e754aa680 --- /dev/null +++ b/spring-data-mongodb/src/main/java/com/baeldung/reactive/repository/UserRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.reactive.repository; + +import org.springframework.data.mongodb.repository.ReactiveMongoRepository; + +import com.baeldung.model.User; + + +public interface UserRepository extends ReactiveMongoRepository { +} diff --git a/spring-data-mongodb/src/main/java/com/baeldung/repository/UserRepository.java b/spring-data-mongodb/src/main/java/com/baeldung/repository/UserRepository.java index e9dc0f5c95..4c69d7f9c6 100644 --- a/spring-data-mongodb/src/main/java/com/baeldung/repository/UserRepository.java +++ b/spring-data-mongodb/src/main/java/com/baeldung/repository/UserRepository.java @@ -1,13 +1,14 @@ package com.baeldung.repository; -import com.baeldung.model.User; -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.data.mongodb.repository.Query; -import org.springframework.data.querydsl.QueryDslPredicateExecutor; - import java.util.List; -public interface UserRepository extends MongoRepository, QueryDslPredicateExecutor { +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; + +import com.baeldung.model.User; + +public interface UserRepository extends MongoRepository, QuerydslPredicateExecutor { @Query("{ 'name' : ?0 }") List findUsersByName(String name); diff --git a/spring-data-mongodb/src/main/resources/logback.xml b/spring-data-mongodb/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-data-mongodb/src/main/resources/logback.xml +++ b/spring-data-mongodb/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-data-mongodb/src/main/resources/mongoConfig.xml b/spring-data-mongodb/src/main/resources/mongoConfig.xml index 2b32863fb6..324f7f60c2 100644 --- a/spring-data-mongodb/src/main/resources/mongoConfig.xml +++ b/spring-data-mongodb/src/main/resources/mongoConfig.xml @@ -3,17 +3,17 @@ xmlns:p="http://www.springframework.org/schema/p" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.2.xsd + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/mongo - http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd + http://www.springframework.org/schema/data/mongo/spring-mongo.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-3.2.xsd" + http://www.springframework.org/schema/context/spring-context.xsd" > - + - + @@ -27,12 +27,12 @@ - + - + - + diff --git a/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java index a4bea45fcf..1da50d7cb4 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/aggregation/ZipsAggregationLiveTest.java @@ -1,12 +1,24 @@ package com.baeldung.aggregation; -import com.mongodb.DB; -import com.mongodb.DBCollection; -import com.mongodb.DBObject; -import com.mongodb.MongoClient; -import com.mongodb.util.JSON; -import com.baeldung.aggregation.model.StatePopulation; -import com.baeldung.config.MongoConfig; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.group; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.limit; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.match; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.project; +import static org.springframework.data.mongodb.core.aggregation.Aggregation.sort; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import org.bson.Document; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -26,23 +38,11 @@ import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.group; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.limit; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.match; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.project; -import static org.springframework.data.mongodb.core.aggregation.Aggregation.sort; +import com.baeldung.aggregation.model.StatePopulation; +import com.baeldung.config.MongoConfig; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) @@ -56,23 +56,22 @@ public class ZipsAggregationLiveTest { @BeforeClass public static void setupTests() throws Exception { client = new MongoClient(); - DB testDB = client.getDB("test"); - DBCollection zipsCollection = testDB.getCollection("zips"); + MongoDatabase testDB = client.getDatabase("test"); + MongoCollection zipsCollection = testDB.getCollection("zips"); zipsCollection.drop(); InputStream zipsJsonStream = ZipsAggregationLiveTest.class.getResourceAsStream("/zips.json"); BufferedReader reader = new BufferedReader(new InputStreamReader(zipsJsonStream)); reader.lines() - .forEach(line -> zipsCollection.insert((DBObject) JSON.parse(line))); + .forEach(line -> zipsCollection.insertOne(Document.parse(line))); reader.close(); - } @AfterClass public static void tearDown() throws Exception { client = new MongoClient(); - DB testDB = client.getDB("test"); - DBCollection zipsCollection = testDB.getCollection("zips"); + MongoDatabase testDB = client.getDatabase("test"); + MongoCollection zipsCollection = testDB.getCollection("zips"); zipsCollection.drop(); client.close(); } @@ -140,13 +139,13 @@ public class ZipsAggregationLiveTest { Aggregation aggregation = newAggregation(sumZips, sortByCount, groupFirstAndLast); - AggregationResults result = mongoTemplate.aggregate(aggregation, "zips", DBObject.class); - DBObject dbObject = result.getUniqueMappedResult(); + AggregationResults result = mongoTemplate.aggregate(aggregation, "zips", Document.class); + Document document = result.getUniqueMappedResult(); - assertEquals("DC", dbObject.get("minZipState")); - assertEquals(24, dbObject.get("minZipCount")); - assertEquals("TX", dbObject.get("maxZipState")); - assertEquals(1671, dbObject.get("maxZipCount")); + assertEquals("DC", document.get("minZipState")); + assertEquals(24, document.get("minZipCount")); + assertEquals("TX", document.get("maxZipState")); + assertEquals(1671, document.get("maxZipCount")); } } diff --git a/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java index 02485e8517..3a88a1e654 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java @@ -1,8 +1,19 @@ package com.baeldung.gridfs; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; -import com.mongodb.gridfs.GridFSDBFile; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.bson.types.ObjectId; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -16,18 +27,9 @@ import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.client.gridfs.model.GridFSFile; @ContextConfiguration("file:src/main/resources/mongoConfig.xml") @RunWith(SpringJUnit4ClassRunner.class) @@ -40,8 +42,9 @@ public class GridFSLiveTest { @After public void tearDown() { - List fileList = gridFsTemplate.find(null); - for (GridFSDBFile file : fileList) { + List fileList = new ArrayList(); + gridFsTemplate.find(new Query()).into(fileList); + for (GridFSFile file : fileList) { gridFsTemplate.delete(new Query(Criteria.where("filename").is(file.getFilename()))); } } @@ -54,7 +57,7 @@ public class GridFSLiveTest { String id = ""; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).getId().toString(); + id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString(); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { @@ -75,10 +78,10 @@ public class GridFSLiveTest { DBObject metaData = new BasicDBObject(); metaData.put("user", "alex"); InputStream inputStream = null; - String id = ""; + ObjectId id = null; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).getId().toString(); + id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { @@ -91,22 +94,22 @@ public class GridFSLiveTest { } } - GridFSDBFile gridFSDBFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id))); + GridFSFile gridFSFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id))); - assertNotNull(gridFSDBFile); - assertNotNull(gridFSDBFile.getInputStream()); - assertThat(gridFSDBFile.numChunks(), is(1)); - assertThat(gridFSDBFile.containsField("filename"), is(true)); - assertThat(gridFSDBFile.get("filename"), is("test.png")); - assertThat(gridFSDBFile.getId(), is(id)); - assertThat(gridFSDBFile.keySet().size(), is(9)); - assertNotNull(gridFSDBFile.getMD5()); - assertNotNull(gridFSDBFile.getUploadDate()); - assertNull(gridFSDBFile.getAliases()); - assertNotNull(gridFSDBFile.getChunkSize()); - assertThat(gridFSDBFile.getContentType(), is("image/png")); - assertThat(gridFSDBFile.getFilename(), is("test.png")); - assertThat(gridFSDBFile.getMetaData().get("user"), is("alex")); + assertNotNull(gridFSFile); +// assertNotNull(gridFSFile.getInputStream()); +// assertThat(gridFSFile.numChunks(), is(1)); +// assertThat(gridFSFile.containsField("filename"), is(true)); + assertThat(gridFSFile.getFilename(), is("test.png")); + assertThat(gridFSFile.getObjectId(), is(id)); +// assertThat(gridFSFile.keySet().size(), is(9)); +// assertNotNull(gridFSFile.getMD5()); + assertNotNull(gridFSFile.getUploadDate()); +// assertNull(gridFSFile.getAliases()); + assertNotNull(gridFSFile.getChunkSize()); + assertThat(gridFSFile.getMetadata().get("_contentType"), is("image/png")); + assertThat(gridFSFile.getFilename(), is("test.png")); + assertThat(gridFSFile.getMetadata().get("user"), is("alex")); } @Test @@ -133,10 +136,11 @@ public class GridFSLiveTest { } } - List gridFSDBFiles = gridFsTemplate.find(null); + List gridFSFiles = new ArrayList(); + gridFsTemplate.find(new Query()).into(gridFSFiles); - assertNotNull(gridFSDBFiles); - assertThat(gridFSDBFiles.size(), is(2)); + assertNotNull(gridFSFiles); + assertThat(gridFSFiles.size(), is(2)); } @Test @@ -163,10 +167,11 @@ public class GridFSLiveTest { } } - List gridFSDBFiles = gridFsTemplate.find(new Query(Criteria.where("metadata.user").is("alex"))); + List gridFSFiles = new ArrayList(); + gridFsTemplate.find(new Query(Criteria.where("metadata.user").is("alex"))).into(gridFSFiles); - assertNotNull(gridFSDBFiles); - assertThat(gridFSDBFiles.size(), is(1)); + assertNotNull(gridFSFiles); + assertThat(gridFSFiles.size(), is(1)); } @Test @@ -177,7 +182,7 @@ public class GridFSLiveTest { String id = ""; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).getId().toString(); + id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString(); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { @@ -200,10 +205,9 @@ public class GridFSLiveTest { DBObject metaData = new BasicDBObject(); metaData.put("user", "alex"); InputStream inputStream = null; - String id = ""; try { inputStream = new FileInputStream("src/main/resources/test.png"); - id = gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).getId().toString(); + gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString(); } catch (FileNotFoundException ex) { logger.error("File not found", ex); } finally { diff --git a/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/DocumentQueryLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/DocumentQueryLiveTest.java index 7a61f9f98a..d05bde0f1b 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/DocumentQueryLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/DocumentQueryLiveTest.java @@ -1,8 +1,11 @@ package com.baeldung.mongotemplate; -import com.baeldung.config.MongoConfig; -import com.baeldung.model.EmailAddress; -import com.baeldung.model.User; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Iterator; +import java.util.List; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -17,11 +20,9 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.Iterator; -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import com.baeldung.config.MongoConfig; +import com.baeldung.model.EmailAddress; +import com.baeldung.model.User; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) @@ -152,7 +153,7 @@ public class DocumentQueryLiveTest { user.setAge(35); mongoTemplate.insert(user); - final Pageable pageableRequest = new PageRequest(0, 2); + final Pageable pageableRequest = PageRequest.of(0, 2); Query query = new Query(); query.with(pageableRequest); diff --git a/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java index ee1d4f4760..fc78921b75 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/mongotemplate/MongoTemplateQueryLiveTest.java @@ -1,8 +1,11 @@ package com.baeldung.mongotemplate; -import com.baeldung.config.MongoConfig; -import com.baeldung.model.EmailAddress; -import com.baeldung.model.User; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +import java.util.List; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -20,11 +23,9 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; +import com.baeldung.config.MongoConfig; +import com.baeldung.model.EmailAddress; +import com.baeldung.model.User; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) @@ -104,7 +105,7 @@ public class MongoTemplateQueryLiveTest { user.setAge(35); mongoTemplate.insert(user); - final Pageable pageableRequest = new PageRequest(0, 2); + final Pageable pageableRequest = PageRequest.of(0, 2); Query query = new Query(); query.with(pageableRequest); diff --git a/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java b/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java index da4e91baec..901610e42d 100644 --- a/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java +++ b/spring-data-mongodb/src/test/java/com/baeldung/repository/UserRepositoryLiveTest.java @@ -5,8 +5,6 @@ import static org.junit.Assert.assertThat; import java.util.List; -import com.baeldung.config.MongoConfig; -import com.baeldung.model.User; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -22,6 +20,9 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import com.baeldung.config.MongoConfig; +import com.baeldung.model.User; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MongoConfig.class) public class UserRepositoryLiveTest { @@ -72,8 +73,7 @@ public class UserRepositoryLiveTest { user.setName("Jim"); userRepository.save(user); - - assertThat(mongoOps.findAll(User.class).size(), is(2)); + assertThat(mongoOps.findAll(User.class).size(), is(1)); } @Test @@ -94,7 +94,7 @@ public class UserRepositoryLiveTest { mongoOps.insert(user); user = mongoOps.findOne(Query.query(Criteria.where("name").is("Chris")), User.class); - final User foundUser = userRepository.findOne(user.getId()); + final User foundUser = userRepository.findById(user.getId()).get(); assertThat(user.getName(), is(foundUser.getName())); } @@ -106,7 +106,7 @@ public class UserRepositoryLiveTest { mongoOps.insert(user); user = mongoOps.findOne(Query.query(Criteria.where("name").is("Harris")), User.class); - final boolean isExists = userRepository.exists(user.getId()); + final boolean isExists = userRepository.existsById(user.getId()); assertThat(isExists, is(true)); } @@ -138,7 +138,7 @@ public class UserRepositoryLiveTest { user.setName("Adam"); mongoOps.insert(user); - final Pageable pageableRequest = new PageRequest(0, 1); + final Pageable pageableRequest = PageRequest.of(0, 1); final Page page = userRepository.findAll(pageableRequest); List users = page.getContent(); diff --git a/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionReactiveIntegrationTest.java b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionReactiveIntegrationTest.java new file mode 100644 index 0000000000..43aa865e91 --- /dev/null +++ b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionReactiveIntegrationTest.java @@ -0,0 +1,47 @@ +package com.baeldung.transaction; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.config.MongoReactiveConfig; +import com.baeldung.model.User; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MongoReactiveConfig.class) +public class MongoTransactionReactiveIntegrationTest { + + @Autowired + private ReactiveMongoOperations reactiveOps; + + @Before + public void testSetup() { + if (!reactiveOps.collectionExists(User.class) + .block()) { + reactiveOps.createCollection(User.class); + } + } + + @After + public void tearDown() { + System.out.println(reactiveOps.findAll(User.class) + .count() + .block()); + reactiveOps.dropCollection(User.class); + } + + @Test + public void whenPerformTransaction_thenSuccess() { + User user1 = new User("Jane", 23); + User user2 = new User("John", 34); + reactiveOps.inTransaction() + .execute(action -> action.insert(user1) + .then(action.insert(user2))); + } + +} diff --git a/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionTemplateIntegrationTest.java b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionTemplateIntegrationTest.java new file mode 100644 index 0000000000..1dbe724d87 --- /dev/null +++ b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionTemplateIntegrationTest.java @@ -0,0 +1,68 @@ +package com.baeldung.transaction; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.MongoTransactionManager; +import org.springframework.data.mongodb.SessionSynchronization; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; + +import com.baeldung.config.MongoConfig; +import com.baeldung.model.User; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MongoConfig.class) +public class MongoTransactionTemplateIntegrationTest { + + @Autowired + private MongoTemplate mongoTemplate; + + @Autowired + private MongoTransactionManager mongoTransactionManager; + + @Before + public void testSetup() { + if (!mongoTemplate.collectionExists(User.class)) { + mongoTemplate.createCollection(User.class); + } + } + + @After + public void tearDown() { + mongoTemplate.dropCollection(User.class); + } + + @Test + public void givenTransactionTemplate_whenPerformTransaction_thenSuccess() { + mongoTemplate.setSessionSynchronization(SessionSynchronization.ALWAYS); + TransactionTemplate transactionTemplate = new TransactionTemplate(mongoTransactionManager); + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + mongoTemplate.insert(new User("Kim", 20)); + mongoTemplate.insert(new User("Jack", 45)); + }; + }); + + Query query = new Query().addCriteria(Criteria.where("name") + .is("Jack")); + List users = mongoTemplate.find(query, User.class); + + assertThat(users.size(), is(1)); + } + +} diff --git a/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalIntegrationTest.java b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalIntegrationTest.java new file mode 100644 index 0000000000..4d747789a0 --- /dev/null +++ b/spring-data-mongodb/src/test/java/com/baeldung/transaction/MongoTransactionalIntegrationTest.java @@ -0,0 +1,90 @@ +package com.baeldung.transaction; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.MongoTransactionException; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import com.baeldung.config.MongoConfig; +import com.baeldung.model.User; +import com.baeldung.repository.UserRepository; +import com.mongodb.MongoCommandException; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MongoConfig.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class MongoTransactionalIntegrationTest { + + @Autowired + private MongoTemplate mongoTemplate; + + @Autowired + private UserRepository userRepository; + + @Test + @Transactional + public void whenPerformMongoTransaction_thenSuccess() { + userRepository.save(new User("John", 30)); + userRepository.save(new User("Ringo", 35)); + Query query = new Query().addCriteria(Criteria.where("name") + .is("John")); + List users = mongoTemplate.find(query, User.class); + + assertThat(users.size(), is(1)); + } + + @Test(expected = MongoTransactionException.class) + @Transactional + public void whenListCollectionDuringMongoTransaction_thenException() { + if (mongoTemplate.collectionExists(User.class)) { + mongoTemplate.save(new User("John", 30)); + mongoTemplate.save(new User("Ringo", 35)); + } + } + + @Test(expected = MongoCommandException.class) + @Transactional + public void whenCountDuringMongoTransaction_thenException() { + userRepository.save(new User("John", 30)); + userRepository.save(new User("Ringo", 35)); + userRepository.count(); + } + + @Test + @Transactional + public void whenQueryDuringMongoTransaction_thenSuccess() { + userRepository.save(new User("Jane", 20)); + userRepository.save(new User("Nick", 33)); + List users = mongoTemplate.find(new Query(), User.class); + + assertTrue(users.size() > 1); + } + + // ==== Using test instead of before and after due to @transactional doesn't allow list collection + + @Test + public void setup() { + if (!mongoTemplate.collectionExists(User.class)) { + mongoTemplate.createCollection(User.class); + } + } + + @Test + public void ztearDown() { + mongoTemplate.dropCollection(User.class); + } +} diff --git a/spring-data-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-data-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..04d549a288 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.config.MongoConfig; +import com.baeldung.config.SimpleMongoConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { MongoConfig.class, SimpleMongoConfig.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-data-rest-querydsl/pom.xml b/spring-data-rest-querydsl/pom.xml index e4832e1552..55ff78f0cb 100644 --- a/spring-data-rest-querydsl/pom.xml +++ b/spring-data-rest-querydsl/pom.xml @@ -1,18 +1,17 @@ + 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 spring-data-rest-querydsl 1.0 - spring-data-rest-querydsl - org.springframework.boot - spring-boot-starter-parent - 1.5.9.RELEASE + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 @@ -46,6 +45,7 @@ test + @@ -94,8 +94,5 @@ -<<<<<<< HEAD + -======= - ->>>>>>> 19a1633c35d6d49f9c51b8ecc3dbe127c91d75c3 diff --git a/spring-data-rest-querydsl/src/main/resources/logback.xml b/spring-data-rest-querydsl/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-data-rest-querydsl/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7f906bdbcd --- /dev/null +++ b/spring-data-rest-querydsl/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-data-rest/pom.xml b/spring-data-rest/pom.xml index b3d2b0e359..a756ef0497 100644 --- a/spring-data-rest/pom.xml +++ b/spring-data-rest/pom.xml @@ -1,12 +1,12 @@ + 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 spring-data-rest 1.0 jar - intro-spring-data-rest + spring-data-rest Intro to Spring Data REST @@ -33,11 +33,9 @@ com.h2database h2 - + diff --git a/spring-data-rest/src/main/resources/logback.xml b/spring-data-rest/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-data-rest/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java similarity index 98% rename from spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java rename to spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java index 2b1f6d4d4f..702c1521da 100644 --- a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java @@ -25,7 +25,7 @@ import com.baeldung.repositories.BookRepository; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) -public class SpringDataProjectionIntegrationTest { +public class SpringDataProjectionLiveTest { private static final String BOOK_ENDPOINT = "http://localhost:8080/books"; private static final String AUTHOR_ENDPOINT = "http://localhost:8080/authors"; diff --git a/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java deleted file mode 100644 index e3fe60d487..0000000000 --- a/spring-data-rest/src/test/java/com/baeldung/relationships/SpringDataRelationshipsIntegrationTest.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.baeldung.relationships; - -import com.baeldung.SpringDataRestApplication; -import com.baeldung.models.Address; -import com.baeldung.models.Author; -import com.baeldung.models.Book; -import com.baeldung.models.Library; -import org.json.JSONArray; -import org.json.JSONObject; -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.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; -import org.json.JSONException; - -import static org.junit.Assert.assertEquals; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) -public class SpringDataRelationshipsIntegrationTest { - - @Autowired - private TestRestTemplate template; - - private static final String BOOK_ENDPOINT = "http://localhost:8080/books/"; - private static final String AUTHOR_ENDPOINT = "http://localhost:8080/authors/"; - private static final String ADDRESS_ENDPOINT = "http://localhost:8080/addresses/"; - private static final String LIBRARY_ENDPOINT = "http://localhost:8080/libraries/"; - - private static final String LIBRARY_NAME = "My Library"; - private static final String AUTHOR_NAME = "George Orwell"; - - @Test - public void whenSaveOneToOneRelationship_thenCorrect() throws JSONException { - Library library = new Library(LIBRARY_NAME); - template.postForEntity(LIBRARY_ENDPOINT, library, Library.class); - - Address address = new Address("Main street, nr 1"); - template.postForEntity(ADDRESS_ENDPOINT, address, Address.class); - - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity httpEntity = new HttpEntity<>(ADDRESS_ENDPOINT + "/1", requestHeaders); - template.exchange(LIBRARY_ENDPOINT + "/1/libraryAddress", HttpMethod.PUT, httpEntity, String.class); - - ResponseEntity libraryGetResponse = template.getForEntity(ADDRESS_ENDPOINT + "/1/library", Library.class); - assertEquals("library is incorrect", libraryGetResponse.getBody() - .getName(), LIBRARY_NAME); - } - - @Test - public void whenSaveOneToManyRelationship_thenCorrect() throws JSONException{ - Library library = new Library(LIBRARY_NAME); - template.postForEntity(LIBRARY_ENDPOINT, library, Library.class); - - Book book1 = new Book("Dune"); - template.postForEntity(BOOK_ENDPOINT, book1, Book.class); - - Book book2 = new Book("1984"); - template.postForEntity(BOOK_ENDPOINT, book2, Book.class); - - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity bookHttpEntity = new HttpEntity<>(LIBRARY_ENDPOINT + "/1", requestHeaders); - template.exchange(BOOK_ENDPOINT + "/1/library", HttpMethod.PUT, bookHttpEntity, String.class); - template.exchange(BOOK_ENDPOINT + "/2/library", HttpMethod.PUT, bookHttpEntity, String.class); - - ResponseEntity libraryGetResponse = template.getForEntity(BOOK_ENDPOINT + "/1/library", Library.class); - assertEquals("library is incorrect", libraryGetResponse.getBody() - .getName(), LIBRARY_NAME); - } - - @Test - public void whenSaveManyToManyRelationship_thenCorrect() throws JSONException{ - Author author1 = new Author(AUTHOR_NAME); - template.postForEntity(AUTHOR_ENDPOINT, author1, Author.class); - - Book book1 = new Book("Animal Farm"); - template.postForEntity(BOOK_ENDPOINT, book1, Book.class); - - Book book2 = new Book("1984"); - template.postForEntity(BOOK_ENDPOINT, book2, Book.class); - - HttpHeaders requestHeaders = new HttpHeaders(); - requestHeaders.add("Content-type", "text/uri-list"); - HttpEntity httpEntity = new HttpEntity<>(BOOK_ENDPOINT + "/1\n" + BOOK_ENDPOINT + "/2", requestHeaders); - template.exchange(AUTHOR_ENDPOINT + "/1/books", HttpMethod.PUT, httpEntity, String.class); - - String jsonResponse = template.getForObject(BOOK_ENDPOINT + "/1/authors", String.class); - JSONObject jsonObj = new JSONObject(jsonResponse).getJSONObject("_embedded"); - JSONArray jsonArray = jsonObj.getJSONArray("authors"); - assertEquals("author is incorrect", jsonArray.getJSONObject(0) - .getString("name"), AUTHOR_NAME); - } -} diff --git a/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java index bc321bc686..4c936ffc1c 100644 --- a/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java @@ -1,31 +1,33 @@ package com.baeldung.validator; -import com.baeldung.SpringDataRestApplication; -import com.baeldung.models.WebsiteUser; -import com.fasterxml.jackson.databind.ObjectMapper; -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.web.context.WebApplicationContext; - import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; +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.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.web.context.WebApplicationContext; + +import com.baeldung.SpringDataRestApplication; +import com.baeldung.models.WebsiteUser; +import com.fasterxml.jackson.databind.ObjectMapper; + @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = SpringDataRestApplication.class) -@WebAppConfiguration +@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK) +@AutoConfigureMockMvc public class SpringDataRestValidatorIntegrationTest { public static final String URL = "http://localhost"; + @Autowired private MockMvc mockMvc; @Autowired diff --git a/spring-data-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-data-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..0380e3dc2f --- /dev/null +++ b/spring-data-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.SpringDataRestApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringDataRestApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-data-spring-security/README.md b/spring-data-spring-security/README.md deleted file mode 100644 index da65527a8a..0000000000 --- a/spring-data-spring-security/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# About this project -This project contains examples from the [Spring Data with Spring Security](http://www.baeldung.com/spring-data-with-spring-security) article from Baeldung. - -# Running the project -The application uses [Spring Boot](http://projects.spring.io/spring-boot/), so it is easy to run. You can start it any of a few ways: -* Run the `main` method from `SpringDataRestApplication` -* Use the Maven Spring Boot plugin: `mvn spring-boot:run` -* Package the application as a JAR and run it using `java -jar spring-data-spring-security.jar` - -# Viewing the running application -To view the running application, visit [http://localhost:8080](http://localhost:8080) in your browser - -###Relevant Articles: -- [Spring Data with Spring Security](http://www.baeldung.com/spring-data-security) diff --git a/spring-data-spring-security/pom.xml b/spring-data-spring-security/pom.xml deleted file mode 100644 index 467c38284d..0000000000 --- a/spring-data-spring-security/pom.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - 4.0.0 - - com.baeldung - spring-data-spring-security - 1.0 - jar - intro-spring-data-spring-security - Spring Data with Spring Security - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-1 - - - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.security - spring-security-data - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.security - spring-security-test - test - - - org.apache.tomcat.embed - tomcat-embed-jasper - - - - com.h2database - h2 - - - javax.servlet - jstl - - - - - ${project.artifactId} - - - diff --git a/spring-dispatcher-servlet/pom.xml b/spring-dispatcher-servlet/pom.xml index 35c6b1ad33..7ac291740e 100644 --- a/spring-dispatcher-servlet/pom.xml +++ b/spring-dispatcher-servlet/pom.xml @@ -1,97 +1,102 @@ - - 4.0.0 - com.baeldung - spring-dispatcher-servlet - war - 1.0.0 - spring-dispatcher-servlet + + 4.0.0 + com.baeldung + spring-dispatcher-servlet + war + 1.0.0 + spring-dispatcher-servlet - - com.baeldung - parent-spring-5 - 0.0.1-SNAPSHOT - ../parent-spring-5 - + + com.baeldung + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 + - - - org.springframework - spring-web - ${spring.version} + + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + + + javax.servlet.jsp.jstl + jstl-api + ${jstl-api.version} + + + javax.servlet.jsp + javax.servlet.jsp-api + ${javax.servlet.jsp-api.version} + + + org.codehaus.jackson + jackson-mapper-asl + ${jackson-mapper-asl.version} + + + javax.servlet + jstl + ${jstl.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test - - org.springframework - spring-webmvc - ${spring.version} - - - javax.servlet - javax.servlet-api - ${javax.servlet-api.version} - - - javax.servlet.jsp.jstl - jstl-api - ${jstl-api.version} - - - javax.servlet.jsp - javax.servlet.jsp-api - ${javax.servlet.jsp-api.version} - - - org.codehaus.jackson - jackson-mapper-asl - ${jackson-mapper-asl.version} - - - javax.servlet - jstl - ${jstl.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson-databind.version} - - - commons-fileupload - commons-fileupload - ${commons-fileupload.version} - - + - - spring-dispatcher-servlet - - - - org.apache.tomcat.maven - tomcat8-maven-plugin - ${tomcat8-maven-plugin.version} - - /springdispatcherservlet - - - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - src/main/webapp - false - - - - - + + spring-dispatcher-servlet + + + + org.apache.tomcat.maven + tomcat8-maven-plugin + ${tomcat8-maven-plugin.version} + + /springdispatcherservlet + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + src/main/webapp + false + + + + + - - 3.0-r1655215 - 3.0.0 - + + 3.0-r1655215 + 3.0.0 + \ No newline at end of file diff --git a/spring-dispatcher-servlet/src/main/resources/logback.xml b/spring-dispatcher-servlet/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-dispatcher-servlet/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-dispatcher-servlet/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-dispatcher-servlet/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..8a9d3421c2 --- /dev/null +++ b/spring-dispatcher-servlet/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.springdispatcherservlet.configuration.AppConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = AppConfig.class) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-drools/pom.xml b/spring-drools/pom.xml index 9df43a89ad..8c65d5e34e 100644 --- a/spring-drools/pom.xml +++ b/spring-drools/pom.xml @@ -1,6 +1,6 @@ + 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 spring-drools @@ -34,7 +34,7 @@ drools-compiler ${drools-version} - + org.kie kie-spring diff --git a/spring-drools/src/main/resources/logback.xml b/spring-drools/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-drools/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-drools/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-drools/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..68325682e5 --- /dev/null +++ b/spring-drools/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.drools.service.TaxiFareConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = TaxiFareConfiguration.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml index 0ce390b6ac..76c0afadee 100644 --- a/spring-ejb/ejb-beans/pom.xml +++ b/spring-ejb/ejb-beans/pom.xml @@ -1,44 +1,35 @@ + 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.singletonsession - singleton-ejb-bean + ejb-beans 1.0.0-SNAPSHOT - EJB Singleton Session Bean + EJB Beans + com.baeldung.spring.ejb - ejb-for-spring + spring-ejb 1.0.1 - - UTF-8 - - javax javaee-api - 8.0 + ${javaee.version} provided - org.apache.openejb tomee-embedded - 1.7.5 + ${tomee-embedded.version} - - - - junit - junit - 4.12 - test - - + + 1.7.5 + + diff --git a/spring-ejb/ejb-beans/src/main/resources/logback.xml b/spring-ejb/ejb-beans/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-ejb/ejb-beans/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-ejb/ejb-remote-for-spring/pom.xml b/spring-ejb/ejb-remote-for-spring/pom.xml index 92f9dbf16c..21256fa801 100755 --- a/spring-ejb/ejb-remote-for-spring/pom.xml +++ b/spring-ejb/ejb-remote-for-spring/pom.xml @@ -7,7 +7,7 @@ com.baeldung.spring.ejb - ejb-for-spring + spring-ejb 1.0.1 @@ -20,7 +20,7 @@ org.assertj assertj-core - 3.9.0 + ${assertj.version} test @@ -66,7 +66,7 @@ - 8.0 + 3.9.0 1.6.1 diff --git a/spring-ejb/ejb-remote-for-spring/src/main/resources/logback.xml b/spring-ejb/ejb-remote-for-spring/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-ejb/ejb-remote-for-spring/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-ejb/pom.xml b/spring-ejb/pom.xml index 357c2cc84c..31cde720f9 100755 --- a/spring-ejb/pom.xml +++ b/spring-ejb/pom.xml @@ -1,12 +1,12 @@ + 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.spring.ejb - ejb-for-spring + spring-ejb 1.0.1 pom - ejb + spring-ejb Spring EJB Tutorial @@ -37,19 +37,19 @@ com.baeldung.spring.ejb ejb-remote-for-spring - 1.0.1 + ${ejb-remote-for-spring.version} ejb javax javaee-api - 8.0 + ${javaee.version} provided org.wildfly wildfly-ejb-client-bom - 12.0.0.Final + ${wildfly-ejb.version} pom import @@ -61,9 +61,9 @@ maven-ejb-plugin - 2.4 + ${maven-ejb-plugin.version} - 3.2 + ${ejb.version} @@ -72,7 +72,15 @@ ejb-remote-for-spring - spring-ejb-client ejb-beans + + + 1.0.1 + 8.0 + 12.0.0.Final + 2.4 + 3.2 + + diff --git a/spring-ejb/spring-ejb-client/pom.xml b/spring-ejb/spring-ejb-client/pom.xml index 83c7028dab..c935e1f14a 100644 --- a/spring-ejb/spring-ejb-client/pom.xml +++ b/spring-ejb/spring-ejb-client/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-ejb-client @@ -16,12 +16,6 @@ ../../parent-boot-2 - - UTF-8 - UTF-8 - 1.8 - - org.springframework.boot @@ -31,14 +25,14 @@ org.wildfly wildfly-ejb-client-bom - 12.0.0.Final + ${wildfly-ejb.version} pom com.baeldung.spring.ejb ejb-remote-for-spring - 1.0.1 + ${ejb-remote-for-spring.version} ejb @@ -47,12 +41,12 @@ spring-boot-starter-test test - + io.undertow undertow-servlet - + @@ -64,4 +58,9 @@ + + 1.0.1 + 12.0.0.Final + + diff --git a/spring-ejb/spring-ejb-client/src/main/java/com/baeldung/springejbclient/SpringEjbClientApplication.java b/spring-ejb/spring-ejb-client/src/main/java/com/baeldung/springejbclient/SpringEjbClientApplication.java index d3542a2158..0a1e389113 100644 --- a/spring-ejb/spring-ejb-client/src/main/java/com/baeldung/springejbclient/SpringEjbClientApplication.java +++ b/spring-ejb/spring-ejb-client/src/main/java/com/baeldung/springejbclient/SpringEjbClientApplication.java @@ -47,4 +47,5 @@ public class SpringEjbClientApplication { public static void main(String[] args) { SpringApplication.run(SpringEjbClientApplication.class, args); } + } diff --git a/spring-ejb/spring-ejb-client/src/main/resources/logback.xml b/spring-ejb/spring-ejb-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-ejb/spring-ejb-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..4d2d83646d --- /dev/null +++ b/spring-ejb/spring-ejb-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springejbclient.SpringEjbClientApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringEjbClientApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-exceptions/pom.xml b/spring-exceptions/pom.xml index a9ea8239f6..16f6286606 100644 --- a/spring-exceptions/pom.xml +++ b/spring-exceptions/pom.xml @@ -1,5 +1,5 @@ + 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 spring-exceptions @@ -174,6 +174,7 @@ + 4.3.4.RELEASE 4.2.0.RELEASE diff --git a/spring-exceptions/src/main/resources/logback.xml b/spring-exceptions/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-exceptions/src/main/resources/logback.xml +++ b/spring-exceptions/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-exceptions/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-exceptions/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..492673b168 --- /dev/null +++ b/spring-exceptions/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.baeldung.spring.config.CoreConfig; +import org.baeldung.spring.config.MvcConfig; +import org.baeldung.spring.config.PersistenceConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { CoreConfig.class, MvcConfig.class, PersistenceConfig.class}) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-freemarker/pom.xml b/spring-freemarker/pom.xml index f2771857c7..4ff57e27f0 100644 --- a/spring-freemarker/pom.xml +++ b/spring-freemarker/pom.xml @@ -1,8 +1,8 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.freemarker.example - spring4-freemarker-example + com.baeldung.freemarker + spring-freemarker war 1.0-SNAPSHOT Spring Freemarker Example @@ -13,16 +13,7 @@ 1.0.0-SNAPSHOT - - 1.8 - 4.3.4.RELEASE - 2.3.23 - 3.1.0 - false - - - org.springframework spring-webmvc @@ -34,13 +25,11 @@ - org.springframework spring-context-support ${spring.version} - @@ -49,14 +38,27 @@ ${servletapi.version} provided - org.freemarker freemarker ${freemarker.version} + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + - \ No newline at end of file + + 5.0.8.RELEASE + 2.3.28 + 3.1.0 + false + + + diff --git a/spring-freemarker/src/main/resources/logback.xml b/spring-freemarker/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-freemarker/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-freemarker/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-freemarker/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ab0e6e8f49 --- /dev/null +++ b/spring-freemarker/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.freemarker.config.SpringWebConfig; +import com.baeldung.freemarker.config.WebConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { SpringWebConfig.class, WebConfiguration.class }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-groovy/pom.xml b/spring-groovy/pom.xml index c9e28deee6..42cdb93fd2 100644 --- a/spring-groovy/pom.xml +++ b/spring-groovy/pom.xml @@ -1,65 +1,68 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldug spring-groovy 0.0.1-SNAPSHOT jar - spring-groovy http://maven.apache.org com.baeldung parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 - + org.springframework.integration spring-integration-groovy - 4.3.7.RELEASE + ${spring-integration-groovy.version} org.codehaus.groovy groovy-all - 2.4.12 + ${groovy-all.version} + maven-compiler-plugin - 3.7.0 + ${maven-compiler-plugin.version} groovy-eclipse-compiler true - 1.8 - 1.8 + ${java.version} + ${java.version} ${project.build.sourceEncoding} org.codehaus.groovy groovy-eclipse-compiler - 2.9.2-01 + ${groovy-eclipse-compiler.version} org.codehaus.groovy groovy-eclipse-batch - 2.4.3-01 + ${groovy-eclipse-batch.version} - + - UTF-8 + 2.9.2-01 + 2.4.3-01 + 4.3.7.RELEASE + 2.4.12 - + diff --git a/spring-groovy/src/main/resources/logback.xml b/spring-groovy/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-groovy/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationUnitTest.java similarity index 97% rename from spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java rename to spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationUnitTest.java index 91ca6dbfe9..dbefba5ba5 100644 --- a/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationUnitTest.java @@ -7,7 +7,7 @@ import java.io.File; import org.junit.Test; import org.springframework.context.support.GenericGroovyApplicationContext; -public class GroovyConfigurationTest { +public class GroovyConfigurationUnitTest { private static final String FILE_NAME = "GroovyBeanConfig.groovy"; private static final String FILE_PATH = "src/main/java/com/baeldug/groovyconfig/"; diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationUnitTest.java similarity index 93% rename from spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java rename to spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationUnitTest.java index 2d9b1000ff..c1e16f1b62 100644 --- a/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationUnitTest.java @@ -5,7 +5,7 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -public class JavaConfigurationTest { +public class JavaConfigurationUnitTest { @Test public void whenJavaConfig_thenCorrectPerson() { diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationUnitTest.java similarity index 94% rename from spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java rename to spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationUnitTest.java index 3ee724207c..b8d341ee39 100644 --- a/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationUnitTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; -public class XmlConfigurationTest { +public class XmlConfigurationUnitTest { @Test public void whenXmlConfig_thenCorrectPerson() { diff --git a/spring-groovy/src/test/java/com/baeldug/spring_groovy/AppTest.java b/spring-groovy/src/test/java/com/baeldug/spring_groovy/AppUnitTest.java similarity index 82% rename from spring-groovy/src/test/java/com/baeldug/spring_groovy/AppTest.java rename to spring-groovy/src/test/java/com/baeldug/spring_groovy/AppUnitTest.java index 19eefb6c0f..3d8fa3e2d8 100644 --- a/spring-groovy/src/test/java/com/baeldug/spring_groovy/AppTest.java +++ b/spring-groovy/src/test/java/com/baeldug/spring_groovy/AppUnitTest.java @@ -7,7 +7,7 @@ import junit.framework.TestSuite; /** * Unit test for simple App. */ -public class AppTest +public class AppUnitTest extends TestCase { /** @@ -15,7 +15,7 @@ public class AppTest * * @param testName name of the test case */ - public AppTest( String testName ) + public AppUnitTest( String testName ) { super( testName ); } @@ -25,7 +25,7 @@ public class AppTest */ public static Test suite() { - return new TestSuite( AppTest.class ); + return new TestSuite( AppUnitTest.class ); } /** diff --git a/spring-hibernate3/src/main/resources/logback.xml b/spring-hibernate3/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-hibernate3/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-hibernate4/README.md b/spring-hibernate4/README.md index 88ee7fadd3..b15b7278f4 100644 --- a/spring-hibernate4/README.md +++ b/spring-hibernate4/README.md @@ -11,7 +11,6 @@ - [Stored Procedures with Hibernate](http://www.baeldung.com/stored-procedures-with-hibernate-tutorial) - [Hibernate: save, persist, update, merge, saveOrUpdate](http://www.baeldung.com/hibernate-save-persist-update-merge-saveorupdate) - [Eager/Lazy Loading In Hibernate](http://www.baeldung.com/hibernate-lazy-eager-loading) -- [Hibernate Criteria Queries](http://www.baeldung.com/hibernate-criteria-queries) - [Hibernate One to Many Annotation Tutorial](http://www.baeldung.com/hibernate-one-to-many) - [Guide to @Immutable Annotation in Hibernate](http://www.baeldung.com/hibernate-immutable) - [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) diff --git a/spring-hibernate4/pom.xml b/spring-hibernate4/pom.xml index be27ba6f6a..505a218a94 100644 --- a/spring-hibernate4/pom.xml +++ b/spring-hibernate4/pom.xml @@ -1,5 +1,5 @@ + 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 spring-hibernate4 @@ -127,6 +127,12 @@ ${hsqldb.version} test + + com.h2database + h2 + ${h2.version} + test + @@ -138,12 +144,6 @@ true - - - - - - @@ -159,6 +159,7 @@ 8.5.8 1.1 2.3.4 + 1.4.193 5.3.3.Final @@ -177,7 +178,6 @@ 2.7 1.6.1 - diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java b/spring-hibernate4/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java deleted file mode 100644 index 83e3c2f9a5..0000000000 --- a/spring-hibernate4/src/main/java/com/baeldung/hibernate/criteria/view/ApplicationView.java +++ /dev/null @@ -1,251 +0,0 @@ -/** - * ApplicationViewer is the class that starts the application - * First it creates the session object and then creates the - * criteria query. - * - * @author Pritam Banerjee - * @version 1.0 - * @since 07/20/2016 - */ - -package com.baeldung.hibernate.criteria.view; - -import java.util.List; - -import org.hibernate.Criteria; -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.criterion.Criterion; -import org.hibernate.criterion.LogicalExpression; -import org.hibernate.criterion.Order; -import org.hibernate.criterion.Projections; -import org.hibernate.criterion.Restrictions; - -import com.baeldung.hibernate.criteria.model.Item; -import com.baeldung.hibernate.criteria.util.HibernateUtil; - -public class ApplicationView { - - // default Constructor - public ApplicationView() { - - } - - public boolean checkIfCriteriaTimeLower() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - Transaction tx = null; - - // calculate the time taken by criteria - final long startTimeCriteria = System.nanoTime(); - cr.add(Restrictions.like("itemName", "%item One%")); - final List results = cr.list(); - final long endTimeCriteria = System.nanoTime(); - final long durationCriteria = (endTimeCriteria - startTimeCriteria) / 1000; - - // calculate the time taken by HQL - final long startTimeHQL = System.nanoTime(); - tx = session.beginTransaction(); - final List items = session.createQuery("FROM Item where itemName like '%item One%'").list(); - final long endTimeHQL = System.nanoTime(); - final long durationHQL = (endTimeHQL - startTimeHQL) / 1000; - - if (durationCriteria > durationHQL) { - return false; - } else { - return true; - } - } - - // To get items having price more than 1000 - public String[] greaterThanCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - cr.add(Restrictions.gt("itemPrice", 1000)); - final List greaterThanItemsList = cr.list(); - final String greaterThanItems[] = new String[greaterThanItemsList.size()]; - for (int i = 0; i < greaterThanItemsList.size(); i++) { - greaterThanItems[i] = greaterThanItemsList.get(i).getItemName(); - } - session.close(); - return greaterThanItems; - } - - // To get items having price less than 1000 - public String[] lessThanCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - cr.add(Restrictions.lt("itemPrice", 1000)); - final List lessThanItemsList = cr.list(); - final String lessThanItems[] = new String[lessThanItemsList.size()]; - for (int i = 0; i < lessThanItemsList.size(); i++) { - lessThanItems[i] = lessThanItemsList.get(i).getItemName(); - } - session.close(); - return lessThanItems; - } - - // To get items whose Name start with Chair - public String[] likeCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - - final Criteria cr = session.createCriteria(Item.class); - cr.add(Restrictions.like("itemName", "%chair%")); - final List likeItemsList = cr.list(); - final String likeItems[] = new String[likeItemsList.size()]; - for (int i = 0; i < likeItemsList.size(); i++) { - likeItems[i] = likeItemsList.get(i).getItemName(); - } - session.close(); - return likeItems; - } - - // Case sensitive search - public String[] likeCaseCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - cr.add(Restrictions.ilike("itemName", "%Chair%")); - final List ilikeItemsList = cr.list(); - final String ilikeItems[] = new String[ilikeItemsList.size()]; - for (int i = 0; i < ilikeItemsList.size(); i++) { - ilikeItems[i] = ilikeItemsList.get(i).getItemName(); - } - session.close(); - return ilikeItems; - } - - // To get records having itemPrice in between 100 and 200 - public String[] betweenCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - // To get items having price more than 1000 - cr.add(Restrictions.between("itemPrice", 100, 200)); - final List betweenItemsList = cr.list(); - final String betweenItems[] = new String[betweenItemsList.size()]; - for (int i = 0; i < betweenItemsList.size(); i++) { - betweenItems[i] = betweenItemsList.get(i).getItemName(); - } - session.close(); - return betweenItems; - } - - // To check if the given property is null - public String[] nullCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - cr.add(Restrictions.isNull("itemDescription")); - final List nullItemsList = cr.list(); - final String nullDescItems[] = new String[nullItemsList.size()]; - for (int i = 0; i < nullItemsList.size(); i++) { - nullDescItems[i] = nullItemsList.get(i).getItemName(); - } - session.close(); - return nullDescItems; - } - - // To check if the given property is not null - public String[] notNullCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - cr.add(Restrictions.isNotNull("itemDescription")); - final List notNullItemsList = cr.list(); - final String notNullDescItems[] = new String[notNullItemsList.size()]; - for (int i = 0; i < notNullItemsList.size(); i++) { - notNullDescItems[i] = notNullItemsList.get(i).getItemName(); - } - session.close(); - return notNullDescItems; - } - - // Adding more than one expression in one cr - public String[] twoCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - cr.add(Restrictions.isNull("itemDescription")); - cr.add(Restrictions.like("itemName", "chair%")); - final List notNullItemsList = cr.list(); - final String notNullDescItems[] = new String[notNullItemsList.size()]; - for (int i = 0; i < notNullItemsList.size(); i++) { - notNullDescItems[i] = notNullItemsList.get(i).getItemName(); - } - session.close(); - return notNullDescItems; - } - - // To get items matching with the above defined conditions joined - // with Logical AND - public String[] andLogicalCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - final Criterion greaterThanPrice = Restrictions.gt("itemPrice", 1000); - final Criterion chairItems = Restrictions.like("itemName", "Chair%"); - final LogicalExpression andExample = Restrictions.and(greaterThanPrice, chairItems); - cr.add(andExample); - final List andItemsList = cr.list(); - final String andItems[] = new String[andItemsList.size()]; - for (int i = 0; i < andItemsList.size(); i++) { - andItems[i] = andItemsList.get(i).getItemName(); - } - session.close(); - return andItems; - } - - // To get items matching with the above defined conditions joined - // with Logical OR - public String[] orLogicalCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - final Criterion greaterThanPrice = Restrictions.gt("itemPrice", 1000); - final Criterion chairItems = Restrictions.like("itemName", "Chair%"); - final LogicalExpression orExample = Restrictions.or(greaterThanPrice, chairItems); - cr.add(orExample); - final List orItemsList = cr.list(); - final String orItems[] = new String[orItemsList.size()]; - for (int i = 0; i < orItemsList.size(); i++) { - orItems[i] = orItemsList.get(i).getItemName(); - } - session.close(); - return orItems; - } - - // Sorting example - public String[] sortingCriteria() { - final Session session = HibernateUtil.getHibernateSession(); - final Criteria cr = session.createCriteria(Item.class); - cr.addOrder(Order.asc("itemName")); - cr.addOrder(Order.desc("itemPrice")).list(); - final List sortedItemsList = cr.list(); - final String sortedItems[] = new String[sortedItemsList.size()]; - for (int i = 0; i < sortedItemsList.size(); i++) { - sortedItems[i] = sortedItemsList.get(i).getItemName(); - } - session.close(); - return sortedItems; - } - - // Set projections Row Count - public Long[] projectionRowCount() { - final Session session = HibernateUtil.getHibernateSession(); - final List itemProjected = session.createCriteria(Item.class).setProjection(Projections.rowCount()).list(); - final Long projectedRowCount[] = new Long[itemProjected.size()]; - for (int i = 0; i < itemProjected.size(); i++) { - projectedRowCount[i] = itemProjected.get(i); - } - session.close(); - return projectedRowCount; - } - - // Set projections average of itemPrice - public Double[] projectionAverage() { - final Session session = HibernateUtil.getHibernateSession(); - final List avgItemPriceList = session.createCriteria(Item.class).setProjection(Projections.projectionList().add(Projections.avg("itemPrice"))).list(); - - final Double avgItemPrice[] = new Double[avgItemPriceList.size()]; - for (int i = 0; i < avgItemPriceList.size(); i++) { - avgItemPrice[i] = (Double) avgItemPriceList.get(i); - } - session.close(); - return avgItemPrice; - } - -} diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java b/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java index 2559d5f048..9fda4c43bb 100644 --- a/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java +++ b/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/model/UserEager.java @@ -16,7 +16,7 @@ public class UserEager implements Serializable { @Column(name = "USER_ID") private Long userId; - @OneToMany(fetch = FetchType.EAGER, mappedBy = "user") + @OneToMany(fetch = FetchType.EAGER) private Set orderDetail = new HashSet(); public UserEager() { diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java b/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java index 5852e74418..a78eaa4ac0 100644 --- a/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java +++ b/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/model/UserLazy.java @@ -16,7 +16,7 @@ public class UserLazy implements Serializable { @Column(name = "USER_ID") private Long userId; - @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") + @OneToMany(fetch = FetchType.LAZY) private Set orderDetail = new HashSet(); public UserLazy() { diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java b/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java index 1a5142c5c2..35cdd254e3 100644 --- a/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java +++ b/spring-hibernate4/src/main/java/com/baeldung/hibernate/fetching/view/FetchingAppView.java @@ -20,7 +20,7 @@ public class FetchingAppView { public Set lazyLoaded() { final Session sessionLazy = HibernateUtil.getHibernateSession("lazy"); List users = sessionLazy.createQuery("From UserLazy").list(); - UserLazy userLazyLoaded = users.get(3); + UserLazy userLazyLoaded = users.get(0); // since data is lazyloaded so data won't be initialized return (userLazyLoaded.getOrderDetail()); } @@ -31,7 +31,7 @@ public class FetchingAppView { // data should be loaded in the following line // also note the queries generated List user = sessionEager.createQuery("From UserEager").list(); - UserEager userEagerLoaded = user.get(3); + UserEager userEagerLoaded = user.get(0); return userEagerLoaded.getOrderDetail(); } diff --git a/spring-hibernate4/src/main/resources/criteria.cfg.xml b/spring-hibernate4/src/main/resources/criteria.cfg.xml deleted file mode 100644 index a39a32e151..0000000000 --- a/spring-hibernate4/src/main/resources/criteria.cfg.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - com.mysql.jdbc.Driver - jdbc:mysql://localhost:3306/test - root - iamtheking - org.hibernate.dialect.MySQLDialect - true - - - \ No newline at end of file diff --git a/spring-hibernate4/src/main/resources/criteria_create_queries.sql b/spring-hibernate4/src/main/resources/criteria_create_queries.sql deleted file mode 100644 index 3a627dd38c..0000000000 --- a/spring-hibernate4/src/main/resources/criteria_create_queries.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE `item` ( - `ITEM_ID` int(11) NOT NULL AUTO_INCREMENT, - `ITEM_DESC` varchar(100) DEFAULT NULL, - `ITEM_PRICE` int(11) NOT NULL, - `ITEM_NAME` varchar(255) NOT NULL, - PRIMARY KEY (`ITEM_ID`) -) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=latin1; diff --git a/spring-hibernate4/src/main/resources/logback.xml b/spring-hibernate4/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-hibernate4/src/main/resources/logback.xml +++ b/spring-hibernate4/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java index ed2e111c8f..2f23a9a532 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/EnversFooBarAuditIntegrationTest.java @@ -5,11 +5,6 @@ import static org.junit.Assert.assertNotNull; import java.util.List; -import com.baeldung.persistence.model.Foo; -import com.baeldung.persistence.service.IBarAuditableService; -import com.baeldung.persistence.service.IFooAuditableService; -import com.baeldung.spring.PersistenceConfig; -import com.baeldung.persistence.model.Bar; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.After; @@ -26,8 +21,14 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.persistence.model.Bar; +import com.baeldung.persistence.model.Foo; +import com.baeldung.persistence.service.IBarAuditableService; +import com.baeldung.persistence.service.IFooAuditableService; +import com.baeldung.spring.config.PersistenceTestConfig; + @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class) public class EnversFooBarAuditIntegrationTest { private static Logger logger = LoggerFactory.getLogger(EnversFooBarAuditIntegrationTest.class); diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java index b63a4b989b..733074a6a3 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/JPABarAuditIntegrationTest.java @@ -7,10 +7,6 @@ import static org.junit.Assert.assertTrue; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; -import com.baeldung.persistence.model.Bar; -import com.baeldung.persistence.model.Bar.OPERATION; -import com.baeldung.persistence.service.IBarService; -import com.baeldung.spring.PersistenceConfig; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -25,8 +21,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.persistence.model.Bar; +import com.baeldung.persistence.model.Bar.OPERATION; +import com.baeldung.persistence.service.IBarService; +import com.baeldung.spring.config.PersistenceTestConfig; + @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class) public class JPABarAuditIntegrationTest { private static Logger logger = LoggerFactory.getLogger(JPABarAuditIntegrationTest.class); diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java index e794b282f6..18227abd28 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/audit/SpringDataJPABarAuditIntegrationTest.java @@ -6,9 +6,6 @@ import static org.junit.Assert.assertTrue; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; -import com.baeldung.persistence.model.Bar; -import com.baeldung.persistence.service.IBarService; -import com.baeldung.spring.PersistenceConfig; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -24,8 +21,12 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.persistence.model.Bar; +import com.baeldung.persistence.service.IBarService; +import com.baeldung.spring.config.PersistenceTestConfig; + @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class) public class SpringDataJPABarAuditIntegrationTest { private static Logger logger = LoggerFactory.getLogger(SpringDataJPABarAuditIntegrationTest.class); diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/hibernate/FooPaginationPersistenceIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/hibernate/FooPaginationPersistenceIntegrationTest.java index 721b20db68..fd7bc4aabf 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/hibernate/FooPaginationPersistenceIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/hibernate/FooPaginationPersistenceIntegrationTest.java @@ -7,9 +7,6 @@ import static org.junit.Assert.assertThat; import java.util.List; -import com.baeldung.persistence.model.Foo; -import com.baeldung.persistence.service.IFooService; -import com.baeldung.spring.PersistenceConfig; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.ScrollMode; @@ -26,10 +23,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.persistence.model.Foo; +import com.baeldung.persistence.service.IFooService; +import com.baeldung.spring.config.PersistenceTestConfig; import com.google.common.collect.Lists; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class) public class FooPaginationPersistenceIntegrationTest { @Autowired diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/hibernate/FooSortingPersistenceIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/hibernate/FooSortingPersistenceIntegrationTest.java index 0f76526960..8173088af0 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/hibernate/FooSortingPersistenceIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/hibernate/FooSortingPersistenceIntegrationTest.java @@ -5,9 +5,6 @@ import static org.junit.Assert.assertNull; import java.util.List; import java.util.Set; -import com.baeldung.persistence.model.Bar; -import com.baeldung.persistence.model.Foo; -import com.baeldung.spring.PersistenceConfig; import org.hibernate.Criteria; import org.hibernate.NullPrecedence; import org.hibernate.Query; @@ -23,8 +20,12 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.persistence.model.Bar; +import com.baeldung.persistence.model.Foo; +import com.baeldung.spring.config.PersistenceTestConfig; + @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class) @SuppressWarnings("unchecked") public class FooSortingPersistenceIntegrationTest { diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooServiceBasicPersistenceIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooServiceBasicPersistenceIntegrationTest.java index c77f5dfb95..146f8e9622 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooServiceBasicPersistenceIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooServiceBasicPersistenceIntegrationTest.java @@ -2,8 +2,6 @@ package com.baeldung.persistence.service; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; -import com.baeldung.persistence.model.Foo; -import com.baeldung.spring.PersistenceConfig; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.junit.After; @@ -15,8 +13,11 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.persistence.model.Foo; +import com.baeldung.spring.config.PersistenceTestConfig; + @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class) public class FooServiceBasicPersistenceIntegrationTest { @Autowired diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java index b82d4621ab..6d426849a6 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java @@ -2,8 +2,6 @@ package com.baeldung.persistence.service; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; -import com.baeldung.persistence.model.Foo; -import com.baeldung.spring.PersistenceConfig; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -16,8 +14,11 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.persistence.model.Foo; +import com.baeldung.spring.config.PersistenceTestConfig; + @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class) public class FooServicePersistenceIntegrationTest { @Autowired diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooStoredProceduresIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooStoredProceduresLiveTest.java similarity index 95% rename from spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooStoredProceduresIntegrationTest.java rename to spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooStoredProceduresLiveTest.java index db64107405..9ec04d297c 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooStoredProceduresIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/service/FooStoredProceduresLiveTest.java @@ -26,9 +26,9 @@ import com.baeldung.spring.PersistenceConfig; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) -public class FooStoredProceduresIntegrationTest { +public class FooStoredProceduresLiveTest { - private static final Logger LOGGER = LoggerFactory.getLogger(FooStoredProceduresIntegrationTest.class); + private static final Logger LOGGER = LoggerFactory.getLogger(FooStoredProceduresLiveTest.class); @Autowired private SessionFactory sessionFactory; diff --git a/spring-hibernate4/src/test/java/com/baeldung/persistence/service/ParentServicePersistenceIntegrationTest.java b/spring-hibernate4/src/test/java/com/baeldung/persistence/service/ParentServicePersistenceIntegrationTest.java index 9e8c4aba92..5a73e39ca2 100644 --- a/spring-hibernate4/src/test/java/com/baeldung/persistence/service/ParentServicePersistenceIntegrationTest.java +++ b/spring-hibernate4/src/test/java/com/baeldung/persistence/service/ParentServicePersistenceIntegrationTest.java @@ -1,8 +1,5 @@ package com.baeldung.persistence.service; -import com.baeldung.persistence.model.Child; -import com.baeldung.persistence.model.Parent; -import com.baeldung.spring.PersistenceConfig; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -11,8 +8,12 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; +import com.baeldung.persistence.model.Child; +import com.baeldung.persistence.model.Parent; +import com.baeldung.spring.config.PersistenceTestConfig; + @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceTestConfig.class }, loader = AnnotationConfigContextLoader.class) public class ParentServicePersistenceIntegrationTest { @Autowired diff --git a/spring-hibernate4/src/test/java/com/baeldung/spring/config/PersistenceTestConfig.java b/spring-hibernate4/src/test/java/com/baeldung/spring/config/PersistenceTestConfig.java new file mode 100644 index 0000000000..9bf55c902a --- /dev/null +++ b/spring-hibernate4/src/test/java/com/baeldung/spring/config/PersistenceTestConfig.java @@ -0,0 +1,179 @@ +package com.baeldung.spring.config; + +import java.util.Properties; + +import javax.sql.DataSource; + +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +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.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.hibernate4.HibernateTransactionManager; +import org.springframework.orm.hibernate4.LocalSessionFactoryBean; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.baeldung.persistence.dao.IBarAuditableDao; +import com.baeldung.persistence.dao.IBarDao; +import com.baeldung.persistence.dao.IFooAuditableDao; +import com.baeldung.persistence.dao.IFooDao; +import com.baeldung.persistence.dao.impl.BarAuditableDao; +import com.baeldung.persistence.dao.impl.BarDao; +import com.baeldung.persistence.dao.impl.BarJpaDao; +import com.baeldung.persistence.dao.impl.FooAuditableDao; +import com.baeldung.persistence.dao.impl.FooDao; +import com.baeldung.persistence.service.IBarAuditableService; +import com.baeldung.persistence.service.IBarService; +import com.baeldung.persistence.service.IFooAuditableService; +import com.baeldung.persistence.service.IFooService; +import com.baeldung.persistence.service.impl.BarAuditableService; +import com.baeldung.persistence.service.impl.BarJpaService; +import com.baeldung.persistence.service.impl.BarSpringDataJpaService; +import com.baeldung.persistence.service.impl.FooAuditableService; +import com.baeldung.persistence.service.impl.FooService; +import com.google.common.base.Preconditions; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories(basePackages = { "com.baeldung.persistence" }, transactionManagerRef = "jpaTransactionManager") +@EnableJpaAuditing +@PropertySource({ "classpath:persistence-h2.properties" }) +@ComponentScan({ "com.baeldung.persistence" }) +public class PersistenceTestConfig { + + @Autowired + private Environment env; + + public PersistenceTestConfig() { + super(); + } + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(restDataSource()); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + + return sessionFactory; + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); + emf.setDataSource(restDataSource()); + emf.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); + + final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + emf.setJpaVendorAdapter(vendorAdapter); + emf.setJpaProperties(hibernateProperties()); + + return emf; + } + + @Bean + public DataSource restDataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager hibernateTransactionManager() { + final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory().getObject()); + return transactionManager; + } + + @Bean + public PlatformTransactionManager jpaTransactionManager() { + final JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + @Bean + public IBarService barJpaService() { + return new BarJpaService(); + } + + @Bean + public IBarService barSpringDataJpaService() { + return new BarSpringDataJpaService(); + } + + @Bean + public IFooService fooHibernateService() { + return new FooService(); + } + + @Bean + public IBarAuditableService barHibernateAuditableService() { + return new BarAuditableService(); + } + + @Bean + public IFooAuditableService fooHibernateAuditableService() { + return new FooAuditableService(); + } + + @Bean + public IBarDao barJpaDao() { + return new BarJpaDao(); + } + + @Bean + public IBarDao barHibernateDao() { + return new BarDao(); + } + + @Bean + public IBarAuditableDao barHibernateAuditableDao() { + return new BarAuditableDao(); + } + + @Bean + public IFooDao fooHibernateDao() { + return new FooDao(); + } + + @Bean + public IFooAuditableDao fooHibernateAuditableDao() { + return new FooAuditableDao(); + } + + private final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + + hibernateProperties.setProperty("hibernate.show_sql", "true"); + // hibernateProperties.setProperty("hibernate.format_sql", "true"); + // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + + // Envers properties + hibernateProperties.setProperty("org.hibernate.envers.audit_table_suffix", env.getProperty("envers.audit_table_suffix")); + + return hibernateProperties; + } + +} \ No newline at end of file diff --git a/spring-hibernate4/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-hibernate4/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..af4618d0f3 --- /dev/null +++ b/spring-hibernate4/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.spring.PersistenceConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-hibernate4/src/test/resources/criteria.cfg.xml b/spring-hibernate4/src/test/resources/criteria.cfg.xml deleted file mode 100644 index 653b5a188a..0000000000 --- a/spring-hibernate4/src/test/resources/criteria.cfg.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - com.mysql.jdbc.Driver - jdbc:mysql://localhost:3306/test - root - iamtheking - org.hibernate.dialect.MySQLDialect - true - - - \ No newline at end of file diff --git a/spring-hibernate4/src/test/resources/fetching.cfg.xml b/spring-hibernate4/src/test/resources/fetching.cfg.xml index acee7008ba..55a3aeb51c 100644 --- a/spring-hibernate4/src/test/resources/fetching.cfg.xml +++ b/spring-hibernate4/src/test/resources/fetching.cfg.xml @@ -5,14 +5,15 @@ - com.mysql.jdbc.Driver - jdbc:mysql://localhost:3306/test - root - iamtheking - org.hibernate.dialect.MySQLDialect + org.h2.Driver + jdbc:h2:mem:testdb + sa + + org.hibernate.dialect.H2Dialect + update true - + \ No newline at end of file diff --git a/spring-hibernate4/src/test/resources/fetchingLazy.cfg.xml b/spring-hibernate4/src/test/resources/fetchingLazy.cfg.xml index 1dc37d0cf8..8fcf578660 100644 --- a/spring-hibernate4/src/test/resources/fetchingLazy.cfg.xml +++ b/spring-hibernate4/src/test/resources/fetchingLazy.cfg.xml @@ -5,14 +5,15 @@ - com.mysql.jdbc.Driver - jdbc:mysql://localhost:3306/test - root - iamtheking - org.hibernate.dialect.MySQLDialect + org.h2.Driver + jdbc:h2:mem:testdb + sa + + org.hibernate.dialect.H2Dialect + update true - + \ No newline at end of file diff --git a/spring-hibernate4/src/test/resources/persistence-h2.properties b/spring-hibernate4/src/test/resources/persistence-h2.properties new file mode 100644 index 0000000000..911619193b --- /dev/null +++ b/spring-hibernate4/src/test/resources/persistence-h2.properties @@ -0,0 +1,13 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:test +jdbc.user=sa +jdbc.pass= + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop + +# envers.X +envers.audit_table_suffix=_audit_log diff --git a/spring-integration/README.md b/spring-integration/README.md index d782862901..e116f934c8 100644 --- a/spring-integration/README.md +++ b/spring-integration/README.md @@ -1,6 +1,7 @@ ### Relevant Articles: - [Introduction to Spring Integration](http://www.baeldung.com/spring-integration) - [Security In Spring Integration](http://www.baeldung.com/spring-integration-security) +- [Spring Integration Java DSL](https://www.baeldung.com/spring-integration-java-dsl) ### Running the Sample Executing the `mvn exec:java` maven command (either from the command line or from an IDE) will start up the application. Follow the command prompt for further instructions. diff --git a/spring-integration/pom.xml b/spring-integration/pom.xml index 7cb2be45e0..457645a144 100644 --- a/spring-integration/pom.xml +++ b/spring-integration/pom.xml @@ -1,5 +1,5 @@ + 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.samples.spring.integration spring-integration @@ -14,52 +14,6 @@ 1.0.0-SNAPSHOT - - UTF-8 - 5.0.3.RELEASE - 1.1.4.RELEASE - 1.4.7 - 1.1.1 - 4.12 - 2.10 - 1.5.0 - - - - - repo.springsource.org.milestone - Spring Framework Maven Milestone Repository - https://repo.springsource.org/milestone - - - - - - - maven-eclipse-plugin - ${maven-eclipse-plugin.version} - - - org.springframework.ide.eclipse.core.springnature - - - org.springframework.ide.eclipse.core.springbuilder - - true - true - - - - org.codehaus.mojo - exec-maven-plugin - ${exec-maven-plugin.version} - - com.baeldung.samples.FileCopyConfig - - - - - @@ -121,12 +75,52 @@ ${spring.version} test - - junit - junit - ${junit.version} - test - + + + + maven-eclipse-plugin + ${maven-eclipse-plugin.version} + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + com.baeldung.samples.FileCopyConfig + + + + + + + + repo.springsource.org.milestone + Spring Framework Maven Milestone Repository + https://repo.springsource.org/milestone + + + + + UTF-8 + 5.0.3.RELEASE + 1.1.4.RELEASE + 1.4.7 + 1.1.1 + 4.12 + 2.10 + 1.5.0 + + diff --git a/spring-integration/src/main/java/com/baeldung/dsl/JavaDSLFileCopyConfig.java b/spring-integration/src/main/java/com/baeldung/dsl/JavaDSLFileCopyConfig.java new file mode 100644 index 0000000000..7e91345f04 --- /dev/null +++ b/spring-integration/src/main/java/com/baeldung/dsl/JavaDSLFileCopyConfig.java @@ -0,0 +1,146 @@ +package com.baeldung.dsl; + +import java.io.File; +import java.util.Scanner; +import java.util.concurrent.TimeUnit; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.integration.annotation.IntegrationComponentScan; +import org.springframework.integration.channel.PriorityChannel; +import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.core.GenericSelector; +import org.springframework.integration.core.MessageSource; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.IntegrationFlows; +import org.springframework.integration.dsl.Pollers; +import org.springframework.integration.file.FileReadingMessageSource; +import org.springframework.integration.file.FileWritingMessageHandler; +import org.springframework.messaging.MessageHandler; + +/** + * JavaDSLFileCopyConfig contains various Integration Flows created from various spring integration components. + * Activate only one flow at a time by un-commenting @Bean annotation from IntegrationFlow beans. + *

    + * Different flows are :
    + * - {@link #fileMover()} - default app - activated
    + * - {@link #fileMoverWithLambda()} - app with file writing expressions as lambda
    + * - {@link #fileMoverWithPriorityChannel()} - app with priority channel
    + * - {@link #fileReader()}, {@link #fileWriter()}, {@link #anotherFileWriter()} - app with bridge + */ +@Configuration +@EnableIntegration +@IntegrationComponentScan +public class JavaDSLFileCopyConfig { + + public static final String INPUT_DIR = "source"; + public static final String OUTPUT_DIR = "target"; + public static final String OUTPUT_DIR2 = "target2"; + + @Bean + public MessageSource sourceDirectory() { + FileReadingMessageSource messageSource = new FileReadingMessageSource(); + messageSource.setDirectory(new File(INPUT_DIR)); + return messageSource; + } + + @Bean + public GenericSelector onlyJpgs() { + return new GenericSelector() { + + @Override + public boolean accept(File source) { + return source.getName() + .endsWith(".jpg"); + } + }; + } + + @Bean + public MessageHandler targetDirectory() { + FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(OUTPUT_DIR)); + handler.setExpectReply(false); // end of pipeline, reply not needed + return handler; + } + + @Bean + public IntegrationFlow fileMover() { + return IntegrationFlows.from(sourceDirectory(), configurer -> configurer.poller(Pollers.fixedDelay(10000))) + .filter(onlyJpgs()) + .handle(targetDirectory()) + .get(); + } + + // @Bean + public IntegrationFlow fileMoverWithLambda() { + return IntegrationFlows.from(sourceDirectory(), configurer -> configurer.poller(Pollers.fixedDelay(10000))) + .filter(message -> ((File) message).getName() + .endsWith(".jpg")) + .handle(targetDirectory()) + .get(); + } + + @Bean + public PriorityChannel alphabetically() { + return new PriorityChannel(1000, (left, right) -> ((File) left.getPayload()).getName() + .compareTo(((File) right.getPayload()).getName())); + } + + // @Bean + public IntegrationFlow fileMoverWithPriorityChannel() { + return IntegrationFlows.from(sourceDirectory()) + .filter(onlyJpgs()) + .channel("alphabetically") + .handle(targetDirectory()) + .get(); + } + + @Bean + public MessageHandler anotherTargetDirectory() { + FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(OUTPUT_DIR2)); + handler.setExpectReply(false); // end of pipeline, reply not needed + return handler; + } + + // @Bean + public IntegrationFlow fileReader() { + return IntegrationFlows.from(sourceDirectory()) + .filter(onlyJpgs()) + .channel("holdingTank") + .get(); + } + + // @Bean + public IntegrationFlow fileWriter() { + return IntegrationFlows.from("holdingTank") + .bridge(e -> e.poller(Pollers.fixedRate(1, TimeUnit.SECONDS, 20))) + .handle(targetDirectory()) + .get(); + } + + // @Bean + public IntegrationFlow anotherFileWriter() { + return IntegrationFlows.from("holdingTank") + .bridge(e -> e.poller(Pollers.fixedRate(2, TimeUnit.SECONDS, 10))) + .handle(anotherTargetDirectory()) + .get(); + } + + public static void main(final String... args) { + final AbstractApplicationContext context = new AnnotationConfigApplicationContext(JavaDSLFileCopyConfig.class); + context.registerShutdownHook(); + final Scanner scanner = new Scanner(System.in); + System.out.print("Please enter a string and press : "); + while (true) { + final String input = scanner.nextLine(); + if ("q".equals(input.trim())) { + context.close(); + scanner.close(); + break; + } + } + System.exit(0); + } +} diff --git a/spring-integration/src/main/resources/logback.xml b/spring-integration/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-integration/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-integration/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-integration/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..92e80a0903 --- /dev/null +++ b/spring-integration/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,21 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.si.security.MessageConsumer; +import com.baeldung.si.security.SecuredDirectChannel; +import com.baeldung.si.security.SecurityConfig; +import com.baeldung.si.security.SecurityPubSubChannel; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { SecurityConfig.class, SecuredDirectChannel.class, SecurityPubSubChannel.class, + MessageConsumer.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-integration/src/test/resources/logback-test.xml b/spring-integration/src/test/resources/logback-test.xml index a807be0ca2..8f1be4eb7a 100644 --- a/spring-integration/src/test/resources/logback-test.xml +++ b/spring-integration/src/test/resources/logback-test.xml @@ -1,5 +1,15 @@ - - + + + # Pattern of log message for console appender + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-jenkins-pipeline/pom.xml b/spring-jenkins-pipeline/pom.xml index 9c3b6f14ed..85336f9689 100644 --- a/spring-jenkins-pipeline/pom.xml +++ b/spring-jenkins-pipeline/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-jenkins-pipeline 0.0.1-SNAPSHOT @@ -29,6 +29,12 @@ spring-boot-starter-test test + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + ${de.flapdoodle.embed.mongo.version} + test + @@ -55,7 +61,7 @@ **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java @@ -69,10 +75,8 @@ - UTF-8 - UTF-8 - 1.8 2.17 + 2.0.0 diff --git a/spring-jenkins-pipeline/src/main/resources/logback.xml b/spring-jenkins-pipeline/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-jenkins-pipeline/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java b/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java index 092ebb93fd..477a7d2adb 100644 --- a/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java +++ b/spring-jenkins-pipeline/src/test/java/com/baeldung/SomeIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.assertNotEquals; @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest +@SpringBootTest(classes = {SpringJenkinsPipelineApplication.class, TestMongoConfig.class }) public class SomeIntegrationTest { @Autowired private StudentRepository studentRepository; diff --git a/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java b/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java new file mode 100644 index 0000000000..a85491cf7e --- /dev/null +++ b/spring-jenkins-pipeline/src/test/java/com/baeldung/TestMongoConfig.java @@ -0,0 +1,11 @@ +package com.baeldung; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class }) +public class TestMongoConfig { + +} \ No newline at end of file diff --git a/spring-jenkins-pipeline/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-jenkins-pipeline/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..8eb1589de7 --- /dev/null +++ b/spring-jenkins-pipeline/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.SpringJenkinsPipelineApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringJenkinsPipelineApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-jersey/README.md b/spring-jersey/README.md index 8b2eecc0e1..37928620d3 100644 --- a/spring-jersey/README.md +++ b/spring-jersey/README.md @@ -3,3 +3,4 @@ ## REST API with Jersey & Spring Example Project - [REST API with Jersey and Spring](http://www.baeldung.com/jersey-rest-api-with-spring) - [JAX-RS Client with Jersey](http://www.baeldung.com/jersey-jax-rs-client) +- [Reactive JAX-RS Client API](https://www.baeldung.com/jax-rs-reactive-client) diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 5fb4adcc61..872835177d 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -1,8 +1,7 @@ + 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 spring-jersey 0.1-SNAPSHOT @@ -14,37 +13,6 @@ 1.0.0-SNAPSHOT - - spring-jersey - - - maven-war-plugin - ${maven-war-plugin.version} - - false - - - - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - true - - jetty8x - embedded - - - - 8082 - - - - - - - @@ -108,6 +76,57 @@ test + + org.glassfish.jersey.inject + jersey-hk2 + ${jersey.version} + + + org.glassfish.jersey.ext.rx + jersey-rx-client-rxjava + ${jersey.version} + + + org.glassfish.jersey.ext.rx + jersey-rx-client-rxjava2 + ${jersey.version} + + + com.github.tomakehurst + wiremock + 1.58 + test + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + 2.6.0 + + + com.fasterxml.jackson.core + jackson-databind + 2.6.0 + + + org.slf4j + slf4j-jdk14 + 1.7.25 + + + org.assertj + assertj-core + 3.10.0 + test + + + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + + @@ -127,7 +146,7 @@ **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/*LiveTest.java @@ -170,8 +189,39 @@ + + spring-jersey + + + maven-war-plugin + ${maven-war-plugin.version} + + false + + + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + jetty8x + embedded + + + + 8082 + + + + + + + - 2.26 + 2.27 3.2.0 1.6.1 4.4.9 diff --git a/spring-jersey/src/main/resources/logback.xml b/spring-jersey/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-jersey/src/main/resources/logback.xml +++ b/spring-jersey/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-jersey/src/test/java/com/baeldung/clientrx/ClientOrchestrationIntegrationTest.java b/spring-jersey/src/test/java/com/baeldung/clientrx/ClientOrchestrationIntegrationTest.java new file mode 100644 index 0000000000..990279a481 --- /dev/null +++ b/spring-jersey/src/test/java/com/baeldung/clientrx/ClientOrchestrationIntegrationTest.java @@ -0,0 +1,272 @@ +package com.baeldung.clientrx; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.assertj.core.api.Assertions.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; + +import org.glassfish.jersey.client.rx.rxjava.RxObservableInvoker; +import org.glassfish.jersey.client.rx.rxjava.RxObservableInvokerProvider; +import org.glassfish.jersey.client.rx.rxjava2.RxFlowableInvoker; +import org.glassfish.jersey.client.rx.rxjava2.RxFlowableInvokerProvider; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; + +import io.reactivex.Flowable; +import rx.Observable; + +/** + * + * @author baeldung + */ +public class ClientOrchestrationIntegrationTest { + + private Client client = ClientBuilder.newClient(); + + private WebTarget userIdService = client.target("http://localhost:8080/id-service/ids"); + private WebTarget nameService = client.target("http://localhost:8080/name-service/users/{userId}/name"); + private WebTarget hashService = client.target("http://localhost:8080/hash-service/{rawValue}"); + + private Logger logger = LoggerFactory.getLogger(ClientOrchestrationIntegrationTest.class); + + private String expectedUserIds = "[1,2,3,4,5,6]"; + + private List expectedNames = Arrays.asList("n/a", "Thor", "Hulk", "BlackWidow", "BlackPanther", "TheTick", "Hawkeye"); + + private List expectedHashValues = Arrays.asList("roht1", "kluh2", "WodiwKcalb3", "RehtnapKclab4", "kciteht5", "eyekwah6"); + + @Rule + public WireMockRule wireMockServer = new WireMockRule(); + + @Before + public void setup() { + + stubFor(get(urlEqualTo("/id-service/ids")).willReturn(aResponse().withBody(expectedUserIds).withHeader("Content-Type", "application/json"))); + + stubFor(get(urlEqualTo("/name-service/users/1/name")).willReturn(aResponse().withBody(expectedNames.get(1)))); + stubFor(get(urlEqualTo("/name-service/users/2/name")).willReturn(aResponse().withBody(expectedNames.get(2)))); + stubFor(get(urlEqualTo("/name-service/users/3/name")).willReturn(aResponse().withBody(expectedNames.get(3)))); + stubFor(get(urlEqualTo("/name-service/users/4/name")).willReturn(aResponse().withBody(expectedNames.get(4)))); + stubFor(get(urlEqualTo("/name-service/users/5/name")).willReturn(aResponse().withBody(expectedNames.get(5)))); + stubFor(get(urlEqualTo("/name-service/users/6/name")).willReturn(aResponse().withBody(expectedNames.get(6)))); + + stubFor(get(urlEqualTo("/hash-service/Thor1")).willReturn(aResponse().withBody(expectedHashValues.get(0)))); + stubFor(get(urlEqualTo("/hash-service/Hulk2")).willReturn(aResponse().withBody(expectedHashValues.get(1)))); + stubFor(get(urlEqualTo("/hash-service/BlackWidow3")).willReturn(aResponse().withBody(expectedHashValues.get(2)))); + stubFor(get(urlEqualTo("/hash-service/BlackPanther4")).willReturn(aResponse().withBody(expectedHashValues.get(3)))); + stubFor(get(urlEqualTo("/hash-service/TheTick5")).willReturn(aResponse().withBody(expectedHashValues.get(4)))); + stubFor(get(urlEqualTo("/hash-service/Hawkeye6")).willReturn(aResponse().withBody(expectedHashValues.get(5)))); + + } + + @Test + public void callBackOrchestrate() throws InterruptedException { + List receivedHashValues = new ArrayList<>(); + + final CountDownLatch completionTracker = new CountDownLatch(expectedHashValues.size()); // used to keep track of the progress of the subsequent calls + + userIdService.request().accept(MediaType.APPLICATION_JSON).async().get(new InvocationCallback>() { + @Override + public void completed(List employeeIds) { + logger.info("[CallbackExample] id-service result: {}", employeeIds); + employeeIds.forEach((id) -> { + // for each employee ID, get the name + nameService.resolveTemplate("userId", id).request().async().get(new InvocationCallback() { + + @Override + public void completed(String response) { + logger.info("[CallbackExample] name-service result: {}", response); + + hashService.resolveTemplate("rawValue", response + id).request().async().get(new InvocationCallback() { + @Override + public void completed(String response) { + logger.info("[CallbackExample] hash-service result: {}", response); + receivedHashValues.add(response); + completionTracker.countDown(); + } + + @Override + public void failed(Throwable throwable) { + logger.warn("[CallbackExample] An error has occurred in the hashing request step!", throwable); + } + }); + } + + @Override + public void failed(Throwable throwable) { + logger.warn("[CallbackExample] An error has occurred in the username request step!", throwable); + } + }); + }); + + } + + @Override + public void failed(Throwable throwable) { + logger.warn("[CallbackExample] An error has occurred in the userId request step!", throwable); + } + }); + + // wait for async calls to complete + try { + // wait for inner requests to complete in 10 seconds + if (!completionTracker.await(10, TimeUnit.SECONDS)) { + logger.warn("[CallbackExample] Some requests didn't complete within the timeout"); + } + } catch (InterruptedException e) { + logger.error("Interrupted!", e); + } + + assertThat(receivedHashValues).containsAll(expectedHashValues); + } + + @Test + public void rxOrchestrate() throws InterruptedException { + List receivedHashValues = new ArrayList<>(); + + final CountDownLatch completionTracker = new CountDownLatch(expectedHashValues.size()); // used to keep track of the progress of the subsequent calls + + CompletionStage> userIdStage = userIdService.request().accept(MediaType.APPLICATION_JSON).rx().get(new GenericType>() { + }).exceptionally((throwable) -> { + logger.warn("[CompletionStageExample] An error has occurred"); + return null; + }); + + userIdStage.thenAcceptAsync(employeeIds -> { + logger.info("[CompletionStageExample] id-service result: {}", employeeIds); + employeeIds.forEach((Long id) -> { + CompletableFuture completable = nameService.resolveTemplate("userId", id).request().rx().get(String.class).toCompletableFuture(); + + completable.thenAccept((String userName) -> { + logger.info("[CompletionStageExample] name-service result: {}", userName); + hashService.resolveTemplate("rawValue", userName + id).request().rx().get(String.class).toCompletableFuture().thenAcceptAsync(hashValue -> { + logger.info("[CompletionStageExample] hash-service result: {}", hashValue); + receivedHashValues.add(hashValue); + completionTracker.countDown(); + }).exceptionally((throwable) -> { + logger.warn("[CompletionStageExample] Hash computation failed for {}", id); + completionTracker.countDown(); + return null; + }); + + }); + + }); + }); + + // wait for async calls to complete + try { + // wait for inner requests to complete in 10 seconds + if (!completionTracker.await(10, TimeUnit.SECONDS)) { + logger.warn("[CallbackExample] Some requests didn't complete within the timeout"); + } + } catch (InterruptedException e) { + logger.error("Interrupted!", e); + } + + assertThat(receivedHashValues).containsAll(expectedHashValues); + } + + @Test + public void observableJavaOrchestrate() throws InterruptedException { + List receivedHashValues = new ArrayList<>(); + + final CountDownLatch completionTracker = new CountDownLatch(expectedHashValues.size()); // used to keep track of the progress of the subsequent calls + + Observable> observableUserIdService = userIdService.register(RxObservableInvokerProvider.class).request().accept(MediaType.APPLICATION_JSON).rx(RxObservableInvoker.class).get(new GenericType>() { + }).asObservable(); + + observableUserIdService.subscribe((List employeeIds) -> { + logger.info("[ObservableExample] id-service result: {}", employeeIds); + Observable.from(employeeIds).subscribe(id -> nameService.register(RxObservableInvokerProvider.class).resolveTemplate("userId", id).request().rx(RxObservableInvoker.class).get(String.class).asObservable() // gotten the name for the given + // userId + .doOnError((throwable) -> { + logger.warn("[ObservableExample] An error has occurred in the username request step {}", throwable.getMessage()); + }).subscribe(userName -> { + logger.info("[ObservableExample] name-service result: {}", userName); + hashService.register(RxObservableInvokerProvider.class).resolveTemplate("rawValue", userName + id).request().rx(RxObservableInvoker.class).get(String.class).asObservable() // gotten the hash value for + // userId+username + .doOnError((throwable) -> { + logger.warn("[ObservableExample] An error has occurred in the hashing request step {}", throwable.getMessage()); + }).subscribe(hashValue -> { + logger.info("[ObservableExample] hash-service result: {}", hashValue); + receivedHashValues.add(hashValue); + completionTracker.countDown(); + }); + })); + }); + + // wait for async calls to complete + try { + // wait for inner requests to complete in 10 seconds + if (!completionTracker.await(10, TimeUnit.SECONDS)) { + logger.warn("[CallbackExample] Some requests didn't complete within the timeout"); + } + } catch (InterruptedException e) { + logger.error("Interrupted!", e); + } + + assertThat(receivedHashValues).containsAll(expectedHashValues); + } + + @Test + public void flowableJavaOrchestrate() throws InterruptedException { + List receivedHashValues = new ArrayList<>(); + + final CountDownLatch completionTracker = new CountDownLatch(expectedHashValues.size()); // used to keep track of the progress of the subsequent calls + + Flowable> userIdFlowable = userIdService.register(RxFlowableInvokerProvider.class).request().rx(RxFlowableInvoker.class).get(new GenericType>() { + }); + + userIdFlowable.subscribe((List employeeIds) -> { + logger.info("[FlowableExample] id-service result: {}", employeeIds); + Flowable.fromIterable(employeeIds).subscribe(id -> { + nameService.register(RxFlowableInvokerProvider.class).resolveTemplate("userId", id).request().rx(RxFlowableInvoker.class).get(String.class) // gotten the name for the given userId + .doOnError((throwable) -> { + logger.warn("[FlowableExample] An error has occurred in the username request step {}", throwable.getMessage()); + }).subscribe(userName -> { + logger.info("[FlowableExample] name-service result: {}", userName); + hashService.register(RxFlowableInvokerProvider.class).resolveTemplate("rawValue", userName + id).request().rx(RxFlowableInvoker.class).get(String.class) // gotten the hash value for userId+username + .doOnError((throwable) -> { + logger.warn(" [FlowableExample] An error has occurred in the hashing request step!", throwable); + }).subscribe(hashValue -> { + logger.info("[FlowableExample] hash-service result: {}", hashValue); + receivedHashValues.add(hashValue); + completionTracker.countDown(); + }); + }); + }); + }); + + // wait for async calls to complete + try { + // wait for inner requests to complete in 10 seconds + if (!completionTracker.await(10, TimeUnit.SECONDS)) { + logger.warn("[CallbackExample] Some requests didn't complete within the timeout"); + } + } catch (InterruptedException e) { + logger.error("Interrupted!", e); + } + + assertThat(receivedHashValues).containsAll(expectedHashValues); + } + +} diff --git a/spring-jersey/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-jersey/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..21f180854c --- /dev/null +++ b/spring-jersey/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.server.config.RestConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = RestConfig.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-jinq/pom.xml b/spring-jinq/pom.xml index 30d8cef823..f142b3ee2f 100644 --- a/spring-jinq/pom.xml +++ b/spring-jinq/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-jinq 0.1-SNAPSHOT @@ -13,18 +13,6 @@ 1.0.0-SNAPSHOT - - - - org.springframework.boot - spring-boot-dependencies - 1.5.9.RELEASE - pom - import - - - - org.jinq @@ -71,9 +59,20 @@ + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + - UTF-8 - 1.8 + 1.5.9.RELEASE 1.8.22 diff --git a/spring-jinq/src/main/resources/logback.xml b/spring-jinq/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-jinq/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-jinq/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-jinq/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ccf774330f --- /dev/null +++ b/spring-jinq/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.jinq.JinqApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = JinqApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-jms/pom.xml b/spring-jms/pom.xml index 6547327161..814875f77b 100644 --- a/spring-jms/pom.xml +++ b/spring-jms/pom.xml @@ -1,5 +1,5 @@ + 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 spring-jms @@ -33,6 +33,14 @@ activemq-all ${activemq.version} + + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + diff --git a/spring-jms/src/main/resources/logback.xml b/spring-jms/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-jms/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-jms/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-jms/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..e13809f571 --- /dev/null +++ b/spring-jms/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:EmbeddedActiveMQ.xml"}) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-jooq/pom.xml b/spring-jooq/pom.xml index bd8bc6f404..744ae34cc8 100644 --- a/spring-jooq/pom.xml +++ b/spring-jooq/pom.xml @@ -1,28 +1,15 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-jooq - 0.0.1-SNAPSHOT - + + parent-boot-1 com.baeldung - parent-modules - 1.0.0-SNAPSHOT + 0.0.1-SNAPSHOT + ../parent-boot-1 - - - - - org.springframework.boot - spring-boot-dependencies - 1.4.4.RELEASE - pom - import - - - - @@ -55,6 +42,10 @@ org.springframework.boot spring-boot-starter-jooq + + org.springframework.boot + spring-boot-starter-test + @@ -62,11 +53,6 @@ spring-test test - - org.springframework.boot - spring-boot-starter-test - - @@ -151,8 +137,7 @@ - + org.eclipse.m2e lifecycle-mapping @@ -185,15 +170,29 @@ + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + 3.8.6 1.4.193 - 4.3.4.RELEASE + 4.3.17.RELEASE 1.0.0 1.5 1.0.0 - + 1.5.13.RELEASE + org.jooq.example.spring.Application \ No newline at end of file diff --git a/spring-jooq/src/main/resources/logback.xml b/spring-jooq/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-jooq/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java b/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java index 25317309ee..5e76fb3c93 100644 --- a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java +++ b/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java @@ -12,14 +12,16 @@ import org.jooq.impl.DSL; 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.dao.DataAccessException; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class) -@Transactional("transactionManager") +import com.baeldung.jooq.introduction.PersistenceContextIntegrationTest; + +@ContextConfiguration(classes = PersistenceContextIntegrationTest.class) +@Transactional(transactionManager = "transactionManager") +@RunWith(SpringJUnit4ClassRunner.class) public class SpringBootIntegrationTest { @Autowired diff --git a/spring-kafka/pom.xml b/spring-kafka/pom.xml index db0d7e6df9..3060dc00b3 100644 --- a/spring-kafka/pom.xml +++ b/spring-kafka/pom.xml @@ -1,5 +1,5 @@ + 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 spring-kafka diff --git a/spring-kafka/src/main/resources/logback.xml b/spring-kafka/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-kafka/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-kafka/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-kafka/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..40bf86c76f --- /dev/null +++ b/spring-kafka/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.kafka.KafkaApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = KafkaApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-katharsis/pom.xml b/spring-katharsis/pom.xml index 6addb614f5..39648a982c 100644 --- a/spring-katharsis/pom.xml +++ b/spring-katharsis/pom.xml @@ -45,12 +45,12 @@ org.reflections reflections - 0.9.10 + ${reflections.version} org.apache.commons commons-lang3 - 3.7 + ${commons-lang3.version} @@ -134,7 +134,9 @@ 3.0.2 + 0.9.10 1.6.1 + 3.7 diff --git a/spring-katharsis/src/main/resources/logback.xml b/spring-katharsis/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-katharsis/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-katharsis/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-katharsis/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..48081903b6 --- /dev/null +++ b/spring-katharsis/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-ldap/pom.xml b/spring-ldap/pom.xml index ab5f557736..3b2525d899 100644 --- a/spring-ldap/pom.xml +++ b/spring-ldap/pom.xml @@ -1,8 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - spring-ldap 0.1-SNAPSHOT jar @@ -13,17 +12,6 @@ 1.0.0-SNAPSHOT - - 2.3.1.RELEASE - 4.3.6.RELEASE - 1.5.5 - 0.9.15 - - - - spring-ldap - - @@ -101,15 +89,20 @@ org.springframework.data spring-data-ldap - 1.0.6.RELEASE + ${spring-data-ldap.version} org.springframework.data spring-data-jpa - 1.11.6.RELEASE + ${spring-data-jpa.version} + + spring-ldap + + + live @@ -128,7 +121,7 @@ **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/*LiveTest.java @@ -141,4 +134,14 @@ + + + 2.3.1.RELEASE + 4.3.6.RELEASE + 1.5.5 + 0.9.15 + 1.0.6.RELEASE + 1.11.6.RELEASE + + \ No newline at end of file diff --git a/spring-ldap/src/main/resources/logback.xml b/spring-ldap/src/main/resources/logback.xml index 32b78577ee..7bd5154680 100644 --- a/spring-ldap/src/main/resources/logback.xml +++ b/spring-ldap/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-ldap/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-ldap/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..9c233e6562 --- /dev/null +++ b/spring-ldap/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.ldap.javaconfig.AppConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = AppConfig.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mobile/pom.xml b/spring-mobile/pom.xml index 3d47bb106b..d65820594f 100644 --- a/spring-mobile/pom.xml +++ b/spring-mobile/pom.xml @@ -1,6 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 com.baeldung diff --git a/spring-mobile/src/main/resources/logback.xml b/spring-mobile/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mobile/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-mobile/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-mobile/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7f906bdbcd --- /dev/null +++ b/spring-mobile/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mockito/pom.xml b/spring-mockito/pom.xml index e27e25b4c8..d1fa7f410e 100644 --- a/spring-mockito/pom.xml +++ b/spring-mockito/pom.xml @@ -1,13 +1,12 @@ + 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 spring-mockito 0.0.1-SNAPSHOT jar - spring-mockito Injecting Mockito Mocks into Spring Beans @@ -25,13 +24,13 @@ org.mockito - mockito-all + mockito-core ${mockito.version} - 1.10.19 + 2.21.0 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 index 05cb43e4df..51db07fde7 100644 --- a/spring-mockito/src/main/java/com/baeldung/domain/util/MessageMatcher.java +++ b/spring-mockito/src/main/java/com/baeldung/domain/util/MessageMatcher.java @@ -3,7 +3,7 @@ package com.baeldung.domain.util; import com.baeldung.domain.model.Message; import org.mockito.ArgumentMatcher; -public class MessageMatcher extends ArgumentMatcher { +public class MessageMatcher implements ArgumentMatcher { private Message left; @@ -12,16 +12,11 @@ public class MessageMatcher extends ArgumentMatcher { } @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; + public boolean matches(Message right) { + return left.getFrom().equals(right.getFrom()) && + left.getTo().equals(right.getTo()) && + left.getText().equals(right.getText()) && + right.getDate() != null && + right.getId() != null; } } \ No newline at end of file diff --git a/spring-mockito/src/main/resources/logback.xml b/spring-mockito/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mockito/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-mockito/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java b/spring-mockito/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java index f30af140af..aeec57d136 100644 --- a/spring-mockito/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java +++ b/spring-mockito/src/test/java/com/baeldung/app/rest/FlowerControllerUnitTest.java @@ -1,17 +1,18 @@ package com.baeldung.app.rest; -import com.baeldung.app.api.Flower; -import com.baeldung.domain.service.FlowerService; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + 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 org.mockito.junit.MockitoJUnitRunner; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; +import com.baeldung.app.api.Flower; +import com.baeldung.domain.service.FlowerService; @RunWith(MockitoJUnitRunner.class) public class FlowerControllerUnitTest { 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 index e303c85caf..15e91d86b5 100644 --- a/spring-mockito/src/test/java/com/baeldung/app/rest/MessageControllerUnitTest.java +++ b/spring-mockito/src/test/java/com/baeldung/app/rest/MessageControllerUnitTest.java @@ -1,18 +1,19 @@ package com.baeldung.app.rest; +import static org.mockito.Mockito.times; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + 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 { @@ -37,6 +38,6 @@ public class MessageControllerUnitTest { message.setTo("you"); message.setText("Hello, you!"); - Mockito.verify(messageService, times(1)).deliverMessage(Matchers.argThat(new MessageMatcher(message))); + Mockito.verify(messageService, times(1)).deliverMessage(ArgumentMatchers.argThat(new MessageMatcher(message))); } } diff --git a/spring-mockito/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-mockito/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7ce9f70302 --- /dev/null +++ b/spring-mockito/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.MocksApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = MocksApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mustache/pom.xml b/spring-mustache/pom.xml index 45fee6b10e..9e4c528ee0 100644 --- a/spring-mustache/pom.xml +++ b/spring-mustache/pom.xml @@ -3,28 +3,18 @@ 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 spring-mustache - 0.0.1-SNAPSHOT jar - spring-mustache Demo project for Spring Boot - org.springframework.boot - spring-boot-starter-parent - 1.5.4.RELEASE - - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 - - UTF-8 - UTF-8 - 1.8 - - org.springframework.boot @@ -39,12 +29,12 @@ org.webjars bootstrap - 3.3.7 + ${bootstrap.version} org.fluttercode.datafactory datafactory - 0.8 + ${datafactory.version} @@ -57,5 +47,9 @@ - + + 3.3.7 + 0.8 + + diff --git a/spring-mustache/src/main/resources/logback.xml b/spring-mustache/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mustache/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationTests.java b/spring-mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationIntegrationTest.java similarity index 94% rename from spring-mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationTests.java rename to spring-mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationIntegrationTest.java index 9138dfe92b..1eecf58986 100644 --- a/spring-mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationTests.java +++ b/spring-mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationIntegrationTest.java @@ -13,7 +13,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -public class SpringMustacheApplicationTests { +public class SpringMustacheApplicationIntegrationTest { @Autowired private TestRestTemplate restTemplate; diff --git a/spring-mvc-email/README.md b/spring-mvc-email/README.md deleted file mode 100644 index aa880188d7..0000000000 --- a/spring-mvc-email/README.md +++ /dev/null @@ -1,17 +0,0 @@ -## Relevant articles: - -- [Guide to Spring Email](http://www.baeldung.com/spring-email) - -## Spring MVC Email - -Example Spring MVC project to send email from web form. - -### Installing and Running - -Just run the Spring Boot application. -Type http://localhost:8080 in your browser to open the application. - - -### Sending test emails - -Follow UI links to send simple email, email using template or email with attachment. diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java b/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java deleted file mode 100644 index 9078d44764..0000000000 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/app/config/AppConfig.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.spring.app.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.mail.SimpleMailMessage; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; -import org.springframework.web.servlet.view.UrlBasedViewResolver; - -/** - * Created with IntelliJ IDEA. - * User: Olga - */ -@Configuration -@ComponentScan("com.baeldung.spring") -@EnableWebMvc //tha same as -public class AppConfig extends WebMvcConfigurerAdapter { - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } - - @Bean - public UrlBasedViewResolver urlBasedViewResolver() { - UrlBasedViewResolver resolver = new UrlBasedViewResolver(); - resolver.setOrder(0); - resolver.setPrefix("/WEB-INF/views/"); - resolver.setSuffix(".jsp"); - resolver.setCache(false); - resolver.setViewClass(JstlView.class); - return resolver; - } - - @Bean - public InternalResourceViewResolver internalResourceViewResolver() { - InternalResourceViewResolver resolver = new InternalResourceViewResolver(); - resolver.setOrder(1); - resolver.setPrefix("/WEB-INF/views/"); - resolver.setSuffix(".jsp"); - resolver.setViewClass(JstlView.class); - return resolver; - } - - @Bean - public SimpleMailMessage templateSimpleMessage() { - SimpleMailMessage message = new SimpleMailMessage(); - message.setText("This is the test email template for your email:\n%s\n"); - return message; - } -} diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java b/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java deleted file mode 100644 index 656e237a9e..0000000000 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/HomeController.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung.spring.controllers; - -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * Created with IntelliJ IDEA. - * User: Olga - */ -@Controller -@RequestMapping({"/","/home"}) -public class HomeController { - - @RequestMapping(method = RequestMethod.GET) - public String showHomePage() { - return "home"; - } -} diff --git a/spring-mvc-email/src/main/resources/META-INF/application.xml b/spring-mvc-email/src/main/resources/META-INF/application.xml deleted file mode 100644 index 759a312bd4..0000000000 --- a/spring-mvc-email/src/main/resources/META-INF/application.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - SpringMVCEmail.war - SpringMVCEmail - - - - - web.war - SpringMVCEmailWeb - - - \ No newline at end of file diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/web.xml b/spring-mvc-email/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 4cd41216d9..0000000000 --- a/spring-mvc-email/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - simpleweb - org.springframework.web.servlet.DispatcherServlet - - contextClass - - org.springframework.web.context.support.AnnotationConfigWebApplicationContext - - - - contextConfigLocation - com.baeldung.spring.app.config.AppConfig - - 1 - - - - simpleweb - / - - - diff --git a/spring-mvc-forms-jsp/pom.xml b/spring-mvc-forms-jsp/pom.xml index 3c18403c71..5536314086 100644 --- a/spring-mvc-forms-jsp/pom.xml +++ b/spring-mvc-forms-jsp/pom.xml @@ -1,13 +1,11 @@ - + 4.0.0 com.baeldung 0.1-SNAPSHOT spring-mvc-forms-jsp - spring-mvc-forms-jsp war @@ -30,37 +28,31 @@ - javax.servlet javax.servlet-api ${javax.servlet-api.version} - javax.servlet.jsp javax.servlet.jsp-api ${javax.servlet.jsp-api.version} - javax.servlet jstl ${jstl.version} - mysql mysql-connector-java - 6.0.6 + ${mysql-connector-java.version} - org.hibernate hibernate-validator ${hibernate-validator.version} - commons-fileupload commons-fileupload @@ -71,9 +63,14 @@ jackson-databind ${jackson-databind.version} - - + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + + @@ -84,7 +81,6 @@ - org.apache.maven.plugins maven-war-plugin @@ -93,10 +89,8 @@ src/main/webapp spring-mvc-forms false - ${deploy-path} - spring-mvc-forms @@ -110,10 +104,9 @@ 2.3.1 3.1.0 6.0.10.Final - server default deploy directory 1.3.3 5.2.5.Final - 5.1.40 + 6.0.6 diff --git a/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/configuration/ApplicationConfiguration.java b/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/configuration/ApplicationConfiguration.java index b8b36df84e..2b2844e0de 100644 --- a/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/configuration/ApplicationConfiguration.java +++ b/spring-mvc-forms-jsp/src/main/java/com/baeldung/springmvcforms/configuration/ApplicationConfiguration.java @@ -14,7 +14,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @EnableWebMvc @ComponentScan(basePackages = {"com.baeldung.springmvcforms", "com.baeldung.jstl"}) -class ApplicationConfiguration implements WebMvcConfigurer { +public class ApplicationConfiguration implements WebMvcConfigurer { @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { diff --git a/spring-mvc-forms-jsp/src/main/resources/logback.xml b/spring-mvc-forms-jsp/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mvc-forms-jsp/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-mvc-forms-jsp/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-mvc-forms-jsp/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..c1e9b71550 --- /dev/null +++ b/spring-mvc-forms-jsp/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import com.baeldung.springmvcforms.configuration.ApplicationConfiguration; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = ApplicationConfiguration.class) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mvc-forms-thymeleaf/pom.xml b/spring-mvc-forms-thymeleaf/pom.xml index 31e5b6cd48..504ad1dcb2 100644 --- a/spring-mvc-forms-thymeleaf/pom.xml +++ b/spring-mvc-forms-thymeleaf/pom.xml @@ -1,21 +1,18 @@ + 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 spring-mvc-forms-thymeleaf - 0.0.1-SNAPSHOT jar - spring-mvc-forms-thymeleaf spring forms examples using thymeleaf - org.springframework.boot - spring-boot-starter-parent - 2.0.0.RELEASE - + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 @@ -41,36 +38,8 @@ - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.apache.maven.plugins - maven-surefire-plugin - - 3 - true - methods - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LiveTest.java - - - - - - - UTF-8 - UTF-8 3.0.9.RELEASE com.baeldung.sessionattrs.SessionAttrsApplication - diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/logback.xml b/spring-mvc-forms-thymeleaf/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextIntegrationTest.java b/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..da87a6830a --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung.listbindingexample; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.listbindingexample.ListBindingApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {ListBindingApplication.class}) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextIntegrationTest.java b/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..e6b0dbf98c --- /dev/null +++ b/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung.sessionattrs; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.sessionattrs.SessionAttrsApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {SessionAttrsApplication.class}) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mvc-java/README.md b/spring-mvc-java/README.md index b97b961e60..3a580202cf 100644 --- a/spring-mvc-java/README.md +++ b/spring-mvc-java/README.md @@ -28,7 +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) +- [Using Spring ResponseEntity to Manipulate the HTTP Response](http://www.baeldung.com/spring-response-entity) +- [Using Spring @ResponseStatus to Set HTTP Status Code](http://www.baeldung.com/spring-response-status) +- [Bootstrap a Web Application with Spring 5](https://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration) +- [Spring MVC Tutorial](https://www.baeldung.com/spring-mvc-tutorial) diff --git a/spring-mvc-java/pom.xml b/spring-mvc-java/pom.xml index 14ced24da7..9d3e0ca1b2 100644 --- a/spring-mvc-java/pom.xml +++ b/spring-mvc-java/pom.xml @@ -1,74 +1,58 @@ + 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 spring-mvc-java 0.1-SNAPSHOT spring-mvc-java + war - parent-boot-2 + parent-spring-5 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-spring-5 - - - org.springframework.boot - spring-boot-starter-thymeleaf + + org.springframework + spring-webmvc + ${spring.version} - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-devtools - - - org.springframework.boot - spring-boot-test - test - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-websocket - - - - - com.fasterxml.jackson.core - jackson-databind - - - javax.servlet javax.servlet-api + 4.0.1 + + + javax.servlet.jsp + javax.servlet.jsp-api + 2.3.3 javax.servlet jstl + ${jstl.version} + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} org.aspectj aspectjrt + 1.9.1 org.aspectj aspectjweaver + 1.9.1 @@ -80,6 +64,7 @@ net.sourceforge.htmlunit htmlunit + 2.32 commons-logging @@ -104,10 +89,12 @@ com.jayway.jsonpath json-path test + 2.4.0 org.springframework spring-test + ${spring.version} test @@ -120,27 +107,29 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} - - javax.el - javax.el-api - 2.2.4 - - - org.glassfish.web - javax.el - 2.2.4 - com.google.code.gson gson + 2.8.5 + + org.springframework + spring-websocket + ${spring.version} + + + + org.springframework + spring-messaging + ${spring.version} + @@ -156,11 +145,13 @@ maven-resources-plugin + ${maven-resources-plugin.version} org.apache.maven.plugins maven-war-plugin + ${maven-war-plugin.version} false @@ -207,7 +198,7 @@ **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/*LiveTest.java @@ -251,10 +242,10 @@ - 3.0.9.RELEASE + 3.0.9.RELEASE - 5.2.5.Final + 6.0.10.Final 5.1.40 @@ -273,15 +264,19 @@ 2.23 - 2.6 + 3.2.2 2.7 1.6.1 + 3.1.0 - 1.8.9 + 1.9.1 3.16-beta1 + + 3.0.1-b06 + diff --git a/spring-mvc-java/src/main/java/com/baeldung/config/AppInitializer.java b/spring-mvc-java/src/main/java/com/baeldung/config/AppInitializer.java index 9cf6e384f1..eec12f466f 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/config/AppInitializer.java +++ b/spring-mvc-java/src/main/java/com/baeldung/config/AppInitializer.java @@ -14,13 +14,20 @@ public class AppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); - context.setConfigLocation("org.baeldung.config"); + + context.scan("com.baeldung"); container.addListener(new ContextLoaderListener(context)); - ServletRegistration.Dynamic dispatcher = container.addServlet("java-servlet", new DispatcherServlet(context)); + ServletRegistration.Dynamic dispatcher = container.addServlet("mvc", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); - dispatcher.addMapping("/java-servlet/*"); + dispatcher.addMapping("/"); + + // final MultipartConfigElement multipartConfigElement = new + // MultipartConfigElement(TMP_FOLDER, MAX_UPLOAD_SIZE, + // MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2); + // + // appServlet.setMultipartConfig(multipartConfigElement); } } diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ApplicationConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ApplicationConfig.java deleted file mode 100644 index 261d5793dc..0000000000 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ApplicationConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.baeldung.spring.web.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; - -@EnableWebMvc -@Configuration -@ComponentScan(basePackages = { "com.baeldung.web.controller" }) -public class ApplicationConfig extends WebMvcConfigurerAdapter { - - public ApplicationConfig() { - super(); - } - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/").setViewName("index"); - } - - @Bean - public ViewResolver viewResolver() { - final InternalResourceViewResolver bean = new InternalResourceViewResolver(); - bean.setViewClass(JstlView.class); - bean.setPrefix("/WEB-INF/jsp/"); - bean.setSuffix(".jsp"); - return bean; - } -} \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ClientWebConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ClientWebConfig.java deleted file mode 100644 index de47f9f69e..0000000000 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ClientWebConfig.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.baeldung.spring.web.config; - -import javax.servlet.ServletContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Description; -import org.springframework.context.support.ResourceBundleMessageSource; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; -import org.thymeleaf.spring4.SpringTemplateEngine; -import org.thymeleaf.spring4.view.ThymeleafViewResolver; -import org.thymeleaf.templateresolver.ServletContextTemplateResolver; - -@EnableWebMvc -@Configuration -public class ClientWebConfig implements WebMvcConfigurer { - - public ClientWebConfig() { - super(); - } - - // API - - @Autowired - private ServletContext ctx; - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - - registry.addViewController("/sample.html"); - } - - @Bean - public ViewResolver thymeleafViewResolver() { - final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); - viewResolver.setTemplateEngine(templateEngine()); - viewResolver.setOrder(1); - return viewResolver; - } - - @Bean - public ViewResolver viewResolver() { - final InternalResourceViewResolver bean = new InternalResourceViewResolver(); - bean.setViewClass(JstlView.class); - bean.setPrefix("/WEB-INF/view/"); - bean.setSuffix(".jsp"); - bean.setOrder(0); - return bean; - } - - @Bean - @Description("Thymeleaf template resolver serving HTML 5") - public ServletContextTemplateResolver templateResolver() { - final ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(ctx); - templateResolver.setPrefix("/WEB-INF/templates/"); - templateResolver.setSuffix(".html"); - templateResolver.setTemplateMode("HTML5"); - return templateResolver; - } - - @Bean - @Description("Thymeleaf template engine with Spring integration") - public SpringTemplateEngine templateEngine() { - final SpringTemplateEngine templateEngine = new SpringTemplateEngine(); - templateEngine.setTemplateResolver(templateResolver()); - return templateEngine; - } - - @Bean - @Description("Spring message resolver") - public MessageSource messageSource() { - final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); - messageSource.setBasename("messages"); - return messageSource; - } - - @Override - public void addResourceHandlers(final ResourceHandlerRegistry registry) { - registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); - } - -} \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ContentManagementWebConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ContentManagementWebConfig.java deleted file mode 100644 index 498105ded1..0000000000 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ContentManagementWebConfig.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.baeldung.spring.web.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.MediaType; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.JstlView; - -@EnableWebMvc -@Configuration -public class ContentManagementWebConfig extends WebMvcConfigurerAdapter { - - public ContentManagementWebConfig() { - super(); - } - - // API - - @Override - public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) { - configurer.favorPathExtension(false).favorParameter(true).parameterName("mediaType").ignoreAcceptHeader(true).useJaf(false).defaultContentType(MediaType.APPLICATION_JSON).mediaType("xml", MediaType.APPLICATION_XML).mediaType("json", - MediaType.APPLICATION_JSON); - } - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/sample.html"); - } - - @Bean - public ViewResolver viewResolver() { - final InternalResourceViewResolver bean = new InternalResourceViewResolver(); - bean.setViewClass(JstlView.class); - bean.setPrefix("/WEB-INF/view/"); - bean.setSuffix(".jsp"); - bean.setOrder(0); - return bean; - } - -} diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java deleted file mode 100644 index 80ce22edd6..0000000000 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.baeldung.spring.web.config; - -import org.springframework.web.WebApplicationInitializer; -import org.springframework.web.context.ContextLoaderListener; -import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; -import org.springframework.web.context.support.GenericWebApplicationContext; -import org.springframework.web.servlet.DispatcherServlet; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; -import java.util.Set; - -public class MainWebAppInitializer implements WebApplicationInitializer { - - private static final String TMP_FOLDER = "/tmp"; - private static final int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; // 5 MB - - /** - * Register and configure all Servlet container components necessary to power the web application. - */ - @Override - public void onStartup(final ServletContext sc) throws ServletException { - - // Create the 'root' Spring application context - final AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); - root.scan("com.baeldung.spring.web.config"); - // root.getEnvironment().setDefaultProfiles("embedded"); - - sc.addListener(new ContextLoaderListener(root)); - - // Handles requests into the application - final ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(new GenericWebApplicationContext())); - appServlet.setLoadOnStartup(1); - - // final MultipartConfigElement multipartConfigElement = new - // MultipartConfigElement(TMP_FOLDER, MAX_UPLOAD_SIZE, - // MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2); - // - // appServlet.setMultipartConfig(multipartConfigElement); - - final Set mappingConflicts = appServlet.addMapping("/"); - if (!mappingConflicts.isEmpty()) { - throw new IllegalStateException("'appServlet' could not be mapped to '/' due " + "to an existing mapping. This is a known issue under Tomcat versions " + "<= 7.0.14; see https://issues.apache.org/bugzilla/show_bug.cgi?id=51278"); - } - } - -} diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java index 11be08a79d..191d721dfb 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java +++ b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java @@ -3,40 +3,105 @@ package com.baeldung.spring.web.config; import java.util.ArrayList; import java.util.List; +import javax.servlet.ServletContext; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Description; +import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.core.io.ClassPathResource; import org.springframework.http.MediaType; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.ResourceBundleViewResolver; import org.springframework.web.servlet.view.XmlViewResolver; import org.springframework.web.util.UrlPathHelper; -import com.baeldung.excel.*; +import org.thymeleaf.spring4.SpringTemplateEngine; +import org.thymeleaf.spring4.view.ThymeleafViewResolver; +import org.thymeleaf.templateresolver.ServletContextTemplateResolver; + +import com.baeldung.excel.ExcelPOIHelper; -@Configuration @EnableWebMvc -@ComponentScan("com.baeldung.web") -public class WebConfig extends WebMvcConfigurerAdapter { +@Configuration +@ComponentScan(basePackages = { "com.baeldung.web.controller" }) +public class WebConfig implements WebMvcConfigurer { - public WebConfig() { - super(); + @Autowired + private ServletContext ctx; + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("index"); + } + + @Bean + public ViewResolver thymeleafViewResolver() { + final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); + viewResolver.setTemplateEngine(templateEngine()); + viewResolver.setOrder(1); + return viewResolver; } - // @Bean - // public StandardServletMultipartResolver multipartResolver() { - // return new StandardServletMultipartResolver(); - // } + @Bean + public ViewResolver viewResolver() { + final InternalResourceViewResolver bean = new InternalResourceViewResolver(); + bean.setViewClass(JstlView.class); + bean.setPrefix("/WEB-INF/view/"); + bean.setSuffix(".jsp"); + bean.setOrder(0); + return bean; + } + @Bean + @Description("Thymeleaf template resolver serving HTML 5") + public ServletContextTemplateResolver templateResolver() { + final ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(ctx); + templateResolver.setPrefix("/WEB-INF/templates/"); + templateResolver.setSuffix(".html"); + templateResolver.setTemplateMode("HTML5"); + return templateResolver; + } + + @Bean + @Description("Thymeleaf template engine with Spring integration") + public SpringTemplateEngine templateEngine() { + final SpringTemplateEngine templateEngine = new SpringTemplateEngine(); + templateEngine.setTemplateResolver(templateResolver()); + return templateEngine; + } + + @Bean + @Description("Spring message resolver") + public MessageSource messageSource() { + final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); + messageSource.setBasename("messages"); + return messageSource; + } + + @Override + public void addResourceHandlers(final ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); + } + + @Override + public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) { + configurer.favorPathExtension(false).favorParameter(true).parameterName("mediaType").ignoreAcceptHeader(true).useRegisteredExtensionsOnly(false).defaultContentType(MediaType.APPLICATION_JSON).mediaType("xml", MediaType.APPLICATION_XML).mediaType("json", + MediaType.APPLICATION_JSON); + } @Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { @@ -45,23 +110,7 @@ public class WebConfig extends WebMvcConfigurerAdapter { return multipartResolver; } - - @Override - public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/sample.html"); - } - - @Bean - public ViewResolver internalResourceViewResolver() { - final InternalResourceViewResolver bean = new InternalResourceViewResolver(); - bean.setViewClass(JstlView.class); - bean.setPrefix("/WEB-INF/view/"); - bean.setSuffix(".jsp"); - bean.setOrder(2); - return bean; - } - + @Bean public ViewResolver xmlViewResolver() { final XmlViewResolver bean = new XmlViewResolver(); @@ -112,5 +161,4 @@ public class WebConfig extends WebMvcConfigurerAdapter { public ExcelPOIHelper excelPOIHelper() { return new ExcelPOIHelper(); } - -} +} \ No newline at end of file diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebSocketConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebSocketConfig.java index 93ec13da58..0793658e90 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebSocketConfig.java +++ b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebSocketConfig.java @@ -2,13 +2,13 @@ package com.baeldung.spring.web.config; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; -import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; @Configuration @EnableWebSocketMessageBroker -public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(final MessageBrokerRegistry config) { diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebSocketSendToUserConfig.java b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebSocketSendToUserConfig.java index 7f14380e5e..dbd52e20ba 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebSocketSendToUserConfig.java +++ b/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebSocketSendToUserConfig.java @@ -6,9 +6,9 @@ import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; import org.springframework.web.socket.server.support.DefaultHandshakeHandler; import javax.servlet.http.HttpSession; @@ -16,7 +16,7 @@ import java.util.Map; @Configuration @EnableWebSocketMessageBroker -public class WebSocketSendToUserConfig extends AbstractWebSocketMessageBrokerConfigurer { +public class WebSocketSendToUserConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/SampleController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/SampleController.java new file mode 100644 index 0000000000..c13986e005 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/SampleController.java @@ -0,0 +1,13 @@ +package com.baeldung.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class SampleController { + @GetMapping("/sample") + public String showForm() { + return "sample"; + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java b/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java index d4c15aead9..4b55bcc00f 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java +++ b/spring-mvc-java/src/main/java/com/baeldung/web/controller/WebsocketSendToUserController.java @@ -1,23 +1,19 @@ package com.baeldung.web.controller; -import com.google.gson.Gson; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.messaging.handler.annotation.MessageExceptionHandler; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.messaging.simp.SimpMessageSendingOperations; -import org.springframework.messaging.simp.annotation.SendToUser; -import org.springframework.stereotype.Controller; - import java.security.Principal; import java.util.Map; +import org.springframework.messaging.handler.annotation.MessageExceptionHandler; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.stereotype.Controller; + +import com.google.gson.Gson; + @Controller public class WebsocketSendToUserController { - @Autowired - private SimpMessageSendingOperations messagingTemplate; - private Gson gson = new Gson(); @MessageMapping("/message") diff --git a/spring-mvc-java/src/main/resources/logback.xml b/spring-mvc-java/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-mvc-java/src/main/resources/logback.xml +++ b/spring-mvc-java/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java b/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java index b628228b7e..384bd85ec6 100644 --- a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java +++ b/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java @@ -20,12 +20,12 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import com.baeldung.spring.web.config.ApplicationConfig; +import com.baeldung.spring.web.config.WebConfig; import com.baeldung.spring.web.config.WebConfig; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@ContextConfiguration(classes = { ApplicationConfig.class, WebConfig.class }) +@ContextConfiguration(classes = { WebConfig.class, WebConfig.class }) public class GreetControllerIntegrationTest { @Autowired diff --git a/spring-mvc-java/src/test/resources/logback-test.xml b/spring-mvc-java/src/test/resources/logback-test.xml index e0721aa890..e35a9680bb 100644 --- a/spring-mvc-java/src/test/resources/logback-test.xml +++ b/spring-mvc-java/src/test/resources/logback-test.xml @@ -3,7 +3,7 @@ - %date [%thread] %-5level %logger{6} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-mvc-kotlin/pom.xml b/spring-mvc-kotlin/pom.xml index cc2bd18255..59b60ebd3c 100644 --- a/spring-mvc-kotlin/pom.xml +++ b/spring-mvc-kotlin/pom.xml @@ -1,126 +1,83 @@ - - 4.0.0 - spring-mvc-kotlin - 0.1-SNAPSHOT - spring-mvc-kotlin - war + + 4.0.0 + spring-mvc-kotlin + spring-mvc-kotlin + war - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + + parent-kotlin + com.baeldung + 1.0.0-SNAPSHOT + ../parent-kotlin + - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - + + + org.springframework + spring-web + + + org.springframework + spring-webmvc + + + org.thymeleaf + thymeleaf + - - org.springframework - spring-web - ${spring.version} - - - org.springframework - spring-webmvc - ${spring.version} - - - org.thymeleaf - thymeleaf - ${thymeleaf.version} - + + org.thymeleaf + thymeleaf-spring4 + ${thymeleaf.version} + + + org.hibernate + hibernate-core + + + org.hibernate + hibernate-testing + test + + + com.h2database + h2 + test + + + org.springframework + spring-test + test + + - - org.thymeleaf - thymeleaf-spring4 - ${thymeleaf.version} - - - org.hibernate - hibernate-core - ${hibernate.version} - - - org.hibernate - hibernate-testing - ${hibernate.version} - test - - - com.h2database - h2 - ${h2.version} - test - - - org.springframework - spring-test - ${spring.version} - test - - + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + spring + jpa + + + + + org.jetbrains.kotlin + kotlin-maven-noarg + ${kotlin.version} + + + + + - - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/test/kotlin - - - kotlin-maven-plugin - org.jetbrains.kotlin - ${kotlin.version} - - - spring - jpa - - 1.8 - - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - - org.jetbrains.kotlin - kotlin-maven-allopen - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-maven-noarg - ${kotlin.version} - - - - - - - - UTF-8 - 5.2.15.Final - 1.2.30 - 4.3.10.RELEASE - 3.0.7.RELEASE - 1.4.196 - + + 3.0.7.RELEASE + \ No newline at end of file diff --git a/spring-mvc-kotlin/src/main/resources/logback.xml b/spring-mvc-kotlin/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mvc-kotlin/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-mvc-simple/README.md b/spring-mvc-simple/README.md index 3505fb8009..39053534fa 100644 --- a/spring-mvc-simple/README.md +++ b/spring-mvc-simple/README.md @@ -5,3 +5,4 @@ - [Spring 5 and Servlet 4 – The PushBuilder](http://www.baeldung.com/spring-5-push) - [Servlet Redirect vs Forward](http://www.baeldung.com/servlet-redirect-forward) - [Apache Tiles Integration with Spring MVC](http://www.baeldung.com/spring-mvc-apache-tiles) +- [Guide to Spring Email](http://www.baeldung.com/spring-email) diff --git a/spring-mvc-simple/pom.xml b/spring-mvc-simple/pom.xml index 08eab59540..bd63b5ed1c 100644 --- a/spring-mvc-simple/pom.xml +++ b/spring-mvc-simple/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 spring-mvc-simple war @@ -10,8 +10,8 @@ com.baeldung parent-spring-5 - 0.0.1-SNAPSHOT - ../parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 @@ -20,6 +20,15 @@ spring-oxm ${spring-oxm.version} + + org.springframework + spring-context-support + + + com.sun.mail + javax.mail + 1.6.1 + javax.servlet javax.servlet-api @@ -50,6 +59,11 @@ spring-webmvc ${spring.version} + + org.springframework + spring-tx + ${spring.version} + @@ -88,8 +102,8 @@ spring-jade4j ${jade.version} - - + + org.apache.tiles tiles-jsp ${apache-tiles.version} @@ -122,6 +136,14 @@ json ${json.version} + + org.apache.maven.surefire + surefire-logger-api + ${maven-surefire-plugin.version} + + test + true + @@ -158,28 +180,25 @@ - springMvcSimple + spring-mvc-simple 1.8 1.8 - UTF-8 3.2.0 3.7.0 2.21.0 1.2 2.3.2-b02 4.0.0 - 5.4.1.Final + 6.0.10.Final enter-location-of-server 1.3.2 - 1.8 3.0.7.RELEASE 2.4.12 2.3.27-incubating 1.2.5 - 5.0.2 1.0.2 1.9.0 2.9.4 diff --git a/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java index c28ee02eef..284be6c212 100644 --- a/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/configuration/ApplicationConfiguration.java @@ -8,6 +8,9 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.feed.RssChannelHttpMessageConverter; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.commons.CommonsMultipartResolver; @@ -20,10 +23,11 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; import java.util.ArrayList; import java.util.List; +import java.util.Properties; @Configuration @EnableWebMvc -@ComponentScan(basePackages = { "com.baeldung.springmvcforms", "com.baeldung.spring.controller", "com.baeldung.spring.validator" }) +@ComponentScan(basePackages = { "com.baeldung.springmvcforms", "com.baeldung.spring.controller", "com.baeldung.spring.validator", "com.baeldung.spring.mail" }) public class ApplicationConfiguration implements WebMvcConfigurer { @Override @@ -60,4 +64,29 @@ public class ApplicationConfiguration implements WebMvcConfigurer { converters.add(new RssChannelHttpMessageConverter()); converters.add(new JsonChannelHttpMessageConverter()); } + + @Bean + public SimpleMailMessage templateSimpleMessage() { + SimpleMailMessage message = new SimpleMailMessage(); + message.setText("This is the test email template for your email:\n%s\n"); + return message; + } + + @Bean + public JavaMailSender getJavaMailSender() { + JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setHost("smtp.gmail.com"); + mailSender.setPort(587); + + mailSender.setUsername("my.gmail@gmail.com"); + mailSender.setPassword("password"); + + Properties props = mailSender.getJavaMailProperties(); + props.put("mail.transport.protocol", "smtp"); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.starttls.enable", "true"); + props.put("mail.debug", "true"); + + return mailSender; + } } diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java similarity index 95% rename from spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java index ff828ca9ec..16d1202eef 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/controllers/MailController.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/MailController.java @@ -1,9 +1,8 @@ -package com.baeldung.spring.controllers; +package com.baeldung.spring.controller; import com.baeldung.spring.mail.EmailServiceImpl; -import com.baeldung.spring.web.dto.MailObject; +import com.baeldung.spring.domain.MailObject; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.SimpleMailMessage; import org.springframework.stereotype.Controller; @@ -62,6 +61,11 @@ public class MailController { props.put("additionalInfo", "To make sure that you send an attachment with this email, change the value for the 'attachment.invoice' in the application.properties file to the path to the attachment."); labels.put("sendAttachment", props); } + + @RequestMapping(method = RequestMethod.GET) + public String showEmailsPage() { + return "emails"; + } @RequestMapping(value = {"/send", "/sendTemplate", "/sendAttachment"}, method = RequestMethod.GET) public String createMail(Model model, diff --git a/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/push/PushController.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/push/PushController.java index b557c65c93..88448d4885 100644 --- a/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/push/PushController.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/controller/push/PushController.java @@ -11,9 +11,7 @@ public class PushController { @GetMapping(path = "/demoWithPush") public String demoWithPush(PushBuilder pushBuilder) { if (null != pushBuilder) { - pushBuilder.path("resources/logo.png") - .addHeader("Content-Type", "image/png") - .push(); + pushBuilder.path("resources/logo.png").push(); } return "demo"; } @@ -22,4 +20,4 @@ public class PushController { public String demoWithoutPush() { return "demo"; } -} \ No newline at end of file +} diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java similarity index 89% rename from spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java index 9623ff5d78..aceaf685fa 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/web/dto/MailObject.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/domain/MailObject.java @@ -1,7 +1,6 @@ -package com.baeldung.spring.web.dto; - -import org.hibernate.validator.constraints.Email; +package com.baeldung.spring.domain; +import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailService.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailService.java similarity index 100% rename from spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailService.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailService.java diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java similarity index 99% rename from spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java rename to spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java index ca418a7d90..039b970d8e 100644 --- a/spring-mvc-email/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java +++ b/spring-mvc-simple/src/main/java/com/baeldung/spring/mail/EmailServiceImpl.java @@ -8,9 +8,10 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; +import java.io.File; + import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; -import java.io.File; /** * Created by Olga on 7/15/2016. diff --git a/spring-mvc-email/src/main/resources/application.properties b/spring-mvc-simple/src/main/resources/application.properties similarity index 83% rename from spring-mvc-email/src/main/resources/application.properties rename to spring-mvc-simple/src/main/resources/application.properties index 61a42050e5..9a804c07d8 100644 --- a/spring-mvc-email/src/main/resources/application.properties +++ b/spring-mvc-simple/src/main/resources/application.properties @@ -1,3 +1,5 @@ +#this property file will have to be loaded explicitly as this is not a Spring Boot project + # Gmail SMTP spring.mail.host=smtp.gmail.com spring.mail.port=587 diff --git a/spring-mvc-simple/src/main/resources/logback.xml b/spring-mvc-simple/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mvc-simple/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/views/home.jsp b/spring-mvc-simple/src/main/webapp/WEB-INF/views/emails.jsp similarity index 100% rename from spring-mvc-email/src/main/webapp/WEB-INF/views/home.jsp rename to spring-mvc-simple/src/main/webapp/WEB-INF/views/emails.jsp diff --git a/spring-mvc-email/src/main/webapp/WEB-INF/views/mail/send.jsp b/spring-mvc-simple/src/main/webapp/WEB-INF/views/mail/send.jsp similarity index 100% rename from spring-mvc-email/src/main/webapp/WEB-INF/views/mail/send.jsp rename to spring-mvc-simple/src/main/webapp/WEB-INF/views/mail/send.jsp diff --git a/spring-mvc-velocity/pom.xml b/spring-mvc-velocity/pom.xml index 077d55c2de..dc5adcf3cf 100644 --- a/spring-mvc-velocity/pom.xml +++ b/spring-mvc-velocity/pom.xml @@ -1,148 +1,127 @@ - 4.0.0 - com.baeldung - 0.1-SNAPSHOT - spring-mvc-velocity + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + 0.1-SNAPSHOT + spring-mvc-velocity - spring-mvc-velocity - war + spring-mvc-velocity + war - - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + - + - + - - org.springframework - spring-web - ${spring.version} - - - org.springframework - spring-webmvc - ${spring.version} - - - org.springframework - spring-context-support - ${spring.version} - + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + + + org.springframework + spring-context-support + ${spring.version} + - + - - javax.servlet - javax.servlet-api - ${javax.servlet-api.version} - provided - + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + provided + - - org.apache.velocity - velocity - ${velocity.version} - + + org.apache.velocity + velocity + ${velocity.version} + - - org.apache.velocity - velocity-tools - ${velocity-tools.version} - - - commons-logging - commons-logging - - - + + org.apache.velocity + velocity-tools + ${velocity-tools.version} + + + commons-logging + commons-logging + + + - - - org.powermock - powermock-module-junit4 - ${powermock.version} - test - - - org.powermock - powermock-api-mockito - ${powermock.version} - test - - - org.springframework - spring-test - ${spring.version} - test - + + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + + + org.powermock + powermock-api-mockito + ${powermock.version} + test + + + org.springframework + spring-test + ${spring.version} + test + - + - - spring-mvc-velocity - - - src/main/resources - true - - + + spring-mvc-velocity + + + src/main/resources + true + + - + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + false + + + + - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - false - - + - - org.apache.maven.plugins - maven-surefire-plugin - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - - - - - - + + 1.6.6 - + 4.4.5 + 4.5.2 - + 3.1.0 + 1.7 + 2.0 + 2.9.0 + + 2.6 + 2.7 + 1.6.1 - - - - 1.6.6 - - 4.4.5 - 4.5.2 - - 3.1.0 - 1.7 - 2.0 - 2.9.0 - - - 2.6 - 2.7 - 1.6.1 - - + \ No newline at end of file diff --git a/spring-mvc-velocity/src/main/resources/logback.xml b/spring-mvc-velocity/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mvc-velocity/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..3649332870 --- /dev/null +++ b/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.mvc.velocity.spring.config.WebConfig; +import com.baeldung.mvc.velocity.test.config.TestConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { TestConfig.class, WebConfig.class }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mvc-webflow/pom.xml b/spring-mvc-webflow/pom.xml index f0a991912a..e1a279a787 100644 --- a/spring-mvc-webflow/pom.xml +++ b/spring-mvc-webflow/pom.xml @@ -1,10 +1,9 @@ + 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 0.1-SNAPSHOT spring-mvc-webflow - spring-mvc-webflow war @@ -36,26 +35,31 @@ - javax.servlet javax.servlet-api ${javax.servlet-api.version} provided - javax.servlet jstl ${jstl.version} runtime - org.slf4j log4j-over-slf4j ${org.slf4j.version} + + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + @@ -67,7 +71,6 @@ true - org.apache.maven.plugins @@ -78,15 +81,14 @@ - - 4.3.4.RELEASE + 5.0.1.RELEASE - 2.4.4.RELEASE + 2.5.0.RELEASE 3.1.0 1.2 @@ -94,8 +96,6 @@ 4.4.5 4.5.2 - 2.9.0 - 2.6 2.7 diff --git a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java index 434f49615b..46bf322f1d 100644 --- a/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java +++ b/spring-mvc-webflow/src/main/java/org/baeldung/spring/WebMvcConfig.java @@ -2,12 +2,10 @@ package org.baeldung.spring; 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.ImportResource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter; @@ -15,7 +13,7 @@ import org.springframework.webflow.mvc.servlet.FlowHandlerMapping; @EnableWebMvc @Configuration -public class WebMvcConfig extends WebMvcConfigurerAdapter { +public class WebMvcConfig implements WebMvcConfigurer { @Autowired private WebFlowConfig webFlowConfig; diff --git a/spring-mvc-webflow/src/main/resources/logback.xml b/spring-mvc-webflow/src/main/resources/logback.xml index 1146dade63..5ce05b3361 100644 --- a/spring-mvc-webflow/src/main/resources/logback.xml +++ b/spring-mvc-webflow/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml b/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml index ab9eb1a9b7..bad5c5f78c 100644 --- a/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml +++ b/spring-mvc-webflow/src/main/webapp/WEB-INF/flows/activation-flow.xml @@ -2,7 +2,7 @@ + http://www.springframework.org/schema/webflow/spring-webflow.xsd"> diff --git a/spring-mvc-webflow/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-mvc-webflow/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6f028c78d8 --- /dev/null +++ b/spring-mvc-webflow/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import org.baeldung.spring.WebFlowConfig; +import org.baeldung.spring.WebMvcConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {WebFlowConfig.class, WebMvcConfig.class}) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mvc-xml/README.md b/spring-mvc-xml/README.md index 6333b20e11..442a533d1b 100644 --- a/spring-mvc-xml/README.md +++ b/spring-mvc-xml/README.md @@ -10,7 +10,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Spring MVC Tutorial](http://www.baeldung.com/spring-mvc-tutorial) - [Servlet Session Timeout](http://www.baeldung.com/servlet-session-timeout) -- [Basic Forms with Spring MVC](http://www.baeldung.com/spring-mvc-form-tutorial) - [Returning Image/Media Data with Spring MVC](http://www.baeldung.com/spring-mvc-image-media-data) - [Geolocation by IP in Java](http://www.baeldung.com/geolocation-by-ip-with-maxmind) - [Guide to JavaServer Pages (JSP)](http://www.baeldung.com/jsp) diff --git a/spring-mvc-xml/pom.xml b/spring-mvc-xml/pom.xml index 8ec2ff10e5..7187b5c270 100644 --- a/spring-mvc-xml/pom.xml +++ b/spring-mvc-xml/pom.xml @@ -1,5 +1,5 @@ + 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 0.1-SNAPSHOT @@ -37,13 +37,6 @@ - - com.fasterxml.jackson.core - jackson-databind - 2.9.2 - - - javax.servlet javax.servlet-api @@ -64,8 +57,8 @@ ${hibernate-validator.version} - + com.fasterxml.jackson.core jackson-databind @@ -93,6 +86,13 @@ + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + @@ -125,12 +125,11 @@ + 5.0.2.RELEASE - 4.2.0.RELEASE - 5.2.5.Final 5.1.40 @@ -138,10 +137,10 @@ 4.5.2 - 5.3.3.Final + 6.0.10.Final 1.2 3.1.0 - 2.8.5 + 2.9.6 19.0 @@ -149,9 +148,6 @@ 2.5 2.8.0 - - 2.9.0 - 2.6 1.6.1 diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java index b5238b04d5..22260fca70 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java @@ -1,12 +1,14 @@ package com.baeldung.spring; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @ImportResource("classpath:webMvcConfig.xml") @Configuration -public class ClientWebConfig extends WebMvcConfigurerAdapter { +@ComponentScan +public class ClientWebConfig implements WebMvcConfigurer { public ClientWebConfig() { super(); diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java index f299c46dbc..7925fa451d 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java @@ -9,13 +9,13 @@ import org.springframework.context.support.MessageSourceResourceBundle; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; //@EnableWebMvc //@Configuration -public class ClientWebConfigJava extends WebMvcConfigurerAdapter { +public class ClientWebConfigJava implements WebMvcConfigurer { public ClientWebConfigJava() { super(); @@ -38,8 +38,6 @@ public class ClientWebConfigJava extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/sample.html"); } diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java deleted file mode 100644 index fa76933f8f..0000000000 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/EmployeeController.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.baeldung.spring.controller; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.servlet.ModelAndView; - -import com.baeldung.spring.form.Employee; - -@Controller -public class EmployeeController { - - Map employeeMap = new HashMap<>(); - - @RequestMapping(value = "/employee", method = RequestMethod.GET) - public ModelAndView showForm() { - return new ModelAndView("employeeHome", "employee", new Employee()); - } - - @RequestMapping(value = "/employee/{Id}", produces = { "application/json", "application/xml" }, method = RequestMethod.GET) - public @ResponseBody Employee getEmployeeById(@PathVariable final long Id) { - return employeeMap.get(Id); - } - - @RequestMapping(value = "/addEmployee", method = RequestMethod.POST) - public String submit(@ModelAttribute("employee") final Employee employee, final BindingResult result, final ModelMap model) { - if (result.hasErrors()) { - return "error"; - } - model.addAttribute("name", employee.getName()); - model.addAttribute("contactNumber", employee.getContactNumber()); - model.addAttribute("id", employee.getId()); - employeeMap.put(employee.getId(), employee); - return "employeeView"; - } - -} diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java index eeaddcf8e0..0e2fe48160 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java @@ -11,7 +11,8 @@ import org.springframework.web.bind.annotation.ResponseBody; import com.baeldung.spring.form.GeoIP; import com.baeldung.spring.service.RawDBDemoGeoIPLocationService; -@Controller +//@Controller +//add db file and uncomment to see the working example public class GeoIPTestController { private RawDBDemoGeoIPLocationService locationService; diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java deleted file mode 100644 index 66b2e9f185..0000000000 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Employee.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.baeldung.spring.form; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -public class Employee { - - private long id; - - @NotNull - @Size(min = 1) - private String name; - @NotNull - @Size(min = 1) - private String contactNumber; - - public Employee() { - super(); - } - - // - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - } - - public long getId() { - return id; - } - - public void setId(final long id) { - this.id = id; - } - - public String getContactNumber() { - return contactNumber; - } - - public void setContactNumber(final String contactNumber) { - this.contactNumber = contactNumber; - } - -} diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java index 01638fbe76..307a36b10f 100644 --- a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java +++ b/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java @@ -2,7 +2,8 @@ package com.baeldung.spring.form; import java.util.List; -import org.hibernate.validator.constraints.NotEmpty; +import javax.validation.constraints.NotEmpty; + import org.springframework.web.multipart.MultipartFile; public class Person { diff --git a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml b/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml index 75d5c1ecd6..8a0671ca87 100644 --- a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml +++ b/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml @@ -4,11 +4,11 @@ xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-4.3.xsd + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-4.3.xsd + http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc - http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"> + http://www.springframework.org/schema/mvc/spring-mvc.xsd"> diff --git a/spring-mvc-xml/src/main/resources/logback.xml b/spring-mvc-xml/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-mvc-xml/src/main/resources/logback.xml +++ b/spring-mvc-xml/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-mvc-xml/src/main/resources/webMvcConfig.xml b/spring-mvc-xml/src/main/resources/webMvcConfig.xml index 37aebe1d1d..4bdb405237 100644 --- a/spring-mvc-xml/src/main/resources/webMvcConfig.xml +++ b/spring-mvc-xml/src/main/resources/webMvcConfig.xml @@ -3,11 +3,11 @@ xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-4.3.xsd + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-4.3.xsd + http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc - http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd" + http://www.springframework.org/schema/mvc/spring-mvc.xsd" > diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp b/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp deleted file mode 100644 index 588678cdcf..0000000000 --- a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeHome.jsp +++ /dev/null @@ -1,33 +0,0 @@ -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> - - - -Form Example - Register an Employee - - -

    Welcome, Enter The Employee Details

    - - - - - - - - - - - - - - - - - - -
    Name
    Id
    Contact Number
    -
    - - - - \ No newline at end of file diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp b/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp deleted file mode 100644 index 1457bc5fc8..0000000000 --- a/spring-mvc-xml/src/main/webapp/WEB-INF/view/employeeView.jsp +++ /dev/null @@ -1,24 +0,0 @@ -<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> - - -Spring MVC Form Handling - - - -

    Submitted Employee Information

    - - - - - - - - - - - - - -
    Name :${name}
    ID :${id}
    Contact Number :${contactNumber}
    - - \ No newline at end of file diff --git a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java b/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java index 0e957f3400..0aa23842b1 100644 --- a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java +++ b/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java @@ -14,10 +14,12 @@ public class GeoIpIntegrationTest { @Test public void givenIP_whenFetchingCity_thenReturnsCityData() throws IOException, GeoIp2Exception { - File database = new File("your-path-to-db-file"); + + ClassLoader classLoader = getClass().getClassLoader(); + File database = new File(classLoader.getResource("GeoLite2-City.mmdb").getFile()); DatabaseReader dbReader = new DatabaseReader.Builder(database).build(); - InetAddress ipAddress = InetAddress.getByName("your-public-ip"); + InetAddress ipAddress = InetAddress.getByName("google.com"); CityResponse response = dbReader.city(ipAddress); String countryName = response.getCountry().getName(); diff --git a/spring-mvc-xml/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-mvc-xml/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ec34abd367 --- /dev/null +++ b/spring-mvc-xml/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.spring.ClientWebConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = ClientWebConfig.class) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb b/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb new file mode 100644 index 0000000000..6de839a7ed Binary files /dev/null and b/spring-mvc-xml/src/test/resources/GeoLite2-City.mmdb differ diff --git a/spring-mybatis/pom.xml b/spring-mybatis/pom.xml index 073c332705..7b8b66fef1 100644 --- a/spring-mybatis/pom.xml +++ b/spring-mybatis/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung spring-mybatis @@ -18,52 +18,57 @@ org.mybatis mybatis - 3.1.1 + ${mybatis.version} org.mybatis mybatis-spring - 1.1.1 + ${mybatis-spring.version} org.springframework spring-context-support - 3.1.1.RELEASE + ${spring.version} org.springframework spring-test - 3.1.1.RELEASE + ${spring.version} test mysql mysql-connector-java - 5.1.40 + ${mysql-connector.version} javax.servlet jstl - 1.2 + ${jstl.version} org.springframework spring-webmvc - 3.2.4.RELEASE + ${spring-webmvc.version} javax.servlet servlet-api - 2.5 - - - junit - junit - 3.8.1 - test + ${servlet.version} + spring-mybatis + + + 3.1.1 + 1.1.1 + 3.1.1.RELEASE + 3.2.4.RELEASE + 5.1.40 + 1.2 + 2.5 + diff --git a/spring-mybatis/src/main/java/com/baeldung/spring/mybatis/controller/StudentController.java b/spring-mybatis/src/main/java/com/baeldung/spring/mybatis/controller/StudentController.java index 427613f23f..c1e5579103 100644 --- a/spring-mybatis/src/main/java/com/baeldung/spring/mybatis/controller/StudentController.java +++ b/spring-mybatis/src/main/java/com/baeldung/spring/mybatis/controller/StudentController.java @@ -31,7 +31,7 @@ public class StudentController { @RequestMapping(value = "/signup", method = RequestMethod.POST) public String signup(@Validated @ModelAttribute("student") Student student, BindingResult result, ModelMap model) { - if (studentService.getStudentByUserName(student.getUserName())) { + if (studentService.getStudentByUserName(student.getUserName()) != null) { model.addAttribute("message", "User Name exists. Try another user name"); return "signup"; } else { @@ -50,7 +50,7 @@ public class StudentController { @RequestMapping(value = "/login", method = RequestMethod.POST) public String login(@ModelAttribute("studentLogin") StudentLogin studentLogin, BindingResult result, ModelMap model) { - boolean found = studentService.getStudentByLogin(studentLogin.getUserName(), studentLogin.getPassword()); + boolean found = studentService.getStudentByLogin(studentLogin.getUserName(), studentLogin.getPassword()) != null; if (found) { return "success"; } else { diff --git a/spring-mybatis/src/main/resources/logback.xml b/spring-mybatis/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-mybatis/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-protobuf/pom.xml b/spring-protobuf/pom.xml index 1dce122f27..1ab5048d27 100644 --- a/spring-protobuf/pom.xml +++ b/spring-protobuf/pom.xml @@ -1,5 +1,5 @@ + 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 spring-protobuf @@ -13,11 +13,6 @@ ../parent-boot-1 - - 3.1.0 - 1.4 - - com.google.protobuf @@ -52,4 +47,10 @@ + + + 3.1.0 + 1.4 + + diff --git a/spring-protobuf/src/main/resources/logback.xml b/spring-protobuf/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-protobuf/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-protobuf/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-protobuf/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..615ebd5f4a --- /dev/null +++ b/spring-protobuf/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.protobuf.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-quartz/pom.xml b/spring-quartz/pom.xml index 2a449ce494..47ffeccba9 100644 --- a/spring-quartz/pom.xml +++ b/spring-quartz/pom.xml @@ -1,6 +1,6 @@ + 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 @@ -17,41 +17,35 @@ ../parent-boot-1 - - 2.2.3 - - - org.springframework.boot spring-boot-starter-jdbc - org.springframework spring-context-support - org.quartz-scheduler quartz ${quartz.version} - - src/main/resources true - + + 2.2.3 + + \ No newline at end of file diff --git a/spring-quartz/src/main/resources/logback.xml b/spring-quartz/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-quartz/src/main/resources/logback.xml +++ b/spring-quartz/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-quartz/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-quartz/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..516cc587a7 --- /dev/null +++ b/spring-quartz/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.springquartz.SpringQuartzApp; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringQuartzApp.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-reactive-kotlin/README.md b/spring-reactive-kotlin/README.md new file mode 100644 index 0000000000..cf5debc617 --- /dev/null +++ b/spring-reactive-kotlin/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Spring Webflux with Kotlin](http://www.baeldung.com/spring-webflux-kotlin) diff --git a/spring-reactive-kotlin/pom.xml b/spring-reactive-kotlin/pom.xml new file mode 100644 index 0000000000..bff39984e0 --- /dev/null +++ b/spring-reactive-kotlin/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + spring-reactive-kotlin + jar + Spring Reactive Kotlin + Demo project for Spring Boot + + + parent-kotlin + com.baeldung + 1.0.0-SNAPSHOT + ../parent-kotlin + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-webflux + + + com.fasterxml.jackson.module + jackson-module-kotlin + + + + org.springframework.boot + spring-boot-starter-test + test + + + io.projectreactor + reactor-test + test + + + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + -Xjsr305=strict + + + + + + diff --git a/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Application.kt b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Application.kt new file mode 100644 index 0000000000..87ac7417b7 --- /dev/null +++ b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Application.kt @@ -0,0 +1,11 @@ +package com.baeldung.springreactivekotlin + +import org.springframework.boot.SpringApplication +import org.springframework.boot.autoconfigure.SpringBootApplication + +@SpringBootApplication +class Application + +fun main(args: Array) { + SpringApplication.run(Application::class.java, *args) +} diff --git a/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Controller.kt b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Controller.kt new file mode 100644 index 0000000000..76f8a62b85 --- /dev/null +++ b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Controller.kt @@ -0,0 +1,18 @@ +package com.baeldung.springreactivekotlin + +import org.springframework.http.MediaType +import org.springframework.stereotype.Controller +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.ResponseBody +import reactor.core.publisher.Flux + +@Controller +class Controller { + + @GetMapping(path = ["/numbers"], produces = [MediaType.APPLICATION_STREAM_JSON_VALUE]) + @ResponseBody + fun getNumbers(): Flux { + return Flux.range(1, 100) + } + +} diff --git a/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Device.kt b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Device.kt new file mode 100644 index 0000000000..9eb6eb8488 --- /dev/null +++ b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Device.kt @@ -0,0 +1,5 @@ +package com.baeldung.springreactivekotlin + +class Device(val name: String, val reading: Double) { + +} diff --git a/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/HomeSensorsHandler.kt b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/HomeSensorsHandler.kt new file mode 100644 index 0000000000..0ef9f37f1b --- /dev/null +++ b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/HomeSensorsHandler.kt @@ -0,0 +1,36 @@ +package com.baeldung.springreactivekotlin + +import org.springframework.stereotype.Component +import org.springframework.web.reactive.function.BodyInserters.fromObject +import org.springframework.web.reactive.function.server.ServerRequest +import org.springframework.web.reactive.function.server.ServerResponse +import reactor.core.publisher.Mono + +@Component +class HomeSensorsHandler { + + var data = mapOf("lamp" to arrayOf(0.7, 0.65, 0.67), "fridge" to arrayOf(12.0, 11.9, 12.5)) + + fun setLight(request: ServerRequest): Mono = ServerResponse.ok().build() + + fun getLightReading(request: ServerRequest): Mono = + ServerResponse.ok().body(fromObject(data["lamp"]!!)) + + fun getDeviceReadings(request: ServerRequest): Mono { + val id = request.pathVariable("id") + return ServerResponse.ok().body(fromObject(Device(id, 1.0))) + } + + fun getAllDevices(request: ServerRequest): Mono = + ServerResponse.ok().body(fromObject(arrayOf("lamp", "tv"))) + + fun getAllDeviceApi(request: ServerRequest): Mono = + ServerResponse.ok().body(fromObject(arrayListOf("kettle", "fridge"))) + + fun setDeviceReadingApi(request: ServerRequest): Mono { + return request.bodyToMono(Device::class.java).flatMap { it -> + ServerResponse.ok().body(fromObject(Device(it.name.toUpperCase(), it.reading))) + } + } + +} \ No newline at end of file diff --git a/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/HomeSensorsRouters.kt b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/HomeSensorsRouters.kt new file mode 100644 index 0000000000..27d87afd89 --- /dev/null +++ b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/HomeSensorsRouters.kt @@ -0,0 +1,32 @@ +package com.baeldung.springreactivekotlin + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.http.MediaType.APPLICATION_JSON +import org.springframework.http.MediaType.TEXT_HTML +import org.springframework.web.reactive.function.server.router + +@Configuration +class HomeSensorsRouters(private val handler: HomeSensorsHandler) { + + @Bean + fun roomsRouter() = router { + (accept(TEXT_HTML) and "/room").nest { + GET("/light", handler::getLightReading) + POST("/light", handler::setLight) + } + } + + @Bean + fun deviceRouter() = router { + accept(TEXT_HTML).nest { + (GET("/device/") or GET("/devices/")).invoke(handler::getAllDevices) + GET("/device/{id}", handler::getDeviceReadings) + } + (accept(APPLICATION_JSON) and "/api").nest { + (GET("/device/") or GET("/devices/")).invoke(handler::getAllDeviceApi) + POST("/device/", handler::setDeviceReadingApi) + } + } + +} diff --git a/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Routes.kt b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Routes.kt new file mode 100644 index 0000000000..9015fc5df8 --- /dev/null +++ b/spring-reactive-kotlin/src/main/kotlin/com/baeldung/springreactivekotlin/Routes.kt @@ -0,0 +1,16 @@ +package com.baeldung.springreactivekotlin + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.web.reactive.function.server.ServerResponse +import org.springframework.web.reactive.function.server.router + +import org.springframework.web.reactive.function.BodyInserters.fromObject + +@Configuration +class SimpleRoute { + @Bean + fun route() = router { + GET("/route") { _ -> ServerResponse.ok().body(fromObject(arrayOf(1, 2, 3))) } + } +} \ No newline at end of file diff --git a/spring-reactive-kotlin/src/main/resources/logback.xml b/spring-reactive-kotlin/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-reactive-kotlin/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-reactive-kotlin/src/test/kotlin/RoutesTest.kt b/spring-reactive-kotlin/src/test/kotlin/RoutesTest.kt new file mode 100644 index 0000000000..ba640070e3 --- /dev/null +++ b/spring-reactive-kotlin/src/test/kotlin/RoutesTest.kt @@ -0,0 +1,35 @@ +package veontomo + +import com.baeldung.springreactivekotlin.SimpleRoute +import org.junit.Before +import org.junit.Test +import org.springframework.test.web.reactive.server.WebTestClient + +class RoutesTest { + + lateinit var client: WebTestClient + + @Before + fun init() { + this.client = WebTestClient.bindToRouterFunction(SimpleRoute().route()).build() + } + + + @Test + fun whenRequestToRoute_thenStatusShouldBeOk() { + client.get() + .uri("/route") + .exchange() + .expectStatus().isOk + } + + + @Test + fun whenRequestToRoute_thenBodyShouldContainArray123() { + client.get() + .uri("/route") + .exchange() + .expectBody() + .json("[1, 2, 3]") + } +} \ No newline at end of file diff --git a/spring-reactor/pom.xml b/spring-reactor/pom.xml index cedaa5e381..f6db404656 100644 --- a/spring-reactor/pom.xml +++ b/spring-reactor/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung spring-reactor diff --git a/spring-reactor/src/main/resources/logback.xml b/spring-reactor/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-reactor/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-reactor/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-reactor/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7f906bdbcd --- /dev/null +++ b/spring-reactor/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/pom.xml b/spring-remoting/pom.xml index 150c1a771c..9f05bc91d2 100644 --- a/spring-remoting/pom.xml +++ b/spring-remoting/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung spring-remoting @@ -33,7 +32,7 @@ remoting-hessian-burlap remoting-amqp remoting-jms - spring-remoting-rmi + remoting-rmi \ No newline at end of file diff --git a/spring-remoting/remoting-amqp/pom.xml b/spring-remoting/remoting-amqp/pom.xml index 3ada2337ee..f52959046a 100644 --- a/spring-remoting/remoting-amqp/pom.xml +++ b/spring-remoting/remoting-amqp/pom.xml @@ -1,17 +1,17 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + remoting-amqp + pom + remoting-amqp + spring-remoting com.baeldung 1.0-SNAPSHOT - 4.0.0 - remoting-amqp - pom - - - remoting-amqp remoting-amqp-server remoting-amqp-client diff --git a/spring-remoting/remoting-amqp/remoting-amqp-client/pom.xml b/spring-remoting/remoting-amqp/remoting-amqp-client/pom.xml index 9a2d0bf9cc..98e0bc5df5 100644 --- a/spring-remoting/remoting-amqp/remoting-amqp-client/pom.xml +++ b/spring-remoting/remoting-amqp/remoting-amqp-client/pom.xml @@ -1,21 +1,17 @@ + 4.0.0 + + remoting-amqp-client + jar + remoting-amqp-client + http://maven.apache.org + remoting-amqp com.baeldung 1.0-SNAPSHOT - 4.0.0 - - remoting-amqp-client - jar - - remoting-amqp-client - http://maven.apache.org - - - UTF-8 - @@ -30,7 +26,8 @@ com.baeldung - api + remoting-http-api + ${project.version} diff --git a/spring-remoting/remoting-amqp/remoting-amqp-client/src/main/resources/logback.xml b/spring-remoting/remoting-amqp/remoting-amqp-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-amqp/remoting-amqp-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-amqp/remoting-amqp-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-amqp/remoting-amqp-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2de3ed94d1 --- /dev/null +++ b/spring-remoting/remoting-amqp/remoting-amqp-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.client.AmqpClient; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AmqpClient.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/remoting-amqp/remoting-amqp-server/pom.xml b/spring-remoting/remoting-amqp/remoting-amqp-server/pom.xml index b926fd3d79..7fe276f824 100644 --- a/spring-remoting/remoting-amqp/remoting-amqp-server/pom.xml +++ b/spring-remoting/remoting-amqp/remoting-amqp-server/pom.xml @@ -1,26 +1,22 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + remoting-amqp-server + jar + remoting-amqp-server + http://maven.apache.org + remoting-amqp com.baeldung 1.0-SNAPSHOT - 4.0.0 - - remoting-amqp-server - jar - - remoting-amqp-server - http://maven.apache.org - - - UTF-8 - com.baeldung - api + remoting-http-api ${project.version} @@ -29,13 +25,13 @@ com.baeldung - api - 1.0-SNAPSHOT - - - com.baeldung - spring-remoting-http-server - 1.0-SNAPSHOT + remoting-http-server + ${remoting-http-server.version} + + + 1.0-SNAPSHOT + + diff --git a/spring-remoting/remoting-amqp/remoting-amqp-server/src/main/resources/logback.xml b/spring-remoting/remoting-amqp/remoting-amqp-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-amqp/remoting-amqp-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-amqp/remoting-amqp-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-amqp/remoting-amqp-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..5dc6d1df75 --- /dev/null +++ b/spring-remoting/remoting-amqp/remoting-amqp-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.server.AmqpServer; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AmqpServer.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/remoting-hessian-burlap/pom.xml b/spring-remoting/remoting-hessian-burlap/pom.xml index 682e460880..6cb5a51812 100644 --- a/spring-remoting/remoting-hessian-burlap/pom.xml +++ b/spring-remoting/remoting-hessian-burlap/pom.xml @@ -2,19 +2,18 @@ - + 4.0.0 + remoting-hessian-burlap + pom + + spring-remoting com.baeldung 1.0-SNAPSHOT - pom + - server - client + remoting-hessian-burlap-server + remoting-hessian-burlap-client - 4.0.0 - - remoting-hessian-burlap - - \ No newline at end of file diff --git a/spring-remoting/remoting-hessian-burlap/client/pom.xml b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/pom.xml similarity index 94% rename from spring-remoting/remoting-hessian-burlap/client/pom.xml rename to spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/pom.xml index 1ae9b10019..f337d5e51f 100644 --- a/spring-remoting/remoting-hessian-burlap/client/pom.xml +++ b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/pom.xml @@ -24,7 +24,8 @@ ${project.groupId} - api + remoting-http-api + ${project.version} com.caucho diff --git a/spring-remoting/remoting-hessian-burlap/client/src/main/java/com/baeldung/client/BurlapClient.java b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/main/java/com/baeldung/client/BurlapClient.java similarity index 100% rename from spring-remoting/remoting-hessian-burlap/client/src/main/java/com/baeldung/client/BurlapClient.java rename to spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/main/java/com/baeldung/client/BurlapClient.java diff --git a/spring-remoting/remoting-hessian-burlap/client/src/main/java/com/baeldung/client/HessianClient.java b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/main/java/com/baeldung/client/HessianClient.java similarity index 100% rename from spring-remoting/remoting-hessian-burlap/client/src/main/java/com/baeldung/client/HessianClient.java rename to spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/main/java/com/baeldung/client/HessianClient.java diff --git a/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/main/resources/logback.xml b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-hessian-burlap/client/src/test/java/com/baeldung/client/CabBookingServiceIntegrationTest.java b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/test/java/com/baeldung/client/CabBookingServiceIntegrationTest.java similarity index 100% rename from spring-remoting/remoting-hessian-burlap/client/src/test/java/com/baeldung/client/CabBookingServiceIntegrationTest.java rename to spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/test/java/com/baeldung/client/CabBookingServiceIntegrationTest.java diff --git a/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..1aec444aa0 --- /dev/null +++ b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.client.BurlapClient; +import com.baeldung.client.HessianClient; + +@SpringBootTest(classes = {BurlapClient.class, HessianClient.class}) +@RunWith(SpringRunner.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/remoting-hessian-burlap/client/src/test/resources/application.properties b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/test/resources/application.properties similarity index 100% rename from spring-remoting/remoting-hessian-burlap/client/src/test/resources/application.properties rename to spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-client/src/test/resources/application.properties diff --git a/spring-remoting/remoting-hessian-burlap/server/pom.xml b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/pom.xml similarity index 93% rename from spring-remoting/remoting-hessian-burlap/server/pom.xml rename to spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/pom.xml index f1fed73ed8..5b6e03348f 100644 --- a/spring-remoting/remoting-hessian-burlap/server/pom.xml +++ b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/pom.xml @@ -14,7 +14,7 @@ com.baeldung - spring-remoting-http-server + remoting-http-server ${project.version} diff --git a/spring-remoting/remoting-hessian-burlap/server/src/main/java/com/baeldung/server/Server.java b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/src/main/java/com/baeldung/server/Server.java similarity index 100% rename from spring-remoting/remoting-hessian-burlap/server/src/main/java/com/baeldung/server/Server.java rename to spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/src/main/java/com/baeldung/server/Server.java diff --git a/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/src/main/resources/logback.xml b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..f1aad1f601 --- /dev/null +++ b/spring-remoting/remoting-hessian-burlap/remoting-hessian-burlap-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.server.Server; + +@SpringBootTest(classes = Server.class) +@RunWith(SpringRunner.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/remoting-http/pom.xml b/spring-remoting/remoting-http/pom.xml index 439f6782ba..3262736ec8 100644 --- a/spring-remoting/remoting-http/pom.xml +++ b/spring-remoting/remoting-http/pom.xml @@ -3,17 +3,19 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + remoting-http + Parent for all modules related to HTTP Spring Remoting. + pom + com.baeldung spring-remoting 1.0-SNAPSHOT - spring-remoting-http - Parent for all modules related to HTTP Spring Remoting. - pom + - server - client - api + remoting-http-server + remoting-http-client + remoting-http-api \ No newline at end of file diff --git a/spring-remoting/remoting-http/api/pom.xml b/spring-remoting/remoting-http/remoting-http-api/pom.xml similarity index 75% rename from spring-remoting/remoting-http/api/pom.xml rename to spring-remoting/remoting-http/remoting-http-api/pom.xml index 633217f7de..579255060d 100644 --- a/spring-remoting/remoting-http/api/pom.xml +++ b/spring-remoting/remoting-http/remoting-http-api/pom.xml @@ -2,13 +2,15 @@ - - spring-remoting-http + 4.0.0 + remoting-http-api + remoting-http-api + API definition shared between client and server. + + + remoting-http com.baeldung 1.0-SNAPSHOT - 4.0.0 - api - spring-remoting-http-api - API definition shared between client and server. + \ No newline at end of file diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java b/spring-remoting/remoting-http/remoting-http-api/src/main/java/com/baeldung/api/Booking.java similarity index 100% rename from spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/Booking.java rename to spring-remoting/remoting-http/remoting-http-api/src/main/java/com/baeldung/api/Booking.java diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/BookingException.java b/spring-remoting/remoting-http/remoting-http-api/src/main/java/com/baeldung/api/BookingException.java similarity index 100% rename from spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/BookingException.java rename to spring-remoting/remoting-http/remoting-http-api/src/main/java/com/baeldung/api/BookingException.java diff --git a/spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java b/spring-remoting/remoting-http/remoting-http-api/src/main/java/com/baeldung/api/CabBookingService.java similarity index 100% rename from spring-remoting/remoting-http/api/src/main/java/com/baeldung/api/CabBookingService.java rename to spring-remoting/remoting-http/remoting-http-api/src/main/java/com/baeldung/api/CabBookingService.java diff --git a/spring-remoting/remoting-http/client/pom.xml b/spring-remoting/remoting-http/remoting-http-client/pom.xml similarity index 82% rename from spring-remoting/remoting-http/client/pom.xml rename to spring-remoting/remoting-http/remoting-http-client/pom.xml index 94a536fc18..9a6e98ffdd 100644 --- a/spring-remoting/remoting-http/client/pom.xml +++ b/spring-remoting/remoting-http/remoting-http-client/pom.xml @@ -3,14 +3,15 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - + remoting-http-client + Shows how to invoke a remote service using Spring Remoting HTTP. + com.baeldung - spring-remoting-http + remoting-http 1.0-SNAPSHOT - spring-remoting-http-client - Shows how to invoke a remote service using Spring Remoting HTTP. + org.springframework.boot @@ -24,7 +25,8 @@ ${project.groupId} - api + remoting-http-api + ${project.version} \ No newline at end of file diff --git a/spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Client.java b/spring-remoting/remoting-http/remoting-http-client/src/main/java/com/baeldug/client/Client.java similarity index 100% rename from spring-remoting/remoting-http/client/src/main/java/com/baeldug/client/Client.java rename to spring-remoting/remoting-http/remoting-http-client/src/main/java/com/baeldug/client/Client.java diff --git a/spring-remoting/remoting-http/remoting-http-client/src/main/resources/logback.xml b/spring-remoting/remoting-http/remoting-http-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-http/remoting-http-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-http/server/pom.xml b/spring-remoting/remoting-http/remoting-http-server/pom.xml similarity index 78% rename from spring-remoting/remoting-http/server/pom.xml rename to spring-remoting/remoting-http/remoting-http-server/pom.xml index 517f4451f7..53d27a5efa 100644 --- a/spring-remoting/remoting-http/server/pom.xml +++ b/spring-remoting/remoting-http/remoting-http-server/pom.xml @@ -3,13 +3,15 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + remoting-http-server + Shows how to expose a service using Spring Remoting HTTP. + com.baeldung - spring-remoting-http + remoting-http 1.0-SNAPSHOT - spring-remoting-http-server - Shows how to expose a service using Spring Remoting HTTP. + org.springframework.boot @@ -17,7 +19,8 @@ ${project.groupId} - api + remoting-http-api + ${project.version} \ No newline at end of file diff --git a/spring-remoting/remoting-http/server/readme.md b/spring-remoting/remoting-http/remoting-http-server/readme.md similarity index 100% rename from spring-remoting/remoting-http/server/readme.md rename to spring-remoting/remoting-http/remoting-http-server/readme.md diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java b/spring-remoting/remoting-http/remoting-http-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java similarity index 100% rename from spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java rename to spring-remoting/remoting-http/remoting-http-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java diff --git a/spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/Server.java b/spring-remoting/remoting-http/remoting-http-server/src/main/java/com/baeldung/server/Server.java similarity index 100% rename from spring-remoting/remoting-http/server/src/main/java/com/baeldung/server/Server.java rename to spring-remoting/remoting-http/remoting-http-server/src/main/java/com/baeldung/server/Server.java diff --git a/spring-remoting/remoting-http/remoting-http-server/src/main/resources/logback.xml b/spring-remoting/remoting-http/remoting-http-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-http/remoting-http-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-http/remoting-http-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-http/remoting-http-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..f1aad1f601 --- /dev/null +++ b/spring-remoting/remoting-http/remoting-http-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.server.Server; + +@SpringBootTest(classes = Server.class) +@RunWith(SpringRunner.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/remoting-jms/remoting-jms-client/pom.xml b/spring-remoting/remoting-jms/remoting-jms-client/pom.xml index 01b7bea657..ed27282a38 100644 --- a/spring-remoting/remoting-jms/remoting-jms-client/pom.xml +++ b/spring-remoting/remoting-jms/remoting-jms-client/pom.xml @@ -28,7 +28,8 @@ com.baeldung - api + remoting-http-api + ${project.version} diff --git a/spring-remoting/remoting-jms/remoting-jms-client/src/main/resources/logback.xml b/spring-remoting/remoting-jms/remoting-jms-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-jms/remoting-jms-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-jms/remoting-jms-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..a94e639dc8 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.client.JmsClient; + +@SpringBootTest(classes = JmsClient.class) +@RunWith(SpringRunner.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/remoting-jms/remoting-jms-server/pom.xml b/spring-remoting/remoting-jms/remoting-jms-server/pom.xml index 8feac4df57..7657267f1d 100644 --- a/spring-remoting/remoting-jms/remoting-jms-server/pom.xml +++ b/spring-remoting/remoting-jms/remoting-jms-server/pom.xml @@ -28,11 +28,7 @@ com.baeldung - api - - - com.baeldung - api + remoting-http-api ${project.version} diff --git a/spring-remoting/remoting-jms/remoting-jms-server/src/main/resources/logback.xml b/spring-remoting/remoting-jms/remoting-jms-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-jms/remoting-jms-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-jms/remoting-jms-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..5c9cc5f872 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.server.JmsServer; + +@SpringBootTest(classes = JmsServer.class) +@RunWith(SpringRunner.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/spring-remoting-rmi/pom.xml b/spring-remoting/remoting-rmi/pom.xml similarity index 86% rename from spring-remoting/spring-remoting-rmi/pom.xml rename to spring-remoting/remoting-rmi/pom.xml index 723158775f..cd15a6ec60 100644 --- a/spring-remoting/spring-remoting-rmi/pom.xml +++ b/spring-remoting/remoting-rmi/pom.xml @@ -2,18 +2,18 @@ - + 4.0.0 + pom + remoting-rmi + + spring-remoting com.baeldung 1.0-SNAPSHOT - 4.0.0 - pom - + + remoting-rmi-server remoting-rmi-client - spring-remoting-rmi - - \ No newline at end of file diff --git a/spring-remoting/spring-remoting-rmi/remoting-rmi-client/pom.xml b/spring-remoting/remoting-rmi/remoting-rmi-client/pom.xml similarity index 86% rename from spring-remoting/spring-remoting-rmi/remoting-rmi-client/pom.xml rename to spring-remoting/remoting-rmi/remoting-rmi-client/pom.xml index 003976dc7b..1e3cd4b977 100644 --- a/spring-remoting/spring-remoting-rmi/remoting-rmi-client/pom.xml +++ b/spring-remoting/remoting-rmi/remoting-rmi-client/pom.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - spring-remoting-rmi + remoting-rmi com.baeldung 1.0-SNAPSHOT @@ -24,7 +24,8 @@ com.baeldung - api + remoting-http-api + ${project.version} \ No newline at end of file diff --git a/spring-remoting/spring-remoting-rmi/remoting-rmi-client/src/main/java/com/baeldung/client/RmiClient.java b/spring-remoting/remoting-rmi/remoting-rmi-client/src/main/java/com/baeldung/client/RmiClient.java similarity index 100% rename from spring-remoting/spring-remoting-rmi/remoting-rmi-client/src/main/java/com/baeldung/client/RmiClient.java rename to spring-remoting/remoting-rmi/remoting-rmi-client/src/main/java/com/baeldung/client/RmiClient.java diff --git a/spring-remoting/remoting-rmi/remoting-rmi-client/src/main/resources/logback.xml b/spring-remoting/remoting-rmi/remoting-rmi-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-rmi/remoting-rmi-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-rmi/remoting-rmi-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-rmi/remoting-rmi-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..3460792fc6 --- /dev/null +++ b/spring-remoting/remoting-rmi/remoting-rmi-client/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.client.RmiClient; + +@SpringBootTest(classes = RmiClient.class) +@RunWith(SpringRunner.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-remoting/spring-remoting-rmi/remoting-rmi-server/pom.xml b/spring-remoting/remoting-rmi/remoting-rmi-server/pom.xml similarity index 83% rename from spring-remoting/spring-remoting-rmi/remoting-rmi-server/pom.xml rename to spring-remoting/remoting-rmi/remoting-rmi-server/pom.xml index f1633e5dc2..68b01829e1 100644 --- a/spring-remoting/spring-remoting-rmi/remoting-rmi-server/pom.xml +++ b/spring-remoting/remoting-rmi/remoting-rmi-server/pom.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - spring-remoting-rmi + remoting-rmi com.baeldung 1.0-SNAPSHOT @@ -28,11 +28,7 @@ com.baeldung - api - - - com.baeldung - api + remoting-http-api ${project.version} diff --git a/spring-remoting/spring-remoting-rmi/remoting-rmi-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java b/spring-remoting/remoting-rmi/remoting-rmi-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java similarity index 100% rename from spring-remoting/spring-remoting-rmi/remoting-rmi-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java rename to spring-remoting/remoting-rmi/remoting-rmi-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java diff --git a/spring-remoting/spring-remoting-rmi/remoting-rmi-server/src/main/java/com/baeldung/server/RmiServer.java b/spring-remoting/remoting-rmi/remoting-rmi-server/src/main/java/com/baeldung/server/RmiServer.java similarity index 100% rename from spring-remoting/spring-remoting-rmi/remoting-rmi-server/src/main/java/com/baeldung/server/RmiServer.java rename to spring-remoting/remoting-rmi/remoting-rmi-server/src/main/java/com/baeldung/server/RmiServer.java diff --git a/spring-remoting/remoting-rmi/remoting-rmi-server/src/main/resources/logback.xml b/spring-remoting/remoting-rmi/remoting-rmi-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-remoting/remoting-rmi/remoting-rmi-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-rmi/remoting-rmi-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-remoting/remoting-rmi/remoting-rmi-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2063dd5e6e --- /dev/null +++ b/spring-remoting/remoting-rmi/remoting-rmi-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.server.RmiServer; + +@SpringBootTest(classes = RmiServer.class) +@RunWith(SpringRunner.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-rest-angular/pom.xml b/spring-rest-angular/pom.xml index 090f09de3b..7aedfa486b 100644 --- a/spring-rest-angular/pom.xml +++ b/spring-rest-angular/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 spring-rest-angular spring-rest-angular diff --git a/spring-rest-angular/src/main/resources/logback.xml b/spring-rest-angular/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-rest-angular/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-rest-angular/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-rest-angular/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..228d0019bd --- /dev/null +++ b/spring-rest-angular/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.web.main.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-rest-embedded-tomcat/pom.xml b/spring-rest-embedded-tomcat/pom.xml index 8fbecb86e8..a8c53dbc3a 100644 --- a/spring-rest-embedded-tomcat/pom.xml +++ b/spring-rest-embedded-tomcat/pom.xml @@ -1,20 +1,18 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung.embedded - SpringRestTomcat - 0.0.1-SNAPSHOT - + spring-rest-embedded-tomcat spring-rest-embedded-tomcat war - + com.baeldung parent-spring-5 - 0.0.1-SNAPSHOT - ../parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 - + org.springframework @@ -25,7 +23,7 @@ javax.servlet javax.servlet-api - 4.0.0 + ${servlet.version} @@ -37,59 +35,44 @@ org.apache.tomcat.embed tomcat-embed-core - 9.0.1 + ${tomcat.version} test org.apache.tomcat tomcat-jasper - 9.0.1 + ${tomcat.version} test org.apache.httpcomponents httpclient - 4.5.3 + ${httpclient.version} org.apache.httpcomponents httpcore - 4.4.8 + ${httpcore.version} + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + - - spring-rest-embedded-tomcat - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/JdbcTest.java - **/*LiveTest.java - - - - - - - 2.19.1 2.9.2 - 1.8 - 1.8 + 4.0.0 + 9.0.1 + 4.5.3 + 4.4.8 false diff --git a/spring-rest-embedded-tomcat/src/main/resources/logback.xml b/spring-rest-embedded-tomcat/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-rest-embedded-tomcat/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-rest-embedded-tomcat/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-rest-embedded-tomcat/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..8b8ff1a322 --- /dev/null +++ b/spring-rest-embedded-tomcat/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.baeldung.embedded.configuration.UserConfiguration; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { UserConfiguration.class }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-rest-full/README.md b/spring-rest-full/README.md index 23b0b0435b..b8fef9cb82 100644 --- a/spring-rest-full/README.md +++ b/spring-rest-full/README.md @@ -16,7 +16,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) - [Project Configuration with Spring](http://www.baeldung.com/project-configuration-with-spring) - [Metrics for your Spring REST API](http://www.baeldung.com/spring-rest-api-metrics) -- [Spring RestTemplate Tutorial](http://www.baeldung.com/rest-template) - [Bootstrap a Web Application with Spring 4](http://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration) - [Build a REST API with Spring 4 and Java Config](http://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration) - [Error Handling for REST with Spring](http://www.baeldung.com/exception-handling-for-rest-with-spring) @@ -41,5 +40,5 @@ mysql -u root -p ### Use the REST Service ``` -curl http://localhost:8080/spring-rest-full/foos +curl http://localhost:8082/spring-rest-full/auth/foos ``` diff --git a/spring-rest-full/pom.xml b/spring-rest-full/pom.xml index 1df22faddd..81c938a289 100644 --- a/spring-rest-full/pom.xml +++ b/spring-rest-full/pom.xml @@ -1,10 +1,9 @@ + 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 spring-rest-full 0.1-SNAPSHOT - spring-rest-full war @@ -26,12 +25,10 @@ org.springframework.boot spring-boot-starter-actuator - org.aspectj aspectjweaver - org.apache.tomcat.embed tomcat-embed-jasper @@ -74,7 +71,6 @@ org.springframework spring-expression - org.springframework spring-web @@ -83,7 +79,6 @@ org.springframework spring-webmvc - org.springframework.data spring-data-commons @@ -140,7 +135,6 @@ mysql-connector-java runtime - com.h2database h2 @@ -153,7 +147,6 @@ javax.servlet-api provided - javax.servlet jstl @@ -161,12 +154,10 @@ - com.fasterxml.jackson.core jackson-databind - com.thoughtworks.xstream xstream @@ -189,7 +180,6 @@ test - @@ -217,14 +207,28 @@ true - - org.apache.maven.plugins maven-war-plugin - + + + org.apache.maven.plugins + maven-surefire-plugin + + 3 + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/*LiveTest.java + **/*TestSuite.java + + + org.codehaus.cargo cargo-maven2-plugin @@ -245,9 +249,7 @@
    - - com.mysema.maven apt-maven-plugin @@ -264,9 +266,7 @@ - - @@ -286,7 +286,7 @@ **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/*LiveTest.java @@ -329,7 +329,6 @@ - 1.4.9 diff --git a/spring-rest-full/src/main/resources/logback.xml b/spring-rest-full/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-rest-full/src/main/resources/logback.xml +++ b/spring-rest-full/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-rest-full/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-rest-full/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..35939c992f --- /dev/null +++ b/spring-rest-full/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.spring.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-rest-hal-browser/README.md b/spring-rest-hal-browser/README.md new file mode 100644 index 0000000000..d9760c8295 --- /dev/null +++ b/spring-rest-hal-browser/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Spring REST and HAL Browser](http://www.baeldung.com/spring-rest-hal) diff --git a/spring-rest-hal-browser/pom.xml b/spring-rest-hal-browser/pom.xml new file mode 100644 index 0000000000..6c56faf0b2 --- /dev/null +++ b/spring-rest-hal-browser/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + com.baeldung + spring-rest-hal-browser + 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + + + org.springframework.boot + spring-boot-starter-web + 2.0.3.RELEASE + + + + org.springframework.boot + spring-boot-starter-data-jpa + 2.0.3.RELEASE + + + + org.springframework.data + spring-data-rest-hal-browser + 3.0.8.RELEASE + + + + com.h2database + h2 + 1.4.197 + + + + + + + \ No newline at end of file diff --git a/spring-rest-hal-browser/src/main/java/com/baeldung/App.java b/spring-rest-hal-browser/src/main/java/com/baeldung/App.java new file mode 100644 index 0000000000..14b6c201d5 --- /dev/null +++ b/spring-rest-hal-browser/src/main/java/com/baeldung/App.java @@ -0,0 +1,13 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class App { + + public static void main(String[] args) { + SpringApplication.run(App.class); + } + +} diff --git a/spring-rest-hal-browser/src/main/java/com/baeldung/config/DBLoader.java b/spring-rest-hal-browser/src/main/java/com/baeldung/config/DBLoader.java new file mode 100644 index 0000000000..7251ef0e8c --- /dev/null +++ b/spring-rest-hal-browser/src/main/java/com/baeldung/config/DBLoader.java @@ -0,0 +1,108 @@ +package com.baeldung.config; + +import com.baeldung.data.BookRepository; +import com.baeldung.model.Book; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +import java.util.Random; +import java.util.stream.IntStream; + +@Component +public class DBLoader implements ApplicationRunner { + + private final BookRepository bookRepository; + + @Autowired + DBLoader(BookRepository bookRepository){ + this.bookRepository = bookRepository; + } + + + public void run(ApplicationArguments applicationArguments) throws Exception { + + String[] templates = { + "Up and running with %s", + "%s Basics", + "%s for Beginners", + "%s for Neckbeards", + "Under the hood: %s", + "Discovering %s", + "A short guide to %s", + "%s with Baeldung" + }; + + String[] buzzWords = { + "Spring REST Data", + "Java 9", + "Scala", + "Groovy", + "Hibernate", + "Spring HATEOS", + "The HAL Browser", + "Spring webflux", + }; + + String[] authorFirstName = { + "John %s", + "Steve %s", + "Samantha %s", + "Gale %s", + "Tom %s" + }; + + String[] authorLastName = { + "Giles", + "Gill", + "Smith", + "Armstrong" + }; + + String[] blurbs = { + "It was getting dark when the %s %s" , + "Scott was nearly there when he heard that a %s %s", + "Diana was a lovable Java coder until the %s %s", + "The gripping story of a small %s and the day it %s" + }; + + String[] blublMiddles = { + "distaster", + "dog", + "cat", + "turtle", + "hurricane" + }; + + String[] end = { + "hit the school", + "memorised pi to 100 decimal places!", + "became a world champion armwrestler", + "became a Java REST master!!" + }; + + Random random = new Random(); + + IntStream.range(0, 100) + .forEach(i -> { + String template = templates[i % templates.length]; + String buzzword = buzzWords[i % buzzWords.length]; + String blurbStart = blurbs[i % blurbs.length]; + String middle = blublMiddles[i % blublMiddles.length]; + String ending = end[i % end.length]; + String blurb = String.format(blurbStart, middle, ending); + String firstName = authorFirstName[i % authorFirstName.length]; + String lastname = authorLastName[i % authorLastName.length]; + Book book = new Book(String.format(template, buzzword), String.format(firstName, lastname), blurb, random.nextInt(1000-200) + 200); + + bookRepository.save(book); + + System.out.println(book); + + }); + + + + } +} diff --git a/spring-rest-hal-browser/src/main/java/com/baeldung/config/RestConfig.java b/spring-rest-hal-browser/src/main/java/com/baeldung/config/RestConfig.java new file mode 100644 index 0000000000..858371facc --- /dev/null +++ b/spring-rest-hal-browser/src/main/java/com/baeldung/config/RestConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener; +import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; +import org.springframework.validation.Validator; + +@Configuration +public class RestConfig extends RepositoryRestConfigurerAdapter { + + //access to global validator + @Autowired + @Lazy + private Validator validator; + + @Override + public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) { + validatingListener.addValidator("beforeCreate", validator ); + validatingListener.addValidator("beforeSave", validator); + } +} diff --git a/spring-rest-hal-browser/src/main/java/com/baeldung/data/BookRepository.java b/spring-rest-hal-browser/src/main/java/com/baeldung/data/BookRepository.java new file mode 100644 index 0000000000..d8e35974b1 --- /dev/null +++ b/spring-rest-hal-browser/src/main/java/com/baeldung/data/BookRepository.java @@ -0,0 +1,21 @@ +package com.baeldung.data; + +import com.baeldung.model.Book; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.stereotype.Repository; + +@Repository +public interface BookRepository extends PagingAndSortingRepository { + + @RestResource(rel = "title-contains", path="title-contains") + Page findByTitleContaining(@Param("query") String query, Pageable page); + + @RestResource(rel = "author-contains", path="author-contains", exported = false) + Page findByAuthorContaining(@Param("query") String query, Pageable page); + +} diff --git a/spring-rest-hal-browser/src/main/java/com/baeldung/model/Book.java b/spring-rest-hal-browser/src/main/java/com/baeldung/model/Book.java new file mode 100644 index 0000000000..b1dc1b41f3 --- /dev/null +++ b/spring-rest-hal-browser/src/main/java/com/baeldung/model/Book.java @@ -0,0 +1,86 @@ +package com.baeldung.model; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; + +@Entity +public class Book { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @NotNull + @Column(columnDefinition = "VARCHAR", length = 100) + private String title; + + @NotNull + @Column(columnDefinition = "VARCHAR", length = 100) + private String author; + + @Column(columnDefinition = "VARCHAR", length = 1000) + private String blurb; + + private int pages; + + public Book() { + } + + public Book(@NotNull String title, @NotNull String author, String blurb, int pages) { + this.title = title; + this.author = author; + this.blurb = blurb; + this.pages = pages; + } + + 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; + } + + public String getBlurb() { + return blurb; + } + + public void setBlurb(String blurb) { + this.blurb = blurb; + } + + public int getPages() { + return pages; + } + + public void setPages(int pages) { + this.pages = pages; + } + + @Override + public String toString() { + return "Book{" + + "id=" + id + + ", title='" + title + '\'' + + ", author='" + author + '\'' + + ", blurb='" + blurb + '\'' + + ", pages=" + pages + + '}'; + } +} diff --git a/spring-rest-hal-browser/src/main/resources/application.properties b/spring-rest-hal-browser/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-rest-hal-browser/src/main/resources/logback.xml b/spring-rest-hal-browser/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-rest-hal-browser/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-rest-query-language/pom.xml b/spring-rest-query-language/pom.xml index 398181c1c8..8b24c7b8fb 100644 --- a/spring-rest-query-language/pom.xml +++ b/spring-rest-query-language/pom.xml @@ -1,10 +1,9 @@ + 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 spring-rest-query-language 0.1-SNAPSHOT - spring-rest-query-language war @@ -31,7 +30,6 @@ org.aspectj aspectjweaver - org.apache.tomcat.embed tomcat-embed-jasper @@ -74,7 +72,6 @@ org.springframework spring-expression - org.springframework spring-web @@ -83,7 +80,6 @@ org.springframework spring-webmvc - org.springframework.data spring-data-commons @@ -305,7 +301,7 @@ **/*IntegrationTest.java - **/*IntTest.java + **/*IntTest.java **/*LiveTest.java diff --git a/spring-rest-query-language/src/main/resources/logback.xml b/spring-rest-query-language/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-rest-query-language/src/main/resources/logback.xml +++ b/spring-rest-query-language/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-rest-query-language/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-rest-query-language/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..35939c992f --- /dev/null +++ b/spring-rest-query-language/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.spring.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-rest-shell/pom.xml b/spring-rest-shell/pom.xml index fe255b397f..7a604946b6 100644 --- a/spring-rest-shell/pom.xml +++ b/spring-rest-shell/pom.xml @@ -1,29 +1,19 @@ + 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 spring-rest-shell - 0.0.1-SNAPSHOT jar - spring-rest-shell A simple project to demonstrate Spring REST Shell features. - org.springframework.boot - spring-boot-starter-parent - 1.5.8.RELEASE - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 - - UTF-8 - UTF-8 - 1.8 - - @@ -56,5 +46,4 @@ - diff --git a/spring-rest-shell/src/main/resources/logback.xml b/spring-rest-shell/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-rest-shell/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-rest-simple/README.md b/spring-rest-simple/README.md index 9345cb70cc..57d6f50887 100644 --- a/spring-rest-simple/README.md +++ b/spring-rest-simple/README.md @@ -6,5 +6,4 @@ - [Spring RequestMapping](http://www.baeldung.com/spring-requestmapping) - [ETags for REST with Spring](http://www.baeldung.com/etags-for-rest-with-spring) - [Spring and Apache FileUpload](http://www.baeldung.com/spring-apache-file-upload) -- [Spring RestTemplate Error Handling](http://www.baeldung.com/spring-rest-template-error-handling) - +- [Test a REST API with curl](http://www.baeldung.com/curl-rest) diff --git a/spring-rest-simple/pom.xml b/spring-rest-simple/pom.xml index 36ee39ab27..d39e3a43c1 100644 --- a/spring-rest-simple/pom.xml +++ b/spring-rest-simple/pom.xml @@ -1,5 +1,5 @@ + 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 spring-rest-simple @@ -8,15 +8,15 @@ war - org.springframework.boot - spring-boot-starter-parent - 1.4.3.RELEASE + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 - org.springframework.boot spring-boot-starter-thymeleaf @@ -36,7 +36,6 @@ - org.springframework spring-web @@ -55,7 +54,6 @@ org.springframework spring-oxm - commons-fileupload commons-fileupload @@ -68,7 +66,6 @@ javax.servlet-api provided - javax.servlet jstl @@ -81,12 +78,10 @@ com.fasterxml.jackson.core jackson-databind - com.fasterxml.jackson.dataformat jackson-dataformat-xml - com.thoughtworks.xstream xstream @@ -100,7 +95,6 @@ guava ${guava.version} - org.apache.commons commons-lang3 @@ -139,7 +133,6 @@ junit test - org.hamcrest hamcrest-core @@ -150,25 +143,20 @@ hamcrest-library test - org.mockito mockito-core test - org.springframework spring-test - com.jayway.restassured rest-assured - ${rest-assured.version} + ${jayway-rest-assured.version} - - com.google.protobuf protobuf-java @@ -179,18 +167,15 @@ protobuf-java-format ${protobuf-java-format.version} - com.esotericsoftware kryo ${kryo.version} - com.jayway.jsonpath json-path - @@ -201,48 +186,13 @@ true - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - 1.8 - 1.8 - - - - - org.apache.maven.plugins - maven-war-plugin - - - - org.apache.maven.plugins - maven-surefire-plugin - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/JdbcTest.java - **/*LiveTest.java - - - - - org.codehaus.cargo cargo-maven2-plugin ${cargo-maven2-plugin.version} - + tomcat8x embedded @@ -257,17 +207,34 @@ - - - integration + + org.codehaus.cargo + cargo-maven2-plugin + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + org.apache.maven.plugins maven-surefire-plugin @@ -289,11 +256,10 @@ - - + live @@ -346,7 +312,6 @@ - @@ -359,7 +324,7 @@ 20.0 - 2.9.0 + 2.9.0 1.6.0 diff --git a/spring-rest-simple/src/main/java/org/baeldung/web/controller/FooController.java b/spring-rest-simple/src/main/java/org/baeldung/web/controller/FooController.java index 3c7e5ed13c..bf26eb3292 100644 --- a/spring-rest-simple/src/main/java/org/baeldung/web/controller/FooController.java +++ b/spring-rest-simple/src/main/java/org/baeldung/web/controller/FooController.java @@ -45,4 +45,19 @@ public class FooController { .setName("Foo Name") .build(); } + + @RequestMapping(method = RequestMethod.POST, value = "/foos/new") + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public Foo createFoo(@RequestBody final Foo foo) { + return foo; + } + + @RequestMapping(method = RequestMethod.DELETE, value = "/foos/{id}") + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public long deleteFoo(@PathVariable final long id) { + return id; + } + } diff --git a/spring-rest-simple/src/main/resources/logback.xml b/spring-rest-simple/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-rest-simple/src/main/resources/logback.xml +++ b/spring-rest-simple/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-rest-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-rest-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..66243ef00d --- /dev/null +++ b/spring-rest-simple/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-rest-simple/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java b/spring-rest-simple/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java deleted file mode 100644 index 40e93f2d89..0000000000 --- a/spring-rest-simple/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.baeldung.client; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -import java.io.IOException; - -import org.baeldung.web.dto.Foo; -import org.junit.Before; -import org.junit.Test; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.RestTemplate; - -public class RestTemplateBasicLiveTest { - - private RestTemplate restTemplate; - - private static final String fooResourceUrl = String.format("http://localhost:%d/spring-rest/foos", 8082); - - @Before - public void beforeTest() { - restTemplate = new RestTemplate(); - } - - // GET - - @Test - public void givenResourceUrl_whenSendGetForRequestEntity_thenStatusOk() throws IOException { - final ResponseEntity response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class); - - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); - } - - @Test - public void givenResourceUrl_whenRetrievingResource_thenCorrect() throws IOException { - final Foo foo = restTemplate.getForObject(fooResourceUrl + "/1", Foo.class); - - assertThat(foo.getName(), notNullValue()); - assertThat(foo.getId(), is(1L)); - } - - // PUT - - @Test - public void givenFooService_whenPutObject_thenUpdatedObjectIsReturned() { - final HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - final Foo foo = new Foo(1, "newName"); - final String resourceUrl = fooResourceUrl + "/1"; - final HttpEntity requestUpdate = new HttpEntity<>(foo, headers); - final ResponseEntity response = restTemplate.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Foo.class); - - assertThat(foo.getName(), is(response.getBody() - .getName())); - } - -} diff --git a/spring-rest-simple/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java b/spring-rest-simple/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java index e29bef501e..7f78146b84 100644 --- a/spring-rest-simple/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java +++ b/spring-rest-simple/src/test/java/org/baeldung/web/controller/status/ExampleControllerIntegrationTest.java @@ -8,6 +8,7 @@ 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.autoconfigure.web.client.AutoConfigureWebClient; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @@ -18,6 +19,7 @@ import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = WebConfig.class) @WebAppConfiguration +@AutoConfigureWebClient public class ExampleControllerIntegrationTest { private MockMvc mockMvc; diff --git a/spring-rest-simple/src/test/java/org/baeldung/web/test/BazzNewMappingsExampleIntegrationTest.java b/spring-rest-simple/src/test/java/org/baeldung/web/test/BazzNewMappingsExampleIntegrationTest.java index 266ee1938b..dfb3ff7a38 100644 --- a/spring-rest-simple/src/test/java/org/baeldung/web/test/BazzNewMappingsExampleIntegrationTest.java +++ b/spring-rest-simple/src/test/java/org/baeldung/web/test/BazzNewMappingsExampleIntegrationTest.java @@ -15,6 +15,7 @@ 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.autoconfigure.web.client.AutoConfigureWebClient; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @@ -26,6 +27,7 @@ import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = WebConfig.class) @WebAppConfiguration +@AutoConfigureWebClient public class BazzNewMappingsExampleIntegrationTest { private MockMvc mockMvc; diff --git a/spring-rest-template/.gitignore b/spring-rest-template/.gitignore new file mode 100644 index 0000000000..afdfaa6ded --- /dev/null +++ b/spring-rest-template/.gitignore @@ -0,0 +1,14 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +*/.idea/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-rest-template/README.md b/spring-rest-template/README.md new file mode 100644 index 0000000000..d69d5c01c7 --- /dev/null +++ b/spring-rest-template/README.md @@ -0,0 +1,7 @@ +## Spring REST Template Example Project + +### The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles: +- [Uploading MultipartFile with Spring RestTemplate](http://www.baeldung.com/spring-rest-template-multipart-upload) diff --git a/spring-rest-template/checkstyle.xml b/spring-rest-template/checkstyle.xml new file mode 100644 index 0000000000..85063a7570 --- /dev/null +++ b/spring-rest-template/checkstyle.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/spring-rest-template/pom.xml b/spring-rest-template/pom.xml new file mode 100644 index 0000000000..fa93308cf5 --- /dev/null +++ b/spring-rest-template/pom.xml @@ -0,0 +1,83 @@ + + 4.0.0 + com.baeldung + spring-rest-template + 0.1-SNAPSHOT + spring-rest-template + jar + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + + + org.springframework + spring-web + + + commons-logging + commons-logging + + + + + + + spring-rest-template + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle-maven-plugin.version} + + checkstyle.xml + + + + + check + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + 3 + true + + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/*LiveTest.java + + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle-maven-plugin.version} + + checkstyle.xml + + + + + + + + 3.0.0 + + diff --git a/spring-rest-template/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java b/spring-rest-template/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java new file mode 100644 index 0000000000..804013d4dc --- /dev/null +++ b/spring-rest-template/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java @@ -0,0 +1,62 @@ +package com.baeldung.web.upload.client; + +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class MultipartFileUploadClient { + + public static void main(String[] args) throws IOException { + uploadSingleFile(); + uploadMultipleFile(); + } + + private static void uploadSingleFile() throws IOException { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("file", getTestFile()); + + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + String serverUrl = "http://localhost:8082/spring-rest/fileserver/singlefileupload/"; + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.postForEntity(serverUrl, requestEntity, String.class); + System.out.println("Response code: " + response.getStatusCode()); + } + + private static void uploadMultipleFile() throws IOException { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("files", getTestFile()); + body.add("files", getTestFile()); + body.add("files", getTestFile()); + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + String serverUrl = "http://localhost:8082/spring-rest/fileserver/multiplefileupload/"; + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.postForEntity(serverUrl, requestEntity, String.class); + System.out.println("Response code: " + response.getStatusCode()); + } + + public static Resource getTestFile() throws IOException { + Path testFile = Files.createTempFile("test-file", ".txt"); + System.out.println("Creating and Uploading Test File: " + testFile); + Files.write(testFile, "Hello World !!, This is a test file.".getBytes()); + return new FileSystemResource(testFile.toFile()); + } + +} diff --git a/spring-rest-template/src/main/resources/logback.xml b/spring-rest-template/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-rest-template/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-rest/README.md b/spring-rest/README.md index d1dcf554a5..d449a4d92a 100644 --- a/spring-rest/README.md +++ b/spring-rest/README.md @@ -14,7 +14,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Introduction to FindBugs](http://www.baeldung.com/intro-to-findbugs) - [A Custom Media Type for a Spring REST API](http://www.baeldung.com/spring-rest-custom-media-type) - [HTTP PUT vs HTTP PATCH in a REST API](http://www.baeldung.com/http-put-patch-difference-spring) -- [Exploring the Spring Boot TestRestTemplate](http://www.baeldung.com/spring-boot-testresttemplate) - [Spring – Log Incoming Requests](http://www.baeldung.com/spring-http-logging) - [RequestBody and ResponseBody Annotations](http://www.baeldung.com/requestbody-and-responsebody-annotations) - [Introduction to CheckStyle](http://www.baeldung.com/checkstyle-java) @@ -22,5 +21,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) - +- [Get and Post Lists of Objects with RestTemplate](http://www.baeldung.com/spring-rest-template-list) +- [How to Set a Header on a Response with Spring 5](http://www.baeldung.com/spring-response-header) diff --git a/spring-rest/pom.xml b/spring-rest/pom.xml index 2b6b663b2a..ba74d26c35 100644 --- a/spring-rest/pom.xml +++ b/spring-rest/pom.xml @@ -1,7 +1,6 @@ + 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 spring-rest 0.1-SNAPSHOT spring-rest @@ -17,8 +16,7 @@ - - + org.springframework.boot spring-boot-starter-web @@ -40,7 +38,6 @@ - org.springframework spring-web @@ -59,14 +56,13 @@ org.springframework spring-oxm - commons-fileupload commons-fileupload ${commons-fileupload.version} - + javax.servlet javax.servlet-api @@ -80,7 +76,6 @@ - com.fasterxml.jackson.core jackson-databind @@ -98,21 +93,17 @@ - com.google.guava guava ${guava.version} - org.apache.commons commons-lang3 - ${commons-lang3.version} - com.squareup.okhttp3 okhttp @@ -120,7 +111,6 @@ - org.hamcrest hamcrest-core @@ -131,13 +121,11 @@ hamcrest-library test - org.mockito mockito-core test - org.springframework spring-test @@ -154,36 +142,30 @@ protobuf-java-format ${protobuf-java-format.version} - com.esotericsoftware kryo ${kryo.version} - com.jayway.jsonpath json-path - commons-io commons-io 2.4 - au.com.dius pact-jvm-provider-junit_2.11 ${pact.version} - io.rest-assured rest-assured - ${rest-assured.version} @@ -209,27 +191,6 @@ org.apache.maven.plugins maven-war-plugin - - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - - tomcat8x - embedded - - - - - - - 8082 - - - - - org.apache.maven.plugins maven-checkstyle-plugin @@ -245,23 +206,7 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/*LiveTest.java - - - - @@ -353,7 +298,6 @@ 3.4.1 2.2.0 - 3.5.11 3.1.0 diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java b/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java new file mode 100644 index 0000000000..ebc18a130b --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.responseheaders; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; + +@ServletComponentScan +@SpringBootApplication +public class ResponseHeadersApplication { + + public static void main(String[] args) { + SpringApplication.run(ResponseHeadersApplication.class, args); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java new file mode 100644 index 0000000000..c92d4afafd --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java @@ -0,0 +1,24 @@ +package com.baeldung.responseheaders.controllers; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/filter-response-header") +public class FilterResponseHeaderController { + + @GetMapping("/no-extra-header") + public String FilterHeaderResponseWithNoExtraHeader() { + return "Response body with Filter header and no extra header"; + } + + @GetMapping("/extra-header") + public String FilterHeaderResponseWithExtraHeader(HttpServletResponse response) { + response.addHeader("Baeldung-Example-Header", "Value-ExtraHeader"); + return "Response body with Filter header and one extra header"; + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java new file mode 100644 index 0000000000..d93964b815 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java @@ -0,0 +1,70 @@ +package com.baeldung.responseheaders.controllers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/single-response-header") +public class ResponseHeaderController { + + @GetMapping("/http-servlet-response") + public String usingHttpServletResponse(HttpServletResponse response) { + response.addHeader("Baeldung-Example-Header", "Value-HttpServletResponse"); + return "Response with header using HttpServletResponse"; + } + + @GetMapping("/response-entity-constructor") + public ResponseEntity usingResponseEntityConstructor() { + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityContructor"); + String responseBody = "Response with header using ResponseEntity (constructor)"; + HttpStatus responseStatus = HttpStatus.OK; + + return new ResponseEntity(responseBody, responseHeaders, responseStatus); + } + + @GetMapping("/response-entity-contructor-multiple-headers") + public ResponseEntity usingResponseEntityConstructorAndMultipleHeaders() { + List acceptableMediaTypes = new ArrayList<>(Arrays.asList(MediaType.APPLICATION_JSON)); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityConstructorAndHeaders"); + responseHeaders.setAccept(acceptableMediaTypes); + String responseBody = "Response with header using ResponseEntity (constructor)"; + HttpStatus responseStatus = HttpStatus.OK; + + return new ResponseEntity(responseBody, responseHeaders, responseStatus); + } + + @GetMapping("/response-entity-builder") + public ResponseEntity usingResponseEntityBuilder() { + String responseHeaderKey = "Baeldung-Example-Header"; + String responseHeaderValue = "Value-ResponseEntityBuilder"; + String responseBody = "Response with header using ResponseEntity (builder)"; + + return ResponseEntity.ok() + .header(responseHeaderKey, responseHeaderValue) + .body(responseBody); + } + + @GetMapping("/response-entity-builder-with-http-headers") + public ResponseEntity usingResponseEntityBuilderAndHttpHeaders() { + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.set("Baeldung-Example-Header", "Value-ResponseEntityBuilderWithHttpHeaders"); + String responseBody = "Response with header using ResponseEntity (builder)"; + + return ResponseEntity.ok() + .headers(responseHeaders) + .body(responseBody); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java b/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java new file mode 100644 index 0000000000..7d4ffb1391 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java @@ -0,0 +1,41 @@ +package com.baeldung.responseheaders.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@WebFilter("/filter-response-header/*") +public class AddResponseHeaderFilter implements Filter { + + private static final Logger LOGGER = LoggerFactory.getLogger(AddResponseHeaderFilter.class); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // add special initialization requirements here + LOGGER.trace("Initializing filter..."); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.setHeader("Baeldung-Example-Filter-Header", "Value-Filter"); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // clean up any resource being held by the filter here + LOGGER.trace("Destroying filter..."); + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/app/Application.java b/spring-rest/src/main/java/com/baeldung/web/upload/app/Application.java similarity index 80% rename from spring-mvc-java/src/main/java/com/baeldung/app/Application.java rename to spring-rest/src/main/java/com/baeldung/web/upload/app/Application.java index 68d078de78..d6821196eb 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/app/Application.java +++ b/spring-rest/src/main/java/com/baeldung/web/upload/app/Application.java @@ -1,4 +1,4 @@ -package com.baeldung.app; +package com.baeldung.web.upload.app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -7,7 +7,7 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer import org.springframework.context.annotation.ComponentScan; @EnableAutoConfiguration -@ComponentScan(value = {"com.baeldung.web.controller"}, resourcePattern = "**/FileUploadController.class") +@ComponentScan("com.baeldung.web.upload") @SpringBootApplication public class Application extends SpringBootServletInitializer { diff --git a/spring-rest/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java b/spring-rest/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java new file mode 100644 index 0000000000..547aec17a0 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java @@ -0,0 +1,61 @@ +package com.baeldung.web.upload.client; + +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class MultipartFileUploadClient { + + public static void main(String[] args) throws IOException { + uploadSingleFile(); + uploadMultipleFile(); + } + + private static void uploadSingleFile() throws IOException { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("file", getTestFile()); + + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + String serverUrl = "http://localhost:8082/spring-rest/fileserver/singlefileupload/"; + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.postForEntity(serverUrl, requestEntity, String.class); + System.out.println("Response code: " + response.getStatusCode()); + } + + private static void uploadMultipleFile() throws IOException { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("files", getTestFile()); + body.add("files", getTestFile()); + body.add("files", getTestFile()); + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + String serverUrl = "http://localhost:8082/spring-rest/fileserver/multiplefileupload/"; + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response = restTemplate.postForEntity(serverUrl, requestEntity, String.class); + System.out.println("Response code: " + response.getStatusCode()); + } + + public static Resource getTestFile() throws IOException { + Path testFile = Files.createTempFile("test-file", ".txt"); + System.out.println("Creating and Uploading Test File: " + testFile); + Files.write(testFile, "Hello World !!, This is a test file.".getBytes()); + return new FileSystemResource(testFile.toFile()); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/web/upload/controller/FileServerResource.java b/spring-rest/src/main/java/com/baeldung/web/upload/controller/FileServerResource.java new file mode 100644 index 0000000000..3863a8f20d --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/web/upload/controller/FileServerResource.java @@ -0,0 +1,43 @@ +package com.baeldung.web.upload.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.List; + +@RestController +@RequestMapping("/fileserver") +public class FileServerResource { + + @RequestMapping(path = "/singlefileupload/", method = RequestMethod.POST) + public ResponseEntity processFile(@RequestParam("file") MultipartFile file) throws IOException { + + byte[] bytes = file.getBytes(); + + System.out.println("File Name: " + file.getOriginalFilename()); + System.out.println("File Content Type: " + file.getContentType()); + System.out.println("File Content:\n" + new String(bytes)); + + return (new ResponseEntity<>("Successful", null, HttpStatus.OK)); + } + + @RequestMapping(path = "/multiplefileupload/", method = RequestMethod.POST) + public ResponseEntity processFile(@RequestParam("files") List files) throws IOException { + + for (MultipartFile file : files) { + byte[] bytes = file.getBytes(); + + System.out.println("File Name: " + file.getOriginalFilename()); + System.out.println("File Content Type: " + file.getContentType()); + System.out.println("File Content:\n" + new String(bytes)); + } + + return (new ResponseEntity<>("Successful", null, HttpStatus.OK)); + } +} \ No newline at end of file diff --git a/spring-rest/src/main/resources/logback.xml b/spring-rest/src/main/resources/logback.xml index 3496a4a03c..9f48d36486 100644 --- a/spring-rest/src/main/resources/logback.xml +++ b/spring-rest/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-rest/src/test/java/com/baeldung/propertyeditor/creditcard/CreditCardEditorUnitTest.java b/spring-rest/src/test/java/com/baeldung/propertyeditor/creditcard/CreditCardEditorUnitTest.java index a84f866dfe..814efc112a 100644 --- a/spring-rest/src/test/java/com/baeldung/propertyeditor/creditcard/CreditCardEditorUnitTest.java +++ b/spring-rest/src/test/java/com/baeldung/propertyeditor/creditcard/CreditCardEditorUnitTest.java @@ -4,10 +4,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; - -import com.baeldung.propertyeditor.creditcard.CreditCard; -import com.baeldung.propertyeditor.creditcard.CreditCardEditor; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class CreditCardEditorUnitTest { diff --git a/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java b/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java new file mode 100644 index 0000000000..bed0de55bd --- /dev/null +++ b/spring-rest/src/test/java/com/baeldung/responseheaders/ResponseHeaderLiveTest.java @@ -0,0 +1,103 @@ +package com.baeldung.responseheaders; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; + +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class ResponseHeaderLiveTest { + + private static final String BASE_URL = "http://localhost:8082/spring-rest"; + private static final String SINGLE_BASE_URL = BASE_URL + "/single-response-header"; + private static final String FILTER_BASE_URL = BASE_URL + "/filter-response-header"; + private static final String SERVICE_SINGLE_RESPONSE_HEADER = "Baeldung-Example-Header"; + private static final String SERVICE_FILTER_RESPONSE_HEADER = "Baeldung-Example-Filter-Header"; + + @Autowired + private TestRestTemplate template; + + @Test + public void whenHttpServletResponseRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/http-servlet-response"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-HttpServletResponse")); + } + + @Test + public void whenResponseEntityConstructorRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-constructor"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityContructor")); + } + + @Test + public void whenResponseEntityConstructorAndMultipleHeadersRequest_thenObtainResponseWithCorrectHeaders() { + final String requestUrl = "/response-entity-contructor-multiple-headers"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityConstructorAndHeaders")); + assertThat(responseHeaders).containsEntry("Accept", Arrays.asList(MediaType.APPLICATION_JSON.toString())); + } + + @Test + public void whenResponseEntityBuilderRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-builder"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityBuilder")); + } + + @Test + public void whenResponseEntityBuilderAndHttpHeadersRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/response-entity-builder-with-http-headers"; + ResponseEntity response = template.getForEntity(SINGLE_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ResponseEntityBuilderWithHttpHeaders")); + } + + @Test + public void whenFilterWithNoExtraHeaderRequest_thenObtainResponseWithCorrectHeader() { + final String requestUrl = "/no-extra-header"; + ResponseEntity response = template.getForEntity(FILTER_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_FILTER_RESPONSE_HEADER, Arrays.asList("Value-Filter")); + } + + @Test + public void whenFilterWithExtraHeaderRequest_thenObtainResponseWithCorrectHeaders() { + final String requestUrl = "/extra-header"; + ResponseEntity response = template.getForEntity(FILTER_BASE_URL + requestUrl, String.class); + HttpHeaders responseHeaders = response.getHeaders(); + + assertThat(responseHeaders).isNotEmpty(); + assertThat(responseHeaders).containsEntry(SERVICE_FILTER_RESPONSE_HEADER, Arrays.asList("Value-Filter")); + assertThat(responseHeaders).containsEntry(SERVICE_SINGLE_RESPONSE_HEADER, Arrays.asList("Value-ExtraHeader")); + } + +} diff --git a/spring-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..d99dacd331 --- /dev/null +++ b/spring-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,24 @@ +package org.baeldung; + +import org.baeldung.config.MainApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.custom.CustomApplication; +import com.baeldung.produceimage.ImageApplication; +import com.baeldung.propertyeditor.PropertyEditorApplication; +import com.baeldung.responseheaders.ResponseHeadersApplication; +import com.baeldung.web.log.app.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { CustomApplication.class, ImageApplication.class, PropertyEditorApplication.class, + ResponseHeadersApplication.class, Application.class, com.baeldung.web.upload.app.Application.class, + MainApplication.class}) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-rest/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java b/spring-rest/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java deleted file mode 100644 index a8a71c7d73..0000000000 --- a/spring-rest/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.baeldung.client; - -import okhttp3.Request; -import okhttp3.RequestBody; -import org.junit.Before; -import org.junit.Test; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.RestTemplate; - -import static org.baeldung.client.Consts.APPLICATION_PORT; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertTrue; - -public class TestRestTemplateBasicLiveTest { - - private RestTemplateBuilder restTemplate; - private static final String FOO_RESOURCE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest/foos"; - private static final String URL_SECURED_BY_AUTHENTICATION = "http://httpbin.org/basic-auth/user/passwd"; - private static final String BASE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-rest"; - - @Before - public void beforeTest() { - restTemplate = new RestTemplateBuilder(); - } - - // GET - @Test - public void givenTestRestTemplate_whenSendGetForEntity_thenStatusOk() { - TestRestTemplate testRestTemplate = new TestRestTemplate(); - ResponseEntity response = testRestTemplate.getForEntity(FOO_RESOURCE_URL + "/1", String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); - } - - @Test - public void givenRestTemplateWrapper_whenSendGetForEntity_thenStatusOk() { - TestRestTemplate testRestTemplate = new TestRestTemplate(restTemplate); - ResponseEntity response = testRestTemplate.getForEntity(FOO_RESOURCE_URL + "/1", String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); - } - - @Test - public void givenRestTemplateBuilderWrapper_whenSendGetForEntity_thenStatusOk() { - RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder(); - restTemplateBuilder.build(); - TestRestTemplate testRestTemplate = new TestRestTemplate(restTemplateBuilder); - ResponseEntity response = testRestTemplate.getForEntity(FOO_RESOURCE_URL + "/1", String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); - } - - @Test - public void givenRestTemplateWrapperWithCredentials_whenSendGetForEntity_thenStatusOk() { - TestRestTemplate testRestTemplate = new TestRestTemplate(restTemplate, "user", "passwd"); - ResponseEntity response = testRestTemplate.getForEntity(URL_SECURED_BY_AUTHENTICATION, - String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); - } - - @Test - public void givenTestRestTemplateWithCredentials_whenSendGetForEntity_thenStatusOk() { - TestRestTemplate testRestTemplate = new TestRestTemplate("user", "passwd"); - ResponseEntity response = testRestTemplate.getForEntity(URL_SECURED_BY_AUTHENTICATION, - String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); - } - - @Test - public void givenTestRestTemplateWithBasicAuth_whenSendGetForEntity_thenStatusOk() { - TestRestTemplate testRestTemplate = new TestRestTemplate(); - ResponseEntity response = testRestTemplate.withBasicAuth("user", "passwd"). - getForEntity(URL_SECURED_BY_AUTHENTICATION, String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); - } - - @Test - public void givenTestRestTemplateWithCredentialsAndEnabledCookies_whenSendGetForEntity_thenStatusOk() { - TestRestTemplate testRestTemplate = new TestRestTemplate("user", "passwd", TestRestTemplate. - HttpClientOption.ENABLE_COOKIES); - ResponseEntity response = testRestTemplate.getForEntity(URL_SECURED_BY_AUTHENTICATION, - String.class); - assertThat(response.getStatusCode(), equalTo(HttpStatus.OK)); - } - - // HEAD - @Test - public void givenFooService_whenCallHeadForHeaders_thenReceiveAllHeaders() { - TestRestTemplate testRestTemplate = new TestRestTemplate(); - final HttpHeaders httpHeaders = testRestTemplate.headForHeaders(FOO_RESOURCE_URL); - assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON)); - } - - // POST - @Test - public void givenService_whenPostForObject_thenCreatedObjectIsReturned() { - TestRestTemplate testRestTemplate = new TestRestTemplate("user", "passwd"); - final RequestBody body = RequestBody.create(okhttp3.MediaType.parse("text/html; charset=utf-8"), - "{\"id\":1,\"name\":\"Jim\"}"); - final Request request = new Request.Builder().url(BASE_URL + "/users/detail").post(body).build(); - testRestTemplate.postForObject(URL_SECURED_BY_AUTHENTICATION, request, String.class); - } - - // PUT - @Test - public void givenService_whenPutForObject_thenCreatedObjectIsReturned() { - TestRestTemplate testRestTemplate = new TestRestTemplate("user", "passwd"); - final RequestBody body = RequestBody.create(okhttp3.MediaType.parse("text/html; charset=utf-8"), - "{\"id\":1,\"name\":\"Jim\"}"); - final Request request = new Request.Builder().url(BASE_URL + "/users/detail").post(body).build(); - testRestTemplate.put(URL_SECURED_BY_AUTHENTICATION, request, String.class); - } - -} diff --git a/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java b/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java similarity index 97% rename from spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java rename to spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java index e0c24c32b1..4f00bebdf4 100644 --- a/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java +++ b/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateLiveTest.java @@ -21,7 +21,7 @@ import com.baeldung.transfer.LoginForm; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RestClientConfig.class) -public class RestTemplateIntegrationTest { +public class RestTemplateLiveTest { @Autowired RestTemplate restTemplate; diff --git a/spring-resttemplate/.gitignore b/spring-resttemplate/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-resttemplate/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-resttemplate/README.md b/spring-resttemplate/README.md new file mode 100644 index 0000000000..bf8c56e6ec --- /dev/null +++ b/spring-resttemplate/README.md @@ -0,0 +1,10 @@ +## Spring REST Example Project + +### The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles: +- [Spring RestTemplate Tutorial](http://www.baeldung.com/rest-template) +- [Exploring the Spring Boot TestRestTemplate](http://www.baeldung.com/spring-boot-testresttemplate) +- [Spring RestTemplate Error Handling](http://www.baeldung.com/spring-rest-template-error-handling) +- [Configure a RestTemplate with RestTemplateBuilder](http://www.baeldung.com/spring-rest-template-builder) \ No newline at end of file diff --git a/spring-resttemplate/pom.xml b/spring-resttemplate/pom.xml new file mode 100644 index 0000000000..481104372a --- /dev/null +++ b/spring-resttemplate/pom.xml @@ -0,0 +1,297 @@ + + 4.0.0 + com.baeldung + spring-resttemplate + 0.1-SNAPSHOT + spring-resttemplate + war + + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 + + + + + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.springframework + spring-web + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + + + org.springframework + spring-oxm + + + + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + + + + com.google.guava + guava + ${guava.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + + org.slf4j + slf4j-api + + + ch.qos.logback + logback-classic + + + + org.slf4j + jcl-over-slf4j + + + + + + + com.squareup.okhttp3 + okhttp + ${com.squareup.okhttp3.version} + + + + + + junit + junit + test + + + org.hamcrest + hamcrest-core + test + + + org.hamcrest + hamcrest-library + test + + + org.mockito + mockito-core + test + + + org.springframework + spring-test + + + + + spring-resttemplate + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-war-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + 3 + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + + + tomcat8x + embedded + + + + + + + 8082 + + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*IntegrationTest.java + **/*IntTest.java + + + + + + + + + + + live + + + + org.codehaus.cargo + cargo-maven2-plugin + + + start-server + pre-integration-test + + start + + + + stop-server + post-integration-test + + stop + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + **/*LiveTest.java + + + cargo + + + + + + + + + + + + + 3.5 + 1.4.9 + + + 20.0 + + + 1.6.0 + 3.0.4 + + + 3.4.1 + + + diff --git a/spring-rest/src/main/java/org/baeldung/resttemplate/configuration/CustomClientHttpRequestInterceptor.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/CustomClientHttpRequestInterceptor.java similarity index 100% rename from spring-rest/src/main/java/org/baeldung/resttemplate/configuration/CustomClientHttpRequestInterceptor.java rename to spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/CustomClientHttpRequestInterceptor.java diff --git a/spring-rest/src/main/java/org/baeldung/resttemplate/configuration/CustomRestTemplateCustomizer.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/CustomRestTemplateCustomizer.java similarity index 100% rename from spring-rest/src/main/java/org/baeldung/resttemplate/configuration/CustomRestTemplateCustomizer.java rename to spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/CustomRestTemplateCustomizer.java diff --git a/spring-rest/src/main/java/org/baeldung/resttemplate/configuration/HelloController.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/HelloController.java similarity index 100% rename from spring-rest/src/main/java/org/baeldung/resttemplate/configuration/HelloController.java rename to spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/HelloController.java diff --git a/spring-rest/src/main/java/org/baeldung/resttemplate/configuration/RestTemplateConfigurationApplication.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/RestTemplateConfigurationApplication.java similarity index 100% rename from spring-rest/src/main/java/org/baeldung/resttemplate/configuration/RestTemplateConfigurationApplication.java rename to spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/RestTemplateConfigurationApplication.java diff --git a/spring-rest/src/main/java/org/baeldung/resttemplate/configuration/SpringConfig.java b/spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/SpringConfig.java similarity index 100% rename from spring-rest/src/main/java/org/baeldung/resttemplate/configuration/SpringConfig.java rename to spring-resttemplate/src/main/java/org/baeldung/resttemplate/configuration/SpringConfig.java diff --git a/spring-resttemplate/src/main/java/org/baeldung/web/dto/Foo.java b/spring-resttemplate/src/main/java/org/baeldung/web/dto/Foo.java new file mode 100644 index 0000000000..240b368b50 --- /dev/null +++ b/spring-resttemplate/src/main/java/org/baeldung/web/dto/Foo.java @@ -0,0 +1,45 @@ +package org.baeldung.web.dto; + +import com.thoughtworks.xstream.annotations.XStreamAlias; + +@XStreamAlias("Foo") +public class Foo { + private long id; + private String name; + + public Foo() { + super(); + } + + public Foo(final String name) { + super(); + + this.name = name; + } + + public Foo(final long id, final String name) { + super(); + + this.id = id; + this.name = name; + } + + // API + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + +} \ No newline at end of file diff --git a/spring-rest-simple/src/main/java/org/baeldung/web/exception/NotFoundException.java b/spring-resttemplate/src/main/java/org/baeldung/web/exception/NotFoundException.java similarity index 100% rename from spring-rest-simple/src/main/java/org/baeldung/web/exception/NotFoundException.java rename to spring-resttemplate/src/main/java/org/baeldung/web/exception/NotFoundException.java diff --git a/spring-rest-simple/src/main/java/org/baeldung/web/handler/RestTemplateResponseErrorHandler.java b/spring-resttemplate/src/main/java/org/baeldung/web/handler/RestTemplateResponseErrorHandler.java similarity index 100% rename from spring-rest-simple/src/main/java/org/baeldung/web/handler/RestTemplateResponseErrorHandler.java rename to spring-resttemplate/src/main/java/org/baeldung/web/handler/RestTemplateResponseErrorHandler.java diff --git a/spring-rest-simple/src/main/java/org/baeldung/web/model/Bar.java b/spring-resttemplate/src/main/java/org/baeldung/web/model/Bar.java similarity index 100% rename from spring-rest-simple/src/main/java/org/baeldung/web/model/Bar.java rename to spring-resttemplate/src/main/java/org/baeldung/web/model/Bar.java diff --git a/spring-rest-simple/src/main/java/org/baeldung/web/service/BarConsumerService.java b/spring-resttemplate/src/main/java/org/baeldung/web/service/BarConsumerService.java similarity index 100% rename from spring-rest-simple/src/main/java/org/baeldung/web/service/BarConsumerService.java rename to spring-resttemplate/src/main/java/org/baeldung/web/service/BarConsumerService.java diff --git a/spring-resttemplate/src/main/resources/application.properties b/spring-resttemplate/src/main/resources/application.properties new file mode 100644 index 0000000000..1a26e3ad99 --- /dev/null +++ b/spring-resttemplate/src/main/resources/application.properties @@ -0,0 +1,2 @@ +server.port=8082 +server.servlet.context-path=/spring-rest \ No newline at end of file diff --git a/spring-resttemplate/src/main/resources/logback.xml b/spring-resttemplate/src/main/resources/logback.xml new file mode 100644 index 0000000000..9f48d36486 --- /dev/null +++ b/spring-resttemplate/src/main/resources/logback.xml @@ -0,0 +1,23 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-resttemplate/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-resttemplate/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..3a5a20cfeb --- /dev/null +++ b/spring-resttemplate/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.resttemplate.configuration.RestTemplateConfigurationApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = RestTemplateConfigurationApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-resttemplate/src/test/java/org/baeldung/client/Consts.java b/spring-resttemplate/src/test/java/org/baeldung/client/Consts.java new file mode 100644 index 0000000000..b40561d9c3 --- /dev/null +++ b/spring-resttemplate/src/test/java/org/baeldung/client/Consts.java @@ -0,0 +1,5 @@ +package org.baeldung.client; + +public interface Consts { + int APPLICATION_PORT = 8082; +} diff --git a/spring-rest/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java b/spring-resttemplate/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java similarity index 100% rename from spring-rest/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java rename to spring-resttemplate/src/test/java/org/baeldung/client/RestTemplateBasicLiveTest.java diff --git a/spring-rest-simple/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java b/spring-resttemplate/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java similarity index 100% rename from spring-rest-simple/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java rename to spring-resttemplate/src/test/java/org/baeldung/client/TestRestTemplateBasicLiveTest.java diff --git a/spring-rest-simple/src/test/java/org/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java b/spring-resttemplate/src/test/java/org/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java similarity index 100% rename from spring-rest-simple/src/test/java/org/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java rename to spring-resttemplate/src/test/java/org/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java diff --git a/spring-resttemplate/src/test/resources/.gitignore b/spring-resttemplate/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/spring-resttemplate/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-roo/pom.xml b/spring-roo/pom.xml index 5827aba7af..c205c98dc0 100644 --- a/spring-roo/pom.xml +++ b/spring-roo/pom.xml @@ -1,266 +1,20 @@ - - + + + 4.0.0 + com.baeldung + spring-roo + 1.0.0.BUILD-SNAPSHOT + Spring Roo + jar + io.spring.platform platform-bom Athens-RELEASE - + - 4.0.0 - com.baeldung - roo - 1.0.0.BUILD-SNAPSHOT - roo - - jar - - - 2.0.0.RC1 - 8 - UTF-8 - 1.8 - 1.5.4 - 1.4.1.RELEASE - 1.8 - 1.2.0.RC1 - 1.1.2 - 3.0.0.RELEASE - 2.0.0 - 2.0.1 - 5.0.11 - 1.0 - 3.3.6 - 1.10.12 - 1.10.11 - 1.1.2 - 1.1.2 - 2.0.2 - 2.0.2 - 1.1.2 - 1.1.2 - 1.1.2 - 2.0.0 - 2.5.4 - 4.6.2 - 1.12.3 - 3.3.1 - 1.15.0 - 2.13.0 - 4.0.3 - 0.1.0-beta.7 - 1.4.2 - 3.7.3 - 1.0.3 - - - - - - maven-snapshot-repository - Maven Snapshot Repository - https://oss.sonatype.org/content/repositories/snapshots - - false - - - true - - - - - spring-roo-repository - Spring Roo Repository - http://repo.spring.io/spring-roo - - - - - - - - - org.springframework.roo - org.springframework.roo.annotations - ${roo.version} - pom - provided - - - - io.springlets - springlets-data-jpa - ${springlets.version} - - - io.springlets - springlets-data-commons - ${springlets.version} - - - io.springlets - springlets-context - ${springlets.version} - - - org.springframework.roo - org.springframework.roo.querydsl.processor - 2.0.0.RELEASE - - - io.tracee.binding - tracee-springmvc - ${tracee.version} - - - io.springlets - springlets-boot-starter-web - ${springlets.version} - - - com.github.mxab.thymeleaf.extras - thymeleaf-extras-data-attribute - ${thymeleaf-data-dialect.version} - - - ar.com.fdvs - DynamicJasper - ${dynamicjasper.version} - - - ar.com.fdvs - DynamicJasper-core-fonts - ${dynamicjasper-fonts.version} - - - org.webjars.bower - bootstrap - ${bootstrap.version} - - - org.webjars.bower - datatables - ${datatables.version} - - - org.webjars.bower - datatables.net-bs - ${datatables-bs.version} - - - org.webjars.bower - datatables.net-buttons - ${datatables-buttons.version} - - - org.webjars.bower - datatables.net-buttons-bs - ${datatables-buttons-bs.version} - - - org.webjars.bower - datatables.net-responsive - ${datatables-responsive.version} - - - org.webjars.bower - datatables.net-responsive-bs - ${datatables-responsive-bs.version} - - - org.webjars.bower - datatables.net-select - ${datatables-select.version} - - - org.webjars.bower - datatables.net-select-bs - ${datatables-select-bs.version} - - - org.webjars.npm - jquery-datatables-checkboxes - ${datatables-checkboxes.version} - - - org.webjars.npm - jquery - - - org.webjars.npm - datatables.net - - - - - org.webjars.bower - github-com-julmot-datatables-mark-js - ${datatables-mark.version} - - - org.webjars.bower - datetimepicker - ${datetimepicker.version} - - - org.webjars.bower - font-awesome - ${fontawesome.version} - - - org.webjars.bower - jquery - ${jquery.version} - - - org.webjars - jquery.inputmask - ${jquery-inputmask.version} - - - org.webjars - jquery - - - - - org.webjars.bower - jquery-validation - ${jquery-validation.version} - - - org.webjars.bower - momentjs - ${momentjs.version} - - - org.webjars.bower - select2 - ${select2.version} - - - org.webjars.bower - select2-bootstrap-theme - ${select2-bootstrap-theme.version} - - - org.webjars - respond - ${respond.version} - - - org.webjars - html5shiv - ${html5shiv.version} - - - org.webjars.bower - ie10-viewport-bug-workaround - ${bootstrap.ie10-viewport-bug-workaround.version} - - - @@ -558,7 +312,8 @@ "projectName=${project.name}" --attribute "projectVersion=${project.version}" - --attribute "doctype=book" + --attribute + "doctype=book" ${project.groupId}:* @@ -642,4 +397,250 @@ + + + + maven-snapshot-repository + Maven Snapshot Repository + https://oss.sonatype.org/content/repositories/snapshots + + false + + + true + + + + + spring-roo-repository + Spring Roo Repository + http://repo.spring.io/spring-roo + + + + + + + + org.springframework.roo + org.springframework.roo.annotations + ${roo.version} + pom + provided + + + + io.springlets + springlets-data-jpa + ${springlets.version} + + + io.springlets + springlets-data-commons + ${springlets.version} + + + io.springlets + springlets-context + ${springlets.version} + + + org.springframework.roo + org.springframework.roo.querydsl.processor + ${querydsl-processor.version} + + + io.tracee.binding + tracee-springmvc + ${tracee.version} + + + io.springlets + springlets-boot-starter-web + ${springlets.version} + + + com.github.mxab.thymeleaf.extras + thymeleaf-extras-data-attribute + ${thymeleaf-data-dialect.version} + + + ar.com.fdvs + DynamicJasper + ${dynamicjasper.version} + + + ar.com.fdvs + DynamicJasper-core-fonts + ${dynamicjasper-fonts.version} + + + org.webjars.bower + bootstrap + ${bootstrap.version} + + + org.webjars.bower + datatables + ${datatables.version} + + + org.webjars.bower + datatables.net-bs + ${datatables-bs.version} + + + org.webjars.bower + datatables.net-buttons + ${datatables-buttons.version} + + + org.webjars.bower + datatables.net-buttons-bs + ${datatables-buttons-bs.version} + + + org.webjars.bower + datatables.net-responsive + ${datatables-responsive.version} + + + org.webjars.bower + datatables.net-responsive-bs + ${datatables-responsive-bs.version} + + + org.webjars.bower + datatables.net-select + ${datatables-select.version} + + + org.webjars.bower + datatables.net-select-bs + ${datatables-select-bs.version} + + + org.webjars.npm + jquery-datatables-checkboxes + ${datatables-checkboxes.version} + + + org.webjars.npm + jquery + + + org.webjars.npm + datatables.net + + + + + org.webjars.bower + github-com-julmot-datatables-mark-js + ${datatables-mark.version} + + + org.webjars.bower + datetimepicker + ${datetimepicker.version} + + + org.webjars.bower + font-awesome + ${fontawesome.version} + + + org.webjars.bower + jquery + ${jquery.version} + + + org.webjars + jquery.inputmask + ${jquery-inputmask.version} + + + org.webjars + jquery + + + + + org.webjars.bower + jquery-validation + ${jquery-validation.version} + + + org.webjars.bower + momentjs + ${momentjs.version} + + + org.webjars.bower + select2 + ${select2.version} + + + org.webjars.bower + select2-bootstrap-theme + ${select2-bootstrap-theme.version} + + + org.webjars + respond + ${respond.version} + + + org.webjars + html5shiv + ${html5shiv.version} + + + org.webjars.bower + ie10-viewport-bug-workaround + ${bootstrap.ie10-viewport-bug-workaround.version} + + + + + + 2.0.0.RC1 + 8 + UTF-8 + 1.8 + 1.5.4 + 1.4.1.RELEASE + 1.8 + 1.2.0.RC1 + 1.1.2 + 3.0.0.RELEASE + 2.0.0 + 2.0.1 + 5.0.11 + 1.0 + 3.3.6 + 1.10.12 + 1.10.11 + 1.1.2 + 1.1.2 + 2.0.2 + 2.0.2 + 1.1.2 + 1.1.2 + 1.1.2 + 2.0.0 + 2.5.4 + 4.6.2 + 1.12.3 + 3.3.1 + 1.15.0 + 2.13.0 + 4.0.3 + 0.1.0-beta.7 + 1.4.2 + 3.7.3 + 1.0.3 + 2.0.0.RELEASE + + diff --git a/spring-roo/src/main/resources/logback.xml b/spring-roo/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-roo/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-acl/pom.xml b/spring-security-acl/pom.xml index 88502bd268..c87c237233 100644 --- a/spring-security-acl/pom.xml +++ b/spring-security-acl/pom.xml @@ -1,12 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-security-acl 0.0.1-SNAPSHOT war - spring-security-acl Spring Security ACL @@ -18,29 +17,24 @@ - org.springframework.boot spring-boot-starter-data-jpa - com.h2database h2 - org.springframework spring-test test - org.springframework.security spring-security-test test - org.springframework.security spring-security-acl @@ -56,10 +50,13 @@ net.sf.ehcache ehcache-core - 2.6.11 + ${ehcache-core.version} jar - + + 2.6.11 + + diff --git a/spring-security-acl/src/main/resources/logback.xml b/spring-security-acl/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-acl/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-acl/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-acl/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..c7890d79ac --- /dev/null +++ b/spring-security-acl/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.acl.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-angular/README.md b/spring-security-angular/README.md new file mode 100644 index 0000000000..80312c4bab --- /dev/null +++ b/spring-security-angular/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Spring Security Login Page with Angular](https://www.baeldung.com/spring-security-login-angular) diff --git a/spring-security-angular/client/anguarjs/app.js b/spring-security-angular/client/anguarjs/app.js new file mode 100644 index 0000000000..4b7268da3f --- /dev/null +++ b/spring-security-angular/client/anguarjs/app.js @@ -0,0 +1,40 @@ +(function () { + 'use strict'; + + angular + .module('app', ['ngRoute']) + .config(config) + .run(run); + + config.$inject = ['$routeProvider', '$locationProvider']; + function config($routeProvider, $locationProvider) { + $routeProvider + .when('/', { + controller: 'HomeController', + templateUrl: 'home/home.view.html', + controllerAs: 'vm' + }) + .when('/login', { + controller: 'LoginController', + templateUrl: 'login/login.view.html', + controllerAs: 'vm' + }) + .otherwise({ redirectTo: '/login' }); + } + + run.$inject = ['$rootScope', '$location', '$http', '$window']; + function run($rootScope, $location, $http, $window) { + var userData = $window.sessionStorage.getItem('userData'); + if (userData) { + $http.defaults.headers.common['Authorization'] = 'Basic ' + JSON.parse(userData).authData; + } + + $rootScope.$on('$locationChangeStart', function (event, next, current) { + var restrictedPage = $.inArray($location.path(), ['/login']) === -1; + var loggedIn = $window.sessionStorage.getItem('userData');; + if (restrictedPage && !loggedIn) { + $location.path('/login'); + } + }); + } +})(); \ No newline at end of file diff --git a/spring-security-angular/client/anguarjs/home/home.controller.js b/spring-security-angular/client/anguarjs/home/home.controller.js new file mode 100644 index 0000000000..6449029ec2 --- /dev/null +++ b/spring-security-angular/client/anguarjs/home/home.controller.js @@ -0,0 +1,34 @@ +(function () { + 'use strict'; + + angular + .module('app') + .controller('HomeController', HomeController); + + HomeController.$inject = ['$window', '$http', '$scope']; + function HomeController($window, $http, $scope) { + var vm = this; + + vm.user = null; + + initController(); + + function initController() { + + $http({ + url: 'http://localhost:8082/user', + method: "GET" + }).then(function (response) { + vm.user = response.data.name; + },function(error){ + console.log(error); + }); + }; + + $scope.logout = function(){ + $window.sessionStorage.setItem('userData', ''); + $http.defaults.headers.common['Authorization'] = 'Basic'; + } + } + +})(); \ No newline at end of file diff --git a/spring-security-angular/client/anguarjs/home/home.view.html b/spring-security-angular/client/anguarjs/home/home.view.html new file mode 100644 index 0000000000..bb5c2d3dbf --- /dev/null +++ b/spring-security-angular/client/anguarjs/home/home.view.html @@ -0,0 +1,3 @@ +

    Hi {{vm.user}}!

    +

    You're logged in!!

    +

    Logout

    \ No newline at end of file diff --git a/spring-security-angular/client/anguarjs/index.html b/spring-security-angular/client/anguarjs/index.html new file mode 100644 index 0000000000..a5584d53be --- /dev/null +++ b/spring-security-angular/client/anguarjs/index.html @@ -0,0 +1,17 @@ + + + + + + +
    + + + + + + + + + + \ No newline at end of file diff --git a/spring-security-angular/client/anguarjs/login/login.controller.js b/spring-security-angular/client/anguarjs/login/login.controller.js new file mode 100644 index 0000000000..2da509ec83 --- /dev/null +++ b/spring-security-angular/client/anguarjs/login/login.controller.js @@ -0,0 +1,38 @@ +(function () { + 'use strict'; + + angular + .module('app') + .controller('LoginController', LoginController); + + LoginController.$inject = ['$location', '$window', '$http']; + function LoginController($location, $window, $http) { + var vm = this; + vm.login = login; + + (function initController() { + $window.localStorage.setItem('token', ''); + })(); + + function login() { + $http({ + url: 'http://localhost:8082/login', + method: "POST", + data: { 'userName': vm.username, 'password': vm.password } + }).then(function (response) { + if (response.data) { + var token = $window.btoa(vm.username + ':' + vm.password); + var userData = { + userName: vm.username, + authData: token + } + $window.sessionStorage.setItem('userData', JSON.stringify(userData)); + $http.defaults.headers.common['Authorization'] = 'Basic ' + token; + $location.path('/'); + } else { + alert("Authentication failed.") + } + }); + }; + } +})(); diff --git a/spring-security-angular/client/anguarjs/login/login.view.html b/spring-security-angular/client/anguarjs/login/login.view.html new file mode 100644 index 0000000000..0d42f29b54 --- /dev/null +++ b/spring-security-angular/client/anguarjs/login/login.view.html @@ -0,0 +1,18 @@ +
    +

    Login

    +
    +
    + + + Username is required +
    +
    + + + Password is required +
    +
    + +
    +
    +
    \ No newline at end of file diff --git a/spring-security-angular/client/angular2/app.css b/spring-security-angular/client/angular2/app.css new file mode 100644 index 0000000000..cdd2d591d8 --- /dev/null +++ b/spring-security-angular/client/angular2/app.css @@ -0,0 +1,7 @@ +a { + cursor: pointer; +} + +.help-block { + font-size: 12px; +} \ No newline at end of file diff --git a/spring-security-angular/client/angular2/app/app.component.html b/spring-security-angular/client/angular2/app/app.component.html new file mode 100644 index 0000000000..7f77adea7b --- /dev/null +++ b/spring-security-angular/client/angular2/app/app.component.html @@ -0,0 +1,7 @@ +
    +
    +
    + +
    +
    +
    diff --git a/spring-security-angular/client/angular2/app/app.component.ts b/spring-security-angular/client/angular2/app/app.component.ts new file mode 100644 index 0000000000..0aae2b6992 --- /dev/null +++ b/spring-security-angular/client/angular2/app/app.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app', + templateUrl: './app/app.component.html' +}) + +export class AppComponent { } \ No newline at end of file diff --git a/spring-security-angular/client/angular2/app/app.module.ts b/spring-security-angular/client/angular2/app/app.module.ts new file mode 100644 index 0000000000..4d484b49f8 --- /dev/null +++ b/spring-security-angular/client/angular2/app/app.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { AppComponent } from './app.component'; +import { routing } from './app.routing'; + +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + routing + ], + declarations: [ + AppComponent, + HomeComponent, + LoginComponent + ], + bootstrap: [AppComponent] +}) + +export class AppModule { } \ No newline at end of file diff --git a/spring-security-angular/client/angular2/app/app.routing.ts b/spring-security-angular/client/angular2/app/app.routing.ts new file mode 100644 index 0000000000..c794fc5c50 --- /dev/null +++ b/spring-security-angular/client/angular2/app/app.routing.ts @@ -0,0 +1,12 @@ +import { Routes, RouterModule } from '@angular/router'; + +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +const appRoutes: Routes = [ + { path: '', component: HomeComponent}, + { path: 'login', component: LoginComponent }, + { path: '**', redirectTo: '' } +]; + +export const routing = RouterModule.forRoot(appRoutes); \ No newline at end of file diff --git a/spring-security-angular/client/angular2/app/home/home.component.html b/spring-security-angular/client/angular2/app/home/home.component.html new file mode 100644 index 0000000000..5f3b24be3a --- /dev/null +++ b/spring-security-angular/client/angular2/app/home/home.component.html @@ -0,0 +1,4 @@ +
    +

    Hi {{userName}}!

    +

    Logout

    +
    \ No newline at end of file diff --git a/spring-security-angular/client/angular2/app/home/home.component.ts b/spring-security-angular/client/angular2/app/home/home.component.ts new file mode 100644 index 0000000000..1b168bfb30 --- /dev/null +++ b/spring-security-angular/client/angular2/app/home/home.component.ts @@ -0,0 +1,36 @@ +import { Component, OnInit } from '@angular/core'; +import { Http, RequestOptions, Headers } from '@angular/http'; +import 'rxjs/add/operator/map' + +@Component({ + selector:'home', + templateUrl: './app/home/home.component.html' +}) + +export class HomeComponent implements OnInit { + + userName: string; + + constructor(private http: Http) { } + + ngOnInit() { + let url = 'http://localhost:8082/user'; + let headers = new Headers({ + 'Authorization': 'Basic ' + sessionStorage.getItem('token') + }); + let options = new RequestOptions({ headers: headers }); + this.http.post(url,{}, options). + map(res => res.json()). + subscribe( + principal => this.userName = principal.name, + error => { + if(error.status == 401) + alert('Unauthorized'); + } + ); + } + + logout() { + sessionStorage.setItem('token', ''); + } +} \ No newline at end of file diff --git a/spring-security-angular/client/angular2/app/login/login.component.html b/spring-security-angular/client/angular2/app/login/login.component.html new file mode 100644 index 0000000000..d87b91a7bb --- /dev/null +++ b/spring-security-angular/client/angular2/app/login/login.component.html @@ -0,0 +1,18 @@ +
    +

    Login

    +
    +
    + + +
    Username is required
    +
    +
    + + +
    Password is required
    +
    +
    + +
    +
    +
    diff --git a/spring-security-angular/client/angular2/app/login/login.component.ts b/spring-security-angular/client/angular2/app/login/login.component.ts new file mode 100644 index 0000000000..81d6c1d7ae --- /dev/null +++ b/spring-security-angular/client/angular2/app/login/login.component.ts @@ -0,0 +1,36 @@ +import { Component, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { Http } from '@angular/http'; + +@Component({ + selector: 'login', + templateUrl: './app/login/login.component.html' +}) + +export class LoginComponent implements OnInit { + model: any = {}; + + constructor( + private route: ActivatedRoute, + private router: Router, + private http: Http) { } + + ngOnInit() { + sessionStorage.setItem('token', ''); + } + + login() { + let url = 'http://localhost:8082/login'; + let result = this.http.post(url, { + userName: this.model.username, + password: this.model.password + }).map(res => res.json()).subscribe(isValid => { + if (isValid) { + sessionStorage.setItem('token', btoa(this.model.username + ':' + this.model.password)); + this.router.navigate(['']); + } else { + alert("Authentication failed."); + } + }); + } +} diff --git a/spring-security-angular/client/angular2/app/main.ts b/spring-security-angular/client/angular2/app/main.ts new file mode 100644 index 0000000000..3a6c754786 --- /dev/null +++ b/spring-security-angular/client/angular2/app/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); \ No newline at end of file diff --git a/spring-security-angular/client/angular2/index.html b/spring-security-angular/client/angular2/index.html new file mode 100644 index 0000000000..c9730a8568 --- /dev/null +++ b/spring-security-angular/client/angular2/index.html @@ -0,0 +1,17 @@ + + + + + + + + + + + + + Loading... + + diff --git a/spring-security-angular/client/angular2/package.json b/spring-security-angular/client/angular2/package.json new file mode 100644 index 0000000000..9b36652fac --- /dev/null +++ b/spring-security-angular/client/angular2/package.json @@ -0,0 +1,37 @@ +{ + "name": "angular2-quickstart", + "version": "1.0.0", + "description": "Sample of how easy and fast to start hacking with Angular2 and ng2-bootstrap", + "scripts": { + "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ", + "lite": "lite-server", + "tsc": "tsc", + "tsc:w": "tsc -w" + }, + "license": "ISC", + "dependencies": { + "@angular/common": "2.4.4", + "@angular/compiler": "2.4.4", + "@angular/core": "2.4.4", + "@angular/forms": "2.4.4", + "@angular/http": "2.4.4", + "@angular/platform-browser": "2.4.4", + "@angular/platform-browser-dynamic": "2.4.4", + "@angular/router": "3.4.4", + "@angular/upgrade": "2.4.4", + "angular2-in-memory-web-api": "0.0.21", + "bootstrap": "^3.3.7", + "core-js": "^2.4.1", + "ng2-bootstrap": "1.3.0", + "reflect-metadata": "^0.1.8", + "rxjs": "5.0.3", + "systemjs": "0.20.0", + "zone.js": "0.7.6" + }, + "devDependencies": { + "concurrently": "3.1.0", + "lite-server": "^2.2.0", + "typescript": "2.1.5" + }, + "repository": {} +} diff --git a/spring-security-angular/client/angular2/systemjs.config.js b/spring-security-angular/client/angular2/systemjs.config.js new file mode 100644 index 0000000000..ea4c543fdd --- /dev/null +++ b/spring-security-angular/client/angular2/systemjs.config.js @@ -0,0 +1,41 @@ +/** + * System configuration for Angular 2 samples + * Adjust as necessary for your application needs. + */ +(function (global) { + System.config({ + paths: { + // paths serve as alias + 'npm:': 'node_modules/' + }, + // map tells the System loader where to look for things + map: { + // our app is within the app folder + app: 'app', + + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + + // other libraries + 'rxjs': 'npm:rxjs', + 'tslib': 'npm:tslib/tslib.js' + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + main: './main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + } + } + }); +})(this); diff --git a/spring-security-angular/client/angular2/tsconfig.json b/spring-security-angular/client/angular2/tsconfig.json new file mode 100644 index 0000000000..55f9ad70c3 --- /dev/null +++ b/spring-security-angular/client/angular2/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": [ "es2015", "dom" ], + "module": "commonjs", + "moduleResolution": "node", + "noImplicitAny": true, + "sourceMap": true, + "suppressImplicitAnyIndexErrors": true, + "target": "es5" + }, + "exclude": [ + "node_modules/*" + ] +} \ No newline at end of file diff --git a/spring-security-angular/client/angular4/.angular-cli.json b/spring-security-angular/client/angular4/.angular-cli.json new file mode 100644 index 0000000000..967934b2f7 --- /dev/null +++ b/spring-security-angular/client/angular4/.angular-cli.json @@ -0,0 +1,65 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "project": { + "name": "angular-crud" + }, + "apps": [ + { + "root": "src", + "outDir": "dist", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.ts", + "polyfills": "polyfills.ts", + "test": "test.ts", + "tsconfig": "tsconfig.app.json", + "testTsconfig": "tsconfig.spec.json", + "prefix": "app", + "styles": [ + "../node_modules/bootstrap/dist/css/bootstrap.min.css", + "styles.css", + "../node_modules/font-awesome/css/font-awesome.min.css" + ], + "scripts": [ + "../node_modules/jquery/dist/jquery.js", + "../node_modules/bootstrap/dist/js/bootstrap.js" + ], + "environmentSource": "environments/environment.ts", + "environments": { + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } + } + ], + "e2e": { + "protractor": { + "config": "./protractor.conf.js" + } + }, + "lint": [ + { + "project": "src/tsconfig.app.json", + "exclude": "**/node_modules/**" + }, + { + "project": "src/tsconfig.spec.json", + "exclude": "**/node_modules/**" + }, + { + "project": "e2e/tsconfig.e2e.json", + "exclude": "**/node_modules/**" + } + ], + "test": { + "karma": { + "config": "./karma.conf.js" + } + }, + "defaults": { + "styleExt": "css", + "component": {} + } +} \ No newline at end of file diff --git a/spring-security-angular/client/angular4/package.json b/spring-security-angular/client/angular4/package.json new file mode 100644 index 0000000000..8c6ddcaf1f --- /dev/null +++ b/spring-security-angular/client/angular4/package.json @@ -0,0 +1,54 @@ +{ + "name": "angular-crud", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" + }, + "private": true, + "dependencies": { + "@angular/animations": "^4.0.0", + "@angular/common": "^4.0.0", + "@angular/compiler": "^4.0.0", + "@angular/core": "^4.0.0", + "@angular/forms": "^4.0.0", + "@angular/http": "^4.0.0", + "@angular/platform-browser": "^4.0.0", + "@angular/platform-browser-dynamic": "^4.0.0", + "@angular/router": "^4.0.0", + "bootstrap": "^3.3.7", + "core-js": "^2.4.1", + "font-awesome": "^4.7.0", + "jquery": "^3.2.1", + "lodash": "^4.17.4", + "rxjs": "^5.4.1", + "zone.js": "^0.8.14" + }, + "devDependencies": { + "@angular/cli": "1.2.3", + "@angular/compiler-cli": "^4.0.0", + "@angular/language-service": "^4.0.0", + "@types/jasmine": "~2.5.53", + "@types/jasminewd2": "~2.0.2", + "@types/lodash": "^4.14.66", + "@types/node": "~6.0.60", + "codelyzer": "~3.0.1", + "jasmine-core": "~2.6.2", + "jasmine-spec-reporter": "~4.1.0", + "karma": "~1.7.0", + "karma-chrome-launcher": "~2.1.1", + "karma-cli": "~1.0.1", + "karma-coverage-istanbul-reporter": "^1.2.1", + "karma-jasmine": "~1.1.0", + "karma-jasmine-html-reporter": "^0.2.2", + "protractor": "~5.1.2", + "ts-node": "~3.0.4", + "tslint": "~5.3.2", + "typescript": "~2.3.3" + } +} diff --git a/spring-security-angular/client/angular4/src/app/app.component.html b/spring-security-angular/client/angular4/src/app/app.component.html new file mode 100644 index 0000000000..7f77adea7b --- /dev/null +++ b/spring-security-angular/client/angular4/src/app/app.component.html @@ -0,0 +1,7 @@ +
    +
    +
    + +
    +
    +
    diff --git a/spring-security-angular/client/angular4/src/app/app.component.ts b/spring-security-angular/client/angular4/src/app/app.component.ts new file mode 100644 index 0000000000..36f986c63f --- /dev/null +++ b/spring-security-angular/client/angular4/src/app/app.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html' +}) + +export class AppComponent { } \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/app/app.module.ts b/spring-security-angular/client/angular4/src/app/app.module.ts new file mode 100644 index 0000000000..9e840e6f13 --- /dev/null +++ b/spring-security-angular/client/angular4/src/app/app.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +// used to create fake backend + +import { AppComponent } from './app.component'; +import { routing } from './app.routing'; + +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + routing + ], + declarations: [ + AppComponent, + HomeComponent, + LoginComponent + ], + bootstrap: [AppComponent] +}) + +export class AppModule { } \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/app/app.routing.ts b/spring-security-angular/client/angular4/src/app/app.routing.ts new file mode 100644 index 0000000000..c794fc5c50 --- /dev/null +++ b/spring-security-angular/client/angular4/src/app/app.routing.ts @@ -0,0 +1,12 @@ +import { Routes, RouterModule } from '@angular/router'; + +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +const appRoutes: Routes = [ + { path: '', component: HomeComponent}, + { path: 'login', component: LoginComponent }, + { path: '**', redirectTo: '' } +]; + +export const routing = RouterModule.forRoot(appRoutes); \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/app/home/home.component.html b/spring-security-angular/client/angular4/src/app/home/home.component.html new file mode 100644 index 0000000000..7ccd2c2a3a --- /dev/null +++ b/spring-security-angular/client/angular4/src/app/home/home.component.html @@ -0,0 +1,4 @@ +
    +

    Hi {{userName}}!

    +

    Logout

    +
    \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/app/home/home.component.ts b/spring-security-angular/client/angular4/src/app/home/home.component.ts new file mode 100644 index 0000000000..0f66f42ce2 --- /dev/null +++ b/spring-security-angular/client/angular4/src/app/home/home.component.ts @@ -0,0 +1,37 @@ +import { Component, OnInit } from '@angular/core'; +import { Http, RequestOptions, Headers } from '@angular/http'; +import 'rxjs/add/operator/map' + +@Component({ + selector:'home', + templateUrl: './home.component.html' +}) + +export class HomeComponent implements OnInit { + + userName: string; + + constructor(private http: Http) { } + + ngOnInit() { + let url = 'http://localhost:8082/user'; + let headers = new Headers({ + 'Authorization': 'Basic ' + sessionStorage.getItem('token') + }); + let options = new RequestOptions({ headers: headers }); + this.http.post(url,{}, options). + map( + res => res.json(), + error => { + if(error.status == 401) + alert('Unauthorized'); + } + ).subscribe(principal => { + this.userName = principal.name; + }); + } + + logout() { + sessionStorage.setItem('token', ''); + } +} \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/app/login/login.component.html b/spring-security-angular/client/angular4/src/app/login/login.component.html new file mode 100644 index 0000000000..d87b91a7bb --- /dev/null +++ b/spring-security-angular/client/angular4/src/app/login/login.component.html @@ -0,0 +1,18 @@ +
    +

    Login

    +
    +
    + + +
    Username is required
    +
    +
    + + +
    Password is required
    +
    +
    + +
    +
    +
    diff --git a/spring-security-angular/client/angular4/src/app/login/login.component.ts b/spring-security-angular/client/angular4/src/app/login/login.component.ts new file mode 100644 index 0000000000..2a2dc102af --- /dev/null +++ b/spring-security-angular/client/angular4/src/app/login/login.component.ts @@ -0,0 +1,39 @@ +import { Component, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { Http } from '@angular/http'; + +@Component({ + selector: 'login', + templateUrl: './login.component.html' +}) + +export class LoginComponent implements OnInit { + model: any = {}; + + constructor( + private route: ActivatedRoute, + private router: Router, + private http: Http) { } + + ngOnInit() { + sessionStorage.setItem('token', ''); + } + + + login() { + let url = 'http://localhost:8082/login'; + let result = this.http.post(url, { + userName: this.model.username, + password: this.model.password + }). + map(res => res.json()). + subscribe(isValid => { + if (isValid) { + sessionStorage.setItem('token', btoa(this.model.username + ':' + this.model.password)); + this.router.navigate(['']); + } else { + alert("Authentication failed.") + } + }); + } +} diff --git a/spring-security-angular/client/angular4/src/index.html b/spring-security-angular/client/angular4/src/index.html new file mode 100644 index 0000000000..c716820396 --- /dev/null +++ b/spring-security-angular/client/angular4/src/index.html @@ -0,0 +1,14 @@ + + + + + AngularCRUD + + + + + + + + + \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/main.ts b/spring-security-angular/client/angular4/src/main.ts new file mode 100644 index 0000000000..49db98ae89 --- /dev/null +++ b/spring-security-angular/client/angular4/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/polyfills.ts b/spring-security-angular/client/angular4/src/polyfills.ts new file mode 100644 index 0000000000..a4984ced57 --- /dev/null +++ b/spring-security-angular/client/angular4/src/polyfills.ts @@ -0,0 +1,68 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. +/** Evergreen browsers require these. **/ +import 'core-js/es6/reflect'; +import 'core-js/es7/reflect'; + + +/** + * Required to support Web Animations `@angular/animation`. + * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + +/*************************************************************************************************** + * Zone JS is required by Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/** + * Date, currency, decimal and percent pipes. + * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 + */ +// import 'intl'; // Run `npm install --save intl`. +/** + * Need to import at least one locale-data with intl. + */ +// import 'intl/locale-data/jsonp/en'; \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/styles.css b/spring-security-angular/client/angular4/src/styles.css new file mode 100644 index 0000000000..cdd2d591d8 --- /dev/null +++ b/spring-security-angular/client/angular4/src/styles.css @@ -0,0 +1,7 @@ +a { + cursor: pointer; +} + +.help-block { + font-size: 12px; +} \ No newline at end of file diff --git a/spring-security-angular/client/angular4/src/tsconfig.app.json b/spring-security-angular/client/angular4/src/tsconfig.app.json new file mode 100644 index 0000000000..213ce42a1b --- /dev/null +++ b/spring-security-angular/client/angular4/src/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "baseUrl": "./", + "module": "es2015", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +} \ No newline at end of file diff --git a/spring-security-angular/client/angular4/tsconfig.json b/spring-security-angular/client/angular4/tsconfig.json new file mode 100644 index 0000000000..ef44e2862b --- /dev/null +++ b/spring-security-angular/client/angular4/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "dom" + ] + } +} diff --git a/spring-security-angular/client/angular4/tslint.json b/spring-security-angular/client/angular4/tslint.json new file mode 100644 index 0000000000..3ea984c776 --- /dev/null +++ b/spring-security-angular/client/angular4/tslint.json @@ -0,0 +1,130 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "deprecation": { + "severity": "warn" + }, + "eofline": true, + "forin": true, + "import-blacklist": [ + true, + "rxjs/Rx" + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "no-output-on-prefix": true, + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true + } +} diff --git a/spring-security-angular/client/angular5/.angular-cli.json b/spring-security-angular/client/angular5/.angular-cli.json new file mode 100644 index 0000000000..d390652214 --- /dev/null +++ b/spring-security-angular/client/angular5/.angular-cli.json @@ -0,0 +1,61 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "project": { + "name": "angular5" + }, + "apps": [ + { + "root": "src", + "outDir": "dist", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.ts", + "polyfills": "polyfills.ts", + "test": "test.ts", + "tsconfig": "tsconfig.app.json", + "testTsconfig": "tsconfig.spec.json", + "prefix": "app", + "styles": [ + "styles.css", + "../node_modules/ngx-toastr/toastr.css" + ], + "scripts": [], + "environmentSource": "environments/environment.ts", + "environments": { + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } + } + ], + "e2e": { + "protractor": { + "config": "./protractor.conf.js" + } + }, + "lint": [ + { + "project": "src/tsconfig.app.json", + "exclude": "**/node_modules/**" + }, + { + "project": "src/tsconfig.spec.json", + "exclude": "**/node_modules/**" + }, + { + "project": "e2e/tsconfig.e2e.json", + "exclude": "**/node_modules/**" + } + ], + "test": { + "karma": { + "config": "./karma.conf.js" + } + }, + "defaults": { + "styleExt": "css", + "component": {} + } +} \ No newline at end of file diff --git a/spring-security-angular/client/angular5/package.json b/spring-security-angular/client/angular5/package.json new file mode 100644 index 0000000000..45f455d191 --- /dev/null +++ b/spring-security-angular/client/angular5/package.json @@ -0,0 +1,50 @@ +{ + "name": "angular5", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build --prod", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" + }, + "private": true, + "dependencies": { + "@angular/animations": "^5.0.0", + "@angular/common": "^5.0.0", + "@angular/compiler": "^5.0.0", + "@angular/core": "^5.0.0", + "@angular/forms": "^5.0.0", + "@angular/http": "^5.0.0", + "@angular/platform-browser": "^5.0.0", + "@angular/platform-browser-dynamic": "^5.0.0", + "@angular/router": "^5.0.0", + "core-js": "^2.4.1", + "ngx-toastr": "^8.1.1", + "rxjs": "^5.5.2", + "zone.js": "^0.8.14" + }, + "devDependencies": { + "@angular/cli": "^1.6.6", + "@angular/compiler-cli": "^5.0.0", + "@angular/language-service": "^5.0.0", + "@types/jasmine": "~2.5.53", + "@types/jasminewd2": "~2.0.2", + "@types/node": "~6.0.60", + "codelyzer": "^4.0.1", + "jasmine-core": "~2.6.2", + "jasmine-spec-reporter": "~4.1.0", + "karma": "~1.7.0", + "karma-chrome-launcher": "~2.1.1", + "karma-cli": "~1.0.1", + "karma-coverage-istanbul-reporter": "^1.2.1", + "karma-jasmine": "~1.1.0", + "karma-jasmine-html-reporter": "^0.2.2", + "protractor": "~5.1.2", + "ts-node": "~3.2.0", + "tslint": "~5.7.0", + "typescript": "~2.4.2" + } +} diff --git a/spring-security-angular/client/angular5/src/app/app.component.html b/spring-security-angular/client/angular5/src/app/app.component.html new file mode 100644 index 0000000000..7f77adea7b --- /dev/null +++ b/spring-security-angular/client/angular5/src/app/app.component.html @@ -0,0 +1,7 @@ +
    +
    +
    + +
    +
    +
    diff --git a/spring-security-angular/client/angular5/src/app/app.component.ts b/spring-security-angular/client/angular5/src/app/app.component.ts new file mode 100644 index 0000000000..36f986c63f --- /dev/null +++ b/spring-security-angular/client/angular5/src/app/app.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html' +}) + +export class AppComponent { } \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/app/app.module.ts b/spring-security-angular/client/angular5/src/app/app.module.ts new file mode 100644 index 0000000000..9e840e6f13 --- /dev/null +++ b/spring-security-angular/client/angular5/src/app/app.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +// used to create fake backend + +import { AppComponent } from './app.component'; +import { routing } from './app.routing'; + +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpModule, + routing + ], + declarations: [ + AppComponent, + HomeComponent, + LoginComponent + ], + bootstrap: [AppComponent] +}) + +export class AppModule { } \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/app/app.routing.ts b/spring-security-angular/client/angular5/src/app/app.routing.ts new file mode 100644 index 0000000000..c794fc5c50 --- /dev/null +++ b/spring-security-angular/client/angular5/src/app/app.routing.ts @@ -0,0 +1,12 @@ +import { Routes, RouterModule } from '@angular/router'; + +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +const appRoutes: Routes = [ + { path: '', component: HomeComponent}, + { path: 'login', component: LoginComponent }, + { path: '**', redirectTo: '' } +]; + +export const routing = RouterModule.forRoot(appRoutes); \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/app/home/home.component.html b/spring-security-angular/client/angular5/src/app/home/home.component.html new file mode 100644 index 0000000000..7ccd2c2a3a --- /dev/null +++ b/spring-security-angular/client/angular5/src/app/home/home.component.html @@ -0,0 +1,4 @@ +
    +

    Hi {{userName}}!

    +

    Logout

    +
    \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/app/home/home.component.ts b/spring-security-angular/client/angular5/src/app/home/home.component.ts new file mode 100644 index 0000000000..7fe1ac4eff --- /dev/null +++ b/spring-security-angular/client/angular5/src/app/home/home.component.ts @@ -0,0 +1,37 @@ +import { Component, OnInit } from '@angular/core'; +import { Http, Headers, RequestOptions } from '@angular/http'; +import 'rxjs/add/operator/map' + +@Component({ + selector:'home', + templateUrl: './home.component.html' +}) + +export class HomeComponent implements OnInit { + + userName: string; + + constructor(private http: Http) { } + + ngOnInit() { + let url = 'http://localhost:8082/user'; + + let headers:Headers = new Headers({ + 'Authorization': 'Basic ' + sessionStorage.getItem('token') + }) + let options = new RequestOptions({headers: headers}); + this.http.post(url,{}, options).map( + res => res.json(), + error => { + if(error.status == 401) + alert('Unauthorized'); + } + ).subscribe(principal => { + this.userName = principal.name; + }); + } + + logout() { + sessionStorage.setItem('token', ''); + } +} \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/app/login/login.component.html b/spring-security-angular/client/angular5/src/app/login/login.component.html new file mode 100644 index 0000000000..d87b91a7bb --- /dev/null +++ b/spring-security-angular/client/angular5/src/app/login/login.component.html @@ -0,0 +1,18 @@ +
    +

    Login

    +
    +
    + + +
    Username is required
    +
    +
    + + +
    Password is required
    +
    +
    + +
    +
    +
    diff --git a/spring-security-angular/client/angular5/src/app/login/login.component.ts b/spring-security-angular/client/angular5/src/app/login/login.component.ts new file mode 100644 index 0000000000..2db8f32871 --- /dev/null +++ b/spring-security-angular/client/angular5/src/app/login/login.component.ts @@ -0,0 +1,37 @@ +import { Component, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { Http } from '@angular/http'; + +@Component({ + selector: 'login', + templateUrl: './login.component.html' +}) + +export class LoginComponent implements OnInit { + model: any = {}; + + constructor( + private route: ActivatedRoute, + private router: Router, + private http: Http) { } + + ngOnInit() { + sessionStorage.setItem('token', ''); + } + + + login() { + let url = 'http://localhost:8082/login'; + let result = this.http.post(url, { + userName: this.model.username, + password: this.model.password + }).map(res => res.json()).subscribe(isValid => { + if (isValid) { + sessionStorage.setItem('token', btoa(this.model.username + ':' + this.model.password)); + this.router.navigate(['']); + } else { + alert("Authentication failed.") + } + }); + } +} diff --git a/spring-security-angular/client/angular5/src/index.html b/spring-security-angular/client/angular5/src/index.html new file mode 100644 index 0000000000..c716820396 --- /dev/null +++ b/spring-security-angular/client/angular5/src/index.html @@ -0,0 +1,14 @@ + + + + + AngularCRUD + + + + + + + + + \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/main.ts b/spring-security-angular/client/angular5/src/main.ts new file mode 100644 index 0000000000..49db98ae89 --- /dev/null +++ b/spring-security-angular/client/angular5/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/polyfills.ts b/spring-security-angular/client/angular5/src/polyfills.ts new file mode 100644 index 0000000000..a4984ced57 --- /dev/null +++ b/spring-security-angular/client/angular5/src/polyfills.ts @@ -0,0 +1,68 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. +/** Evergreen browsers require these. **/ +import 'core-js/es6/reflect'; +import 'core-js/es7/reflect'; + + +/** + * Required to support Web Animations `@angular/animation`. + * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + +/*************************************************************************************************** + * Zone JS is required by Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/** + * Date, currency, decimal and percent pipes. + * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 + */ +// import 'intl'; // Run `npm install --save intl`. +/** + * Need to import at least one locale-data with intl. + */ +// import 'intl/locale-data/jsonp/en'; \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/styles.css b/spring-security-angular/client/angular5/src/styles.css new file mode 100644 index 0000000000..cdd2d591d8 --- /dev/null +++ b/spring-security-angular/client/angular5/src/styles.css @@ -0,0 +1,7 @@ +a { + cursor: pointer; +} + +.help-block { + font-size: 12px; +} \ No newline at end of file diff --git a/spring-security-angular/client/angular5/src/tsconfig.app.json b/spring-security-angular/client/angular5/src/tsconfig.app.json new file mode 100644 index 0000000000..213ce42a1b --- /dev/null +++ b/spring-security-angular/client/angular5/src/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "baseUrl": "./", + "module": "es2015", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +} \ No newline at end of file diff --git a/spring-security-angular/client/angular5/tsconfig.json b/spring-security-angular/client/angular5/tsconfig.json new file mode 100644 index 0000000000..0fdb5c817d --- /dev/null +++ b/spring-security-angular/client/angular5/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "dom" + ] + } +} \ No newline at end of file diff --git a/spring-security-angular/client/angular5/tslint.json b/spring-security-angular/client/angular5/tslint.json new file mode 100644 index 0000000000..1c1d53b0d9 --- /dev/null +++ b/spring-security-angular/client/angular5/tslint.json @@ -0,0 +1,144 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "deprecation": { + "severity": "warn" + }, + "eofline": true, + "forin": true, + "import-blacklist": [ + true, + "rxjs", + "rxjs/Rx" + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "typeof-compare": true, + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "directive-selector": [ + true, + "attribute", + "app", + "camelCase" + ], + "component-selector": [ + true, + "element", + "app", + "kebab-case" + ], + "no-output-on-prefix": true, + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true + } +} \ No newline at end of file diff --git a/spring-security-angular/client/angular6/angular.json b/spring-security-angular/client/angular6/angular.json new file mode 100644 index 0000000000..0168c58817 --- /dev/null +++ b/spring-security-angular/client/angular6/angular.json @@ -0,0 +1,127 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "angular6-login": { + "root": "", + "sourceRoot": "src", + "projectType": "application", + "prefix": "app", + "schematics": {}, + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/angular6-login", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.app.json", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/styles.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "angular6-login:build" + }, + "configurations": { + "production": { + "browserTarget": "angular6-login:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "angular6-login:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.spec.json", + "karmaConfig": "src/karma.conf.js", + "styles": [ + "src/styles.css" + ], + "scripts": [], + "assets": [ + "src/favicon.ico", + "src/assets" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "src/tsconfig.app.json", + "src/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "angular6-login-e2e": { + "root": "e2e/", + "projectType": "application", + "architect": { + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "angular6-login:serve" + }, + "configurations": { + "production": { + "devServerTarget": "angular6-login:serve:production" + } + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": "e2e/tsconfig.e2e.json", + "exclude": [ + "**/node_modules/**" + ] + } + } + } + } + }, + "defaultProject": "angular6-login" +} \ No newline at end of file diff --git a/spring-security-angular/client/angular6/package.json b/spring-security-angular/client/angular6/package.json new file mode 100644 index 0000000000..a0adcd03f3 --- /dev/null +++ b/spring-security-angular/client/angular6/package.json @@ -0,0 +1,48 @@ +{ + "name": "angular6-login", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" + }, + "private": true, + "dependencies": { + "@angular/animations": "^6.0.3", + "@angular/common": "^6.0.3", + "@angular/compiler": "^6.0.3", + "@angular/core": "^6.0.3", + "@angular/forms": "^6.0.3", + "@angular/http": "^6.0.3", + "@angular/platform-browser": "^6.0.3", + "@angular/platform-browser-dynamic": "^6.0.3", + "@angular/router": "^6.0.3", + "core-js": "^2.5.4", + "rxjs": "^6.0.0", + "zone.js": "^0.8.26" + }, + "devDependencies": { + "@angular/compiler-cli": "^6.0.3", + "@angular-devkit/build-angular": "~0.6.8", + "typescript": "~2.7.2", + "@angular/cli": "~6.0.8", + "@angular/language-service": "^6.0.3", + "@types/jasmine": "~2.8.6", + "@types/jasminewd2": "~2.0.3", + "@types/node": "~8.9.4", + "codelyzer": "~4.2.1", + "jasmine-core": "~2.99.1", + "jasmine-spec-reporter": "~4.2.1", + "karma": "~1.7.1", + "karma-chrome-launcher": "~2.2.0", + "karma-coverage-istanbul-reporter": "~2.0.0", + "karma-jasmine": "~1.1.1", + "karma-jasmine-html-reporter": "^0.2.2", + "protractor": "~5.3.0", + "ts-node": "~5.0.1", + "tslint": "~5.9.1" + } +} diff --git a/spring-security-angular/client/angular6/src/app/app.component.html b/spring-security-angular/client/angular6/src/app/app.component.html new file mode 100644 index 0000000000..6bf00f3018 --- /dev/null +++ b/spring-security-angular/client/angular6/src/app/app.component.html @@ -0,0 +1,2 @@ + + diff --git a/spring-security-angular/client/angular6/src/app/app.component.ts b/spring-security-angular/client/angular6/src/app/app.component.ts new file mode 100644 index 0000000000..36f986c63f --- /dev/null +++ b/spring-security-angular/client/angular6/src/app/app.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html' +}) + +export class AppComponent { } \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/app/app.module.ts b/spring-security-angular/client/angular6/src/app/app.module.ts new file mode 100644 index 0000000000..4f9a792e19 --- /dev/null +++ b/spring-security-angular/client/angular6/src/app/app.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { HttpClientModule } from '@angular/common/http'; + +import { AppComponent } from './app.component'; +import { routing } from './app.routing'; + +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +@NgModule({ + imports: [ + BrowserModule, + FormsModule, + HttpClientModule, + routing + ], + declarations: [ + AppComponent, + HomeComponent, + LoginComponent + ], + bootstrap: [AppComponent] +}) + +export class AppModule { } \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/app/app.routing.ts b/spring-security-angular/client/angular6/src/app/app.routing.ts new file mode 100644 index 0000000000..e5f5e04aa8 --- /dev/null +++ b/spring-security-angular/client/angular6/src/app/app.routing.ts @@ -0,0 +1,11 @@ +import { Routes, RouterModule } from '@angular/router'; +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +const appRoutes: Routes = [ + { path: '', component: HomeComponent }, + { path: 'login', component: LoginComponent }, + { path: '**', redirectTo: '' } +]; + +export const routing = RouterModule.forRoot(appRoutes); \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/app/home/home.component.html b/spring-security-angular/client/angular6/src/app/home/home.component.html new file mode 100644 index 0000000000..7ccd2c2a3a --- /dev/null +++ b/spring-security-angular/client/angular6/src/app/home/home.component.html @@ -0,0 +1,4 @@ +
    +

    Hi {{userName}}!

    +

    Logout

    +
    \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/app/home/home.component.ts b/spring-security-angular/client/angular6/src/app/home/home.component.ts new file mode 100644 index 0000000000..6c9fcfd97f --- /dev/null +++ b/spring-security-angular/client/angular6/src/app/home/home.component.ts @@ -0,0 +1,49 @@ +import { Component, OnInit } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError, map, tap} from 'rxjs/operators'; +@Component({ + selector: 'home', + templateUrl: './home.component.html' +}) + +export class HomeComponent implements OnInit { + + userName: string; + + constructor(private http: HttpClient) { } + + ngOnInit() { + let url = 'http://localhost:8082/user'; + + let headers: HttpHeaders = new HttpHeaders({ + 'Authorization': 'Basic ' + sessionStorage.getItem('token') + }); + + let options = { headers: headers }; + this.http.post>(url, {}, options). + subscribe(principal => { + this.userName = principal['name']; + }, + error => { + if(error.status == 401) + alert('Unauthorized'); + } + ); + } + + logout() { + sessionStorage.setItem('token', ''); + } + private handleError(error: HttpErrorResponse) { + if (error.error instanceof ErrorEvent) { + console.error('An error occurred:', error.error.message); + } else { + console.error( + `Backend returned code ${error.status}, ` + + `body was: ${error.error}`); + } + return throwError( + 'Something bad happened; please try again later.'); + }; +} \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/app/login/login.component.html b/spring-security-angular/client/angular6/src/app/login/login.component.html new file mode 100644 index 0000000000..4291206469 --- /dev/null +++ b/spring-security-angular/client/angular6/src/app/login/login.component.html @@ -0,0 +1,15 @@ +
    +
    + + +
    Username is required
    +
    +
    + + +
    Password is required
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/app/login/login.component.ts b/spring-security-angular/client/angular6/src/app/login/login.component.ts new file mode 100644 index 0000000000..27af9ebba5 --- /dev/null +++ b/spring-security-angular/client/angular6/src/app/login/login.component.ts @@ -0,0 +1,39 @@ +import { Component, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'login', + templateUrl: './login.component.html' +}) + +export class LoginComponent implements OnInit { + + model: any = {}; + + constructor( + private route: ActivatedRoute, + private router: Router, + private http: HttpClient + ) { } + + ngOnInit() { + sessionStorage.setItem('token', ''); + } + + login() { + let url = 'http://localhost:8082/login'; + this.http.post>(url, { + userName: this.model.username, + password: this.model.password + }).subscribe(isValid => { + if (isValid) { + sessionStorage.setItem('token', btoa(this.model.username + ':' + this.model.password)); + this.router.navigate(['']); + } else { + alert("Authentication failed.") + } + }); + } +} diff --git a/spring-security-angular/client/angular6/src/index.html b/spring-security-angular/client/angular6/src/index.html new file mode 100644 index 0000000000..c716820396 --- /dev/null +++ b/spring-security-angular/client/angular6/src/index.html @@ -0,0 +1,14 @@ + + + + + AngularCRUD + + + + + + + + + \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/main.ts b/spring-security-angular/client/angular6/src/main.ts new file mode 100644 index 0000000000..49db98ae89 --- /dev/null +++ b/spring-security-angular/client/angular6/src/main.ts @@ -0,0 +1,5 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic().bootstrapModule(AppModule); \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/polyfills.ts b/spring-security-angular/client/angular6/src/polyfills.ts new file mode 100644 index 0000000000..a4984ced57 --- /dev/null +++ b/spring-security-angular/client/angular6/src/polyfills.ts @@ -0,0 +1,68 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. +/** Evergreen browsers require these. **/ +import 'core-js/es6/reflect'; +import 'core-js/es7/reflect'; + + +/** + * Required to support Web Animations `@angular/animation`. + * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + + +/*************************************************************************************************** + * Zone JS is required by Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/** + * Date, currency, decimal and percent pipes. + * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 + */ +// import 'intl'; // Run `npm install --save intl`. +/** + * Need to import at least one locale-data with intl. + */ +// import 'intl/locale-data/jsonp/en'; \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/styles.css b/spring-security-angular/client/angular6/src/styles.css new file mode 100644 index 0000000000..cdd2d591d8 --- /dev/null +++ b/spring-security-angular/client/angular6/src/styles.css @@ -0,0 +1,7 @@ +a { + cursor: pointer; +} + +.help-block { + font-size: 12px; +} \ No newline at end of file diff --git a/spring-security-angular/client/angular6/src/tsconfig.app.json b/spring-security-angular/client/angular6/src/tsconfig.app.json new file mode 100644 index 0000000000..213ce42a1b --- /dev/null +++ b/spring-security-angular/client/angular6/src/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "baseUrl": "./", + "module": "es2015", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +} \ No newline at end of file diff --git a/spring-security-angular/client/angular6/tsconfig.json b/spring-security-angular/client/angular6/tsconfig.json new file mode 100644 index 0000000000..ef44e2862b --- /dev/null +++ b/spring-security-angular/client/angular6/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "dom" + ] + } +} diff --git a/spring-security-angular/client/angular6/tslint.json b/spring-security-angular/client/angular6/tslint.json new file mode 100644 index 0000000000..3ea984c776 --- /dev/null +++ b/spring-security-angular/client/angular6/tslint.json @@ -0,0 +1,130 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "deprecation": { + "severity": "warn" + }, + "eofline": true, + "forin": true, + "import-blacklist": [ + true, + "rxjs/Rx" + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "no-output-on-prefix": true, + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true + } +} diff --git a/spring-security-angular/server/pom.xml b/spring-security-angular/server/pom.xml new file mode 100644 index 0000000000..c1faecca55 --- /dev/null +++ b/spring-security-angular/server/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + com.baeldung + spring-security-angular + 0.0.1-SNAPSHOT + jar + spring-security-angular + Spring Security Angular + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + + org.springframework.boot + spring-boot-dependencies + 1.5.9.RELEASE + pom + import + + + + + + + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + UTF-8 + UTF-8 + + + diff --git a/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/SpringBootSecurityApplication.java b/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/SpringBootSecurityApplication.java new file mode 100644 index 0000000000..681c7590a8 --- /dev/null +++ b/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/SpringBootSecurityApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.springbootsecurityrest.basicauth; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.baeldung.springbootsecurityrest") +@EnableAutoConfiguration +public class SpringBootSecurityApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootSecurityApplication.class, args); + } +} diff --git a/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/config/BasicAuthConfiguration.java b/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/config/BasicAuthConfiguration.java new file mode 100644 index 0000000000..3ed301439c --- /dev/null +++ b/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/basicauth/config/BasicAuthConfiguration.java @@ -0,0 +1,34 @@ +package com.baeldung.springbootsecurityrest.basicauth.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +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; + +@Configuration +@EnableWebSecurity +public class BasicAuthConfiguration extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user") + .password("password") + .roles("USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable() + .authorizeRequests() + .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() + .antMatchers("/login").permitAll() + .anyRequest() + .authenticated() + .and() + .httpBasic(); + } +} diff --git a/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/controller/UserController.java b/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/controller/UserController.java new file mode 100644 index 0000000000..ab66065b61 --- /dev/null +++ b/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/controller/UserController.java @@ -0,0 +1,29 @@ +package com.baeldung.springbootsecurityrest.controller; + +import java.security.Principal; +import java.util.Base64; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.springbootsecurityrest.vo.User; + +@RestController +@CrossOrigin +public class UserController { + + @RequestMapping("/login") + public boolean login(@RequestBody User user) { + return user.getUserName().equals("user") && user.getPassword().equals("password"); + } + + @RequestMapping("/user") + public Principal user(HttpServletRequest request) { + String authToken = request.getHeader("Authorization").substring("Basic".length()).trim(); + return () -> new String(Base64.getDecoder().decode(authToken)).split(":")[0]; + } +} diff --git a/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/vo/User.java b/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/vo/User.java new file mode 100644 index 0000000000..0eda5ce9ec --- /dev/null +++ b/spring-security-angular/server/src/main/java/com/baeldung/springbootsecurityrest/vo/User.java @@ -0,0 +1,21 @@ +package com.baeldung.springbootsecurityrest.vo; + + +public class User { + + private String userName; + private String password; + + public String getUserName() { + return userName; + } + public void setUserName(String userName) { + this.userName = userName; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } +} diff --git a/spring-security-angular/server/src/main/resources/application.properties b/spring-security-angular/server/src/main/resources/application.properties new file mode 100644 index 0000000000..565d97a7b0 --- /dev/null +++ b/spring-security-angular/server/src/main/resources/application.properties @@ -0,0 +1,5 @@ +#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration +#security.user.password=password +#security.oauth2.client.client-id=client +#security.oauth2.client.client-secret=secret +server.port=8082 diff --git a/spring-security-angular/server/src/main/resources/logback.xml b/spring-security-angular/server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-angular/server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-angular/server/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java b/spring-security-angular/server/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java new file mode 100644 index 0000000000..952a0806a1 --- /dev/null +++ b/spring-security-angular/server/src/test/java/com/baeldung/springbootsecurityrest/BasicAuthConfigurationIntegrationTest.java @@ -0,0 +1,87 @@ +package com.baeldung.springbootsecurityrest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springbootsecurityrest.basicauth.SpringBootSecurityApplication; +import com.baeldung.springbootsecurityrest.vo.User; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = RANDOM_PORT, classes = SpringBootSecurityApplication.class) +public class BasicAuthConfigurationIntegrationTest { + + TestRestTemplate restTemplate; + URL base; + + @LocalServerPort int port; + + @Before + public void setUp() throws MalformedURLException { + restTemplate = new TestRestTemplate("user", "password"); + base = new URL("http://localhost:" + port); + } + + @Test + public void givenCorrectCredentials_whenLogin_ThenSuccess() throws IllegalStateException, IOException { + restTemplate = new TestRestTemplate(); + User user = new User(); + user.setUserName("user"); + user.setPassword("password"); + ResponseEntity response = restTemplate.postForEntity(base.toString()+"/login",user, String.class); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertTrue(response + .getBody() + .contains("true")); + } + + @Test + public void givenWrongCredentials_whenLogin_ThenReturnFalse() throws IllegalStateException, IOException { + restTemplate = new TestRestTemplate(); + User user = new User(); + user.setUserName("user"); + user.setPassword("wrongpassword"); + ResponseEntity response = restTemplate.postForEntity(base.toString()+"/login",user, String.class); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertTrue(response + .getBody() + .contains("false")); + } + + @Test + public void givenLoggedInUser_whenRequestsHomePage_ThenSuccess() throws IllegalStateException, IOException { + ResponseEntity response = restTemplate.getForEntity(base.toString()+"/user", String.class); + + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertTrue(response + .getBody() + .contains("user")); + } + + @Test + public void givenWrongCredentials_whenRequestsHomePage_ThenUnauthorized() throws IllegalStateException, IOException { + restTemplate = new TestRestTemplate("user", "wrongpassword"); + ResponseEntity response = restTemplate.getForEntity(base.toString()+"/user", String.class); + + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue(response + .getBody() + .contains("Unauthorized")); + } +} diff --git a/spring-security-angular/server/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-angular/server/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..8c62ac5e91 --- /dev/null +++ b/spring-security-angular/server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springbootsecurityrest.basicauth.SpringBootSecurityApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringBootSecurityApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-cache-control/pom.xml b/spring-security-cache-control/pom.xml index 85b8b5a203..b7dfc9db3a 100644 --- a/spring-security-cache-control/pom.xml +++ b/spring-security-cache-control/pom.xml @@ -1,6 +1,6 @@ + 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 diff --git a/spring-security-cache-control/src/main/resources/logback.xml b/spring-security-cache-control/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-cache-control/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-cache-control/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-cache-control/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..c047fc6210 --- /dev/null +++ b/spring-security-cache-control/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.cachecontrol.AppRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AppRunner.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-client/spring-security-jsp-authentication/pom.xml b/spring-security-client/spring-security-jsp-authentication/pom.xml index 637fd3dbdb..0e564b47b8 100644 --- a/spring-security-client/spring-security-jsp-authentication/pom.xml +++ b/spring-security-client/spring-security-jsp-authentication/pom.xml @@ -1,13 +1,11 @@ + 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 spring-security-jsp-authentication 0.0.1-SNAPSHOT war - spring-security-jsp-authenticate Spring Security JSP Authentication tag sample @@ -27,28 +25,23 @@ org.springframework.boot spring-boot-starter-web
    - org.springframework.boot spring-boot-starter-tomcat - org.apache.tomcat.embed tomcat-embed-jasper provided - javax.servlet jstl - org.springframework.security spring-security-taglibs -
    diff --git a/spring-security-client/spring-security-jsp-authentication/src/main/resources/logback.xml b/spring-security-client/spring-security-jsp-authentication/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-client/spring-security-jsp-authentication/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..66243ef00d --- /dev/null +++ b/spring-security-client/spring-security-jsp-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-client/spring-security-jsp-authorize/pom.xml b/spring-security-client/spring-security-jsp-authorize/pom.xml index 94f70ed5f0..427ba7754a 100644 --- a/spring-security-client/spring-security-jsp-authorize/pom.xml +++ b/spring-security-client/spring-security-jsp-authorize/pom.xml @@ -1,13 +1,12 @@ + 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 spring-security-jsp-authorize 0.0.1-SNAPSHOT war - spring-security-jsp-authorize Spring Security JSP Authorize tag sample @@ -27,28 +26,23 @@ org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-tomcat - org.apache.tomcat.embed tomcat-embed-jasper provided - javax.servlet jstl - org.springframework.security spring-security-taglibs - diff --git a/spring-security-client/spring-security-jsp-authorize/src/main/resources/logback.xml b/spring-security-client/spring-security-jsp-authorize/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-client/spring-security-jsp-authorize/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..66243ef00d --- /dev/null +++ b/spring-security-client/spring-security-jsp-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-client/spring-security-jsp-config/pom.xml b/spring-security-client/spring-security-jsp-config/pom.xml index 54dc2fe947..c0318a2c5c 100644 --- a/spring-security-client/spring-security-jsp-config/pom.xml +++ b/spring-security-client/spring-security-jsp-config/pom.xml @@ -1,13 +1,11 @@ + 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 spring-security-jsp-config 0.0.1-SNAPSHOT war - spring-security-jsp-config Spring Security JSP configuration @@ -27,28 +25,23 @@ org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-tomcat - org.apache.tomcat.embed tomcat-embed-jasper provided - javax.servlet jstl - org.springframework.security spring-security-taglibs - diff --git a/spring-security-client/spring-security-jsp-config/src/main/resources/logback.xml b/spring-security-client/spring-security-jsp-config/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-client/spring-security-jsp-config/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..66243ef00d --- /dev/null +++ b/spring-security-client/spring-security-jsp-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-client/spring-security-mvc/pom.xml b/spring-security-client/spring-security-mvc/pom.xml index 5064aec7e8..6ddc6fbe65 100644 --- a/spring-security-client/spring-security-mvc/pom.xml +++ b/spring-security-client/spring-security-mvc/pom.xml @@ -1,13 +1,11 @@ + 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 spring-security-mvc 0.0.1-SNAPSHOT war - spring-security-mvc Spring Security MVC @@ -27,7 +25,6 @@ org.springframework.boot spring-boot-starter-web - diff --git a/spring-security-client/spring-security-mvc/src/main/resources/logback.xml b/spring-security-client/spring-security-mvc/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-client/spring-security-mvc/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..66243ef00d --- /dev/null +++ b/spring-security-client/spring-security-mvc/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-client/spring-security-thymeleaf-authentication/pom.xml b/spring-security-client/spring-security-thymeleaf-authentication/pom.xml index 7bea8124e7..8e6a352af1 100644 --- a/spring-security-client/spring-security-thymeleaf-authentication/pom.xml +++ b/spring-security-client/spring-security-thymeleaf-authentication/pom.xml @@ -1,13 +1,12 @@ + 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 spring-security-thymeleaf-authentication 0.0.1-SNAPSHOT war - spring-security-thymeleaf-authentication Spring Security thymeleaf authentication tag sample @@ -27,22 +26,18 @@ org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-tomcat - org.springframework.boot spring-boot-starter-thymeleaf - org.thymeleaf.extras thymeleaf-extras-springsecurity4 - diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/logback.xml b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..66243ef00d --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authentication/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-client/spring-security-thymeleaf-authorize/pom.xml b/spring-security-client/spring-security-thymeleaf-authorize/pom.xml index b03464877a..52972c0241 100644 --- a/spring-security-client/spring-security-thymeleaf-authorize/pom.xml +++ b/spring-security-client/spring-security-thymeleaf-authorize/pom.xml @@ -1,13 +1,12 @@ + 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 spring-security-thymeleaf-authorize 0.0.1-SNAPSHOT war - spring-security-thymeleaf-authorize Spring Security thymeleaf authorize tag sample @@ -27,22 +26,18 @@ org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-tomcat - org.springframework.boot spring-boot-starter-thymeleaf - org.thymeleaf.extras thymeleaf-extras-springsecurity4 - diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/logback.xml b/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authorize/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..66243ef00d --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-authorize/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-client/spring-security-thymeleaf-config/pom.xml b/spring-security-client/spring-security-thymeleaf-config/pom.xml index 3abe9d8c8b..668f20c001 100644 --- a/spring-security-client/spring-security-thymeleaf-config/pom.xml +++ b/spring-security-client/spring-security-thymeleaf-config/pom.xml @@ -1,13 +1,12 @@ + 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 spring-security-thymeleaf-config 0.0.1-SNAPSHOT war - spring-security-thymeleaf-config Spring Security thymeleaf configuration sample project @@ -27,22 +26,18 @@ org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-tomcat - org.springframework.boot spring-boot-starter-thymeleaf - org.thymeleaf.extras thymeleaf-extras-springsecurity4 - diff --git a/spring-security-client/spring-security-thymeleaf-config/src/main/resources/logback.xml b/spring-security-client/spring-security-thymeleaf-config/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-config/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..66243ef00d --- /dev/null +++ b/spring-security-client/spring-security-thymeleaf-config/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.Application; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-core/pom.xml b/spring-security-core/pom.xml index a11743d9fa..41dea087d3 100644 --- a/spring-security-core/pom.xml +++ b/spring-security-core/pom.xml @@ -1,5 +1,5 @@ + 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 spring-security-core @@ -56,16 +56,12 @@ true - - org.apache.maven.plugins maven-war-plugin - - @@ -73,7 +69,6 @@ live - org.apache.maven.plugins maven-surefire-plugin @@ -97,7 +92,6 @@ - diff --git a/spring-security-core/src/main/resources/logback.xml b/spring-security-core/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-core/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-core/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-core/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..5698afa417 --- /dev/null +++ b/spring-security-core/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.app.App; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = App.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-mvc-boot/README.MD b/spring-security-mvc-boot/README.MD index 32976b0896..6f01bfdc65 100644 --- a/spring-security-mvc-boot/README.MD +++ b/spring-security-mvc-boot/README.MD @@ -1,7 +1,7 @@ -###The Course +### The Course The "REST With Spring" Classes: http://github.learnspringsecurity.com -###Relevant Articles: +### Relevant Articles: - [A Custom Security Expression with Spring Security](http://www.baeldung.com/spring-security-create-new-custom-security-expression) - [Custom AccessDecisionVoters in Spring Security](http://www.baeldung.com/spring-security-custom-voter) - [Spring Security: Authentication with a Database-backed UserDetailsService](http://www.baeldung.com/spring-security-authentication-with-a-database) @@ -9,3 +9,6 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com - [Multiple Entry Points in Spring Security](http://www.baeldung.com/spring-security-multiple-entry-points) - [Multiple Authentication Providers in Spring Security](http://www.baeldung.com/spring-security-multiple-auth-providers) - [Granted Authority Versus Role in Spring Security](http://www.baeldung.com/spring-security-granted-authority-vs-role) +- [Spring Data with Spring Security](https://www.baeldung.com/spring-data-security) +- [Spring Security – Whitelist IP Range](https://www.baeldung.com/spring-security-whitelist-ip-range) +- [Find the Registered Spring Security Filters](https://www.baeldung.com/spring-security-registered-filters) diff --git a/spring-security-mvc-boot/pom.xml b/spring-security-mvc-boot/pom.xml index 3b1796b978..4090beab99 100644 --- a/spring-security-mvc-boot/pom.xml +++ b/spring-security-mvc-boot/pom.xml @@ -7,7 +7,6 @@ spring-security-mvc-boot 0.0.1-SNAPSHOT war - spring-security-mvc-boot Spring Security MVC Boot @@ -19,7 +18,6 @@ - org.springframework.boot spring-boot-starter-security @@ -32,53 +30,46 @@ org.springframework.boot spring-boot-starter-tomcat - org.springframework.boot spring-boot-starter-thymeleaf - org.thymeleaf.extras thymeleaf-extras-springsecurity4 - - - org.springframework.boot spring-boot-starter-data-jpa - + + org.springframework.security + spring-security-data + com.h2database h2 - org.hamcrest hamcrest-core test - org.hamcrest hamcrest-library test - org.springframework spring-test test - org.springframework.security spring-security-test test - taglibs standard @@ -88,18 +79,15 @@ org.springframework.security spring-security-taglibs - org.springframework.security spring-security-core - javax.servlet.jsp.jstl jstl-api ${jstl.version} - org.springframework.security spring-security-config @@ -111,7 +99,7 @@ net.sf.ehcache ehcache-core - 2.6.11 + ${ehcache-core.version} jar @@ -246,6 +234,7 @@ 1.1.2 1.2 1.6.1 + 2.6.11
    diff --git a/spring-data-spring-security/src/main/java/com/baeldung/AppConfig.java b/spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/AppConfig.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/AppConfig.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/SpringSecurityConfig.java b/spring-security-mvc-boot/src/main/java/com/baeldung/SpringSecurityConfig.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/SpringSecurityConfig.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/SpringSecurityConfig.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/data/repositories/TweetRepository.java b/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/TweetRepository.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/data/repositories/TweetRepository.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/TweetRepository.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/data/repositories/UserRepository.java b/spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/UserRepository.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/data/repositories/UserRepository.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/data/repositories/UserRepository.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/models/AppUser.java b/spring-security-mvc-boot/src/main/java/com/baeldung/models/AppUser.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/models/AppUser.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/models/AppUser.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/models/Tweet.java b/spring-security-mvc-boot/src/main/java/com/baeldung/models/Tweet.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/models/Tweet.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/models/Tweet.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/security/AppUserPrincipal.java b/spring-security-mvc-boot/src/main/java/com/baeldung/security/AppUserPrincipal.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/security/AppUserPrincipal.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/security/AppUserPrincipal.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java b/spring-security-mvc-boot/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/security/AuthenticationSuccessHandlerImpl.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/security/CustomUserDetailsService.java b/spring-security-mvc-boot/src/main/java/com/baeldung/security/CustomUserDetailsService.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/security/CustomUserDetailsService.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/security/CustomUserDetailsService.java diff --git a/spring-data-spring-security/src/main/java/com/baeldung/util/DummyContentUtil.java b/spring-security-mvc-boot/src/main/java/com/baeldung/util/DummyContentUtil.java similarity index 100% rename from spring-data-spring-security/src/main/java/com/baeldung/util/DummyContentUtil.java rename to spring-security-mvc-boot/src/main/java/com/baeldung/util/DummyContentUtil.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java new file mode 100644 index 0000000000..fd270686a2 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java @@ -0,0 +1,12 @@ +package org.baeldung.ip; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +@SpringBootApplication +public class IpApplication extends SpringBootServletInitializer { + public static void main(String[] args) { + SpringApplication.run(IpApplication.class, args); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java new file mode 100644 index 0000000000..078dd81259 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java @@ -0,0 +1,53 @@ +package org.baeldung.ip.config; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.web.authentication.WebAuthenticationDetails; +import org.springframework.stereotype.Component; + +@Component +public class CustomIpAuthenticationProvider implements AuthenticationProvider { + + Set whitelist = new HashSet(); + + public CustomIpAuthenticationProvider() { + super(); + whitelist.add("11.11.11.11"); + whitelist.add("127.0.0.1"); + } + + @Override + public Authentication authenticate(Authentication auth) throws AuthenticationException { + WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails(); + String userIp = details.getRemoteAddress(); + if(! whitelist.contains(userIp)){ + throw new BadCredentialsException("Invalid IP Address"); + } + final String name = auth.getName(); + final String password = auth.getCredentials().toString(); + + if (name.equals("john") && password.equals("123")) { + List authorities =new ArrayList(); + authorities.add(new SimpleGrantedAuthority("ROLE_USER")); + return new UsernamePasswordAuthenticationToken(name, password, authorities); + } + else{ + throw new BadCredentialsException("Invalid username or password"); + } + } + + @Override + public boolean supports(Class authentication) { + return authentication.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java new file mode 100644 index 0000000000..3a8032a734 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java @@ -0,0 +1,36 @@ +package org.baeldung.ip.config; + +import org.springframework.beans.factory.annotation.Autowired; +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; + +@Configuration +@EnableWebSecurity//(debug = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private CustomIpAuthenticationProvider authenticationProvider; + + @Override + protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("john").password("{noop}123").authorities("ROLE_USER"); + // auth.authenticationProvider(authenticationProvider); + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers("/login").permitAll() +// .antMatchers("/foos/**").hasIpAddress("11.11.11.11") + .antMatchers("/foos/**").access("isAuthenticated() and hasIpAddress('11.11.11.11')") + .anyRequest().authenticated() + .and().formLogin().permitAll() + .and().csrf().disable(); + // @formatter:on + } + +} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java new file mode 100644 index 0000000000..1d22ca4c67 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java @@ -0,0 +1,9 @@ +package org.baeldung.ip.config; + + +//@Configuration +//@EnableWebSecurity +//@ImportResource({ "classpath:spring-security-ip.xml" }) +public class SecurityXmlConfig { + +} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java new file mode 100644 index 0000000000..940194c421 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java @@ -0,0 +1,42 @@ +package org.baeldung.ip.web; + +import java.util.List; + +import javax.servlet.Filter; +import javax.servlet.http.HttpServletRequest; + +import org.baeldung.custom.persistence.model.Foo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class MainController { + + @Autowired + @Qualifier("springSecurityFilterChain") + private Filter springSecurityFilterChain; + + @RequestMapping(method = RequestMethod.GET, value = "/filters") + @ResponseBody + public void getFilters() { + FilterChainProxy filterChainProxy = (FilterChainProxy) springSecurityFilterChain; + List list = filterChainProxy.getFilterChains(); + list.stream() + .flatMap(chain -> chain.getFilters().stream()) + .forEach(filter -> System.out.println(filter.getClass())); + } + + @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") + @ResponseBody + public Foo findById(@PathVariable final long id, HttpServletRequest request) { + return new Foo("Sample"); + } + +} diff --git a/spring-security-mvc-boot/src/main/resources/application.properties b/spring-security-mvc-boot/src/main/resources/application.properties index f015086a4f..25eac743d1 100644 --- a/spring-security-mvc-boot/src/main/resources/application.properties +++ b/spring-security-mvc-boot/src/main/resources/application.properties @@ -6,4 +6,7 @@ spring.datasource.password= spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.database=H2 spring.jpa.show-sql=false -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect \ No newline at end of file +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect + + +#logging.level.org.springframework.security.web.FilterChainProxy=DEBUG \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/logback.xml b/spring-security-mvc-boot/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-data-spring-security/src/main/resources/persistence-h2.properties b/spring-security-mvc-boot/src/main/resources/persistence-h2.properties similarity index 100% rename from spring-data-spring-security/src/main/resources/persistence-h2.properties rename to spring-security-mvc-boot/src/main/resources/persistence-h2.properties diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml b/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml new file mode 100644 index 0000000000..31796ad134 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/spring-data-spring-security/src/test/java/com/baeldung/relationships/SpringDataWithSecurityTest.java b/spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityUnitTest.java similarity index 95% rename from spring-data-spring-security/src/test/java/com/baeldung/relationships/SpringDataWithSecurityTest.java rename to spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityUnitTest.java index dbbfe7e85e..8207363a70 100644 --- a/spring-data-spring-security/src/test/java/com/baeldung/relationships/SpringDataWithSecurityTest.java +++ b/spring-security-mvc-boot/src/test/java/com/baeldung/relationships/SpringDataWithSecurityUnitTest.java @@ -36,7 +36,7 @@ import com.baeldung.util.DummyContentUtil; @WebAppConfiguration @ContextConfiguration @DirtiesContext -public class SpringDataWithSecurityTest { +public class SpringDataWithSecurityUnitTest { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); @Autowired private ServletContext servletContext; @@ -50,8 +50,8 @@ public class SpringDataWithSecurityTest { ctx.refresh(); userRepository = ctx.getBean(UserRepository.class); tweetRepository = ctx.getBean(TweetRepository.class); - List appUsers = (List) userRepository.save(DummyContentUtil.generateDummyUsers()); - tweetRepository.save(DummyContentUtil.generateDummyTweets(appUsers)); + List appUsers = (List) userRepository.saveAll(DummyContentUtil.generateDummyUsers()); + tweetRepository.saveAll(DummyContentUtil.generateDummyTweets(appUsers)); } @AfterClass diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java new file mode 100644 index 0000000000..e12e2f87b0 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java @@ -0,0 +1,27 @@ +package org.baeldung.web; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.restassured.RestAssured; +import io.restassured.response.Response; + +import org.junit.Test; + + +public class IpLiveTest { + + @Test + public void givenUser_whenGetHomePage_thenOK() { + final Response response = RestAssured.given().auth().form("john", "123").get("http://localhost:8082/"); + assertEquals(200, response.getStatusCode()); + assertTrue(response.asString().contains("Welcome")); + } + + @Test + public void givenUserWithWrongIP_whenGetFooById_thenForbidden() { + final Response response = RestAssured.given().auth().form("john", "123").get("http://localhost:8082/foos/1"); + assertEquals(403, response.getStatusCode()); + assertTrue(response.asString().contains("Forbidden")); + } + +} \ No newline at end of file diff --git a/spring-security-mvc-custom/pom.xml b/spring-security-mvc-custom/pom.xml index e50304aa1b..a1a1beb4f4 100644 --- a/spring-security-mvc-custom/pom.xml +++ b/spring-security-mvc-custom/pom.xml @@ -1,224 +1,213 @@ - 4.0.0 - com.baeldung - spring-security-mvc-custom - 0.1-SNAPSHOT - spring-security-mvc-custom - war + 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 + spring-security-mvc-custom + 0.1-SNAPSHOT + spring-security-mvc-custom + war - - com.baeldung - parent-spring-5 - 0.0.1-SNAPSHOT - ../parent-spring-5 - + + com.baeldung + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 + - + - + - - org.springframework.security - spring-security-web - ${org.springframework.security.version} - - - org.springframework.security - spring-security-config - ${org.springframework.security.version} - - - org.springframework.security - spring-security-taglibs - ${org.springframework.security.version} - + + org.springframework.security + spring-security-web + ${org.springframework.security.version} + + + org.springframework.security + spring-security-config + ${org.springframework.security.version} + + + org.springframework.security + spring-security-taglibs + ${org.springframework.security.version} + - + - - org.springframework - spring-core - ${spring.version} - - - commons-logging - commons-logging - - - - - org.springframework - spring-context - ${spring.version} - - - org.springframework - spring-jdbc - ${spring.version} - - - org.springframework - spring-beans - ${spring.version} - - - org.springframework - spring-aop - ${spring.version} - - - org.springframework - spring-tx - ${spring.version} - - - org.springframework - spring-expression - ${spring.version} - + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-jdbc + ${spring.version} + + + org.springframework + spring-beans + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework + spring-expression + ${spring.version} + - - org.springframework - spring-web - ${spring.version} - - - org.springframework - spring-webmvc - ${spring.version} - + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-webmvc + ${spring.version} + - + - - javax.servlet - javax.servlet-api - ${javax.servlet.version} - provided - + + javax.servlet + javax.servlet-api + ${javax.servlet.version} + provided + - - javax.servlet - jstl - ${jstl.version} - runtime - + + javax.servlet + jstl + ${jstl.version} + runtime + - + - - - - - + + + + + - - - com.fasterxml.jackson.core - jackson-databind - ${jackson-databind.version} - + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} + - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + - - com.google.guava - guava - ${guava.version} - + + com.google.guava + guava + ${guava.version} + - + - - org.springframework - spring-test - ${spring.version} - test - + + org.springframework + spring-test + ${spring.version} + test + - - org.springframework.security - spring-security-test - ${org.springframework.security.version} - test - - + + org.springframework.security + spring-security-test + ${org.springframework.security.version} + test + + - - spring-security-mvc-custom - - - src/main/resources - true - - + + spring-security-mvc-custom + + + src/main/resources + true + + - + - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - true - - jetty8x - embedded - - - - - - - 8082 - - - - + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + true + + jetty8x + embedded + + + + + + + 8082 + + + + - + - + - - - 5.0.6.RELEASE + + + 5.0.6.RELEASE - - 5.2.5.Final - 5.1.40 + + 3.1.0 + 1.2 - - 5.4.1.Final - 3.1.0 - 1.2 + + 19.0 + 3.5 + 2.9.4 - - 19.0 - 3.5 - 2.9.4 + + 2.6 + 1.6.1 - 4.5.2 - 4.4.5 - - 3.0.7 - - - 2.6 - 2.7 - 1.6.1 - - + \ No newline at end of file diff --git a/spring-security-mvc-custom/src/main/resources/logback.xml b/spring-security-mvc-custom/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-mvc-custom/src/main/resources/logback.xml +++ b/spring-security-mvc-custom/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-mvc-custom/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-custom/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..9e74e83a53 --- /dev/null +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import org.baeldung.spring.MvcConfig; +import org.baeldung.spring.SecSecurityConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { MvcConfig.class, SecSecurityConfig.class }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityConfig.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityConfig.java index 874856095c..23d13a0ff1 100644 --- a/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityConfig.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/ManualSecurityConfig.java @@ -3,7 +3,6 @@ package org.baeldung.security.spring; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.BeanIds; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -24,7 +23,7 @@ public class ManualSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN"); + auth.inMemoryAuthentication().withUser("user1").password("{noop}user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN"); } @Override @@ -32,7 +31,7 @@ public class ManualSecurityConfig extends WebSecurityConfigurerAdapter { web.ignoring().antMatchers("/resources/**"); } - @Bean(name = BeanIds.AUTHENTICATION_MANAGER) + @Bean("authenticationManager") @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); diff --git a/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java index 9600977e37..ca401622c0 100644 --- a/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java @@ -1,6 +1,8 @@ package org.baeldung.security.spring; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -17,7 +19,11 @@ public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter { super(); } - // java config + @Bean("authenticationManager") + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { diff --git a/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java index f7dbd5b42c..1067c70fea 100644 --- a/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java @@ -1,6 +1,8 @@ package org.baeldung.security.spring; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -17,7 +19,11 @@ public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter { super(); } - // java config + @Bean("authenticationManager") + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { diff --git a/spring-security-mvc-digest-auth/pom.xml b/spring-security-mvc-digest-auth/pom.xml index a0a6a9647e..33b3b5ff31 100644 --- a/spring-security-mvc-digest-auth/pom.xml +++ b/spring-security-mvc-digest-auth/pom.xml @@ -1,19 +1,17 @@ + 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 spring-security-mvc-digest-auth 0.1-SNAPSHOT - spring-security-mvc-digest-auth war - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + @@ -91,12 +89,6 @@ ${spring.version} - - org.springframework - spring-web - ${spring.version} - - @@ -202,12 +194,7 @@ 4.2.6.RELEASE - - 5.2.5.Final - 5.1.40 - - 5.3.3.Final 1.2 3.1.0 @@ -218,13 +205,9 @@ 4.4.5 4.5.2 - 2.9.0 - 2.6 - 2.7 1.6.1 - \ No newline at end of file diff --git a/spring-security-mvc-digest-auth/src/main/resources/logback.xml b/spring-security-mvc-digest-auth/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-mvc-digest-auth/src/main/resources/logback.xml +++ b/spring-security-mvc-digest-auth/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-mvc-digest-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-digest-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..a4a85a8fa2 --- /dev/null +++ b/spring-security-mvc-digest-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import org.baeldung.spring.ClientConfig; +import org.baeldung.spring.MvcConfig; +import org.baeldung.spring.SecSecurityConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { ClientConfig.class, MvcConfig.class, SecSecurityConfig.class }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-mvc-ldap/pom.xml b/spring-security-mvc-ldap/pom.xml index 6a9aa5eebe..1c5df368a7 100644 --- a/spring-security-mvc-ldap/pom.xml +++ b/spring-security-mvc-ldap/pom.xml @@ -1,10 +1,9 @@ + 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 spring-security-mvc-ldap 0.1-SNAPSHOT - spring-security-mvc-ldap war diff --git a/spring-security-mvc-ldap/src/main/resources/logback.xml b/spring-security-mvc-ldap/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-mvc-ldap/src/main/resources/logback.xml +++ b/spring-security-mvc-ldap/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-mvc-ldap/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-ldap/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..0b701e9acf --- /dev/null +++ b/spring-security-mvc-ldap/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SampleLDAPApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-mvc-login/README.md b/spring-security-mvc-login/README.md index f7eb314869..c19cbc87a5 100644 --- a/spring-security-mvc-login/README.md +++ b/spring-security-mvc-login/README.md @@ -12,6 +12,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - [Spring HTTP/HTTPS Channel Security](http://www.baeldung.com/spring-channel-security-https) - [Spring Security - Customize the 403 Forbidden/Access Denied Page](http://www.baeldung.com/spring-security-custom-access-denied-page) - [Spring Security – Redirect to the Previous URL After Login](http://www.baeldung.com/spring-security-redirect-login) +- [Spring Security Custom AuthenticationFailureHandler](http://www.baeldung.com/spring-security-custom-authentication-failure-handler) ### Build the Project ``` diff --git a/spring-security-mvc-login/pom.xml b/spring-security-mvc-login/pom.xml index 6f4bd8c8e0..f70cf256dc 100644 --- a/spring-security-mvc-login/pom.xml +++ b/spring-security-mvc-login/pom.xml @@ -1,19 +1,19 @@ + 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 spring-security-mvc-login 0.1-SNAPSHOT - spring-security-mvc-login war - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + @@ -169,27 +169,12 @@ 4.2.6.RELEASE - - 5.2.5.Final - 5.1.40 - - 5.3.3.Final 3.1.0 1.2 - - 19.0 - 3.5 - - 4.4.5 - 4.5.2 - - 2.9.0 - 2.6 - 2.7 1.6.1 diff --git a/spring-security-mvc-login/src/main/java/org/baeldung/security/CustomAuthenticationFailureHandler.java b/spring-security-mvc-login/src/main/java/org/baeldung/security/CustomAuthenticationFailureHandler.java new file mode 100644 index 0000000000..5eddf3883e --- /dev/null +++ b/spring-security-mvc-login/src/main/java/org/baeldung/security/CustomAuthenticationFailureHandler.java @@ -0,0 +1,22 @@ +package org.baeldung.security; + +import org.springframework.http.HttpStatus; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Calendar; + +public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { + httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); + + String jsonPayload = "{\"message\" : \"%s\", \"timestamp\" : \"%s\" }"; + httpServletResponse.getOutputStream().println(String.format(jsonPayload, e.getMessage(), Calendar.getInstance().getTime())); + } +} diff --git a/spring-security-mvc-login/src/main/java/org/baeldung/spring/SecSecurityConfig.java b/spring-security-mvc-login/src/main/java/org/baeldung/spring/SecSecurityConfig.java index d9a43d48d0..accc7c9afd 100644 --- a/spring-security-mvc-login/src/main/java/org/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-mvc-login/src/main/java/org/baeldung/spring/SecSecurityConfig.java @@ -1,6 +1,7 @@ package org.baeldung.spring; import org.baeldung.security.CustomAccessDeniedHandler; +import org.baeldung.security.CustomAuthenticationFailureHandler; import org.baeldung.security.CustomLogoutSuccessHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,6 +11,7 @@ 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.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; @Configuration @@ -26,11 +28,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // @formatter:off auth.inMemoryAuthentication() - .withUser("user1").password("user1Pass").roles("USER") - .and() - .withUser("user2").password("user2Pass").roles("USER") - .and() - .withUser("admin").password("adminPass").roles("ADMIN"); + .withUser("user1").password("user1Pass").roles("USER") + .and() + .withUser("user2").password("user2Pass").roles("USER") + .and() + .withUser("admin").password("adminPass").roles("ADMIN"); // @formatter:on } @@ -38,23 +40,24 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity http) throws Exception { // @formatter:off http - .csrf().disable() - .authorizeRequests() - .antMatchers("/admin/**").hasRole("ADMIN") - .antMatchers("/anonymous*").anonymous() - .antMatchers("/login*").permitAll() - .anyRequest().authenticated() - .and() - .formLogin() - .loginPage("/login.html") - .loginProcessingUrl("/perform_login") - .defaultSuccessUrl("/homepage.html",true) - .failureUrl("/login.html?error=true") - .and() - .logout() - .logoutUrl("/perform_logout") - .deleteCookies("JSESSIONID") - .logoutSuccessHandler(logoutSuccessHandler()); + .csrf().disable() + .authorizeRequests() + .antMatchers("/admin/**").hasRole("ADMIN") + .antMatchers("/anonymous*").anonymous() + .antMatchers("/login*").permitAll() + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/login.html") + .loginProcessingUrl("/perform_login") + .defaultSuccessUrl("/homepage.html", true) + //.failureUrl("/login.html?error=true") + .failureHandler(authenticationFailureHandler()) + .and() + .logout() + .logoutUrl("/perform_logout") + .deleteCookies("JSESSIONID") + .logoutSuccessHandler(logoutSuccessHandler()); //.and() //.exceptionHandling().accessDeniedPage("/accessDenied"); //.exceptionHandling().accessDeniedHandler(accessDeniedHandler()); @@ -71,4 +74,8 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { return new CustomAccessDeniedHandler(); } + @Bean + public AuthenticationFailureHandler authenticationFailureHandler() { + return new CustomAuthenticationFailureHandler(); + } } diff --git a/spring-security-mvc-login/src/main/resources/logback.xml b/spring-security-mvc-login/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-mvc-login/src/main/resources/logback.xml +++ b/spring-security-mvc-login/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-mvc-login/src/main/resources/webSecurityConfig.xml b/spring-security-mvc-login/src/main/resources/webSecurityConfig.xml index f0fa956934..189522889f 100644 --- a/spring-security-mvc-login/src/main/resources/webSecurityConfig.xml +++ b/spring-security-mvc-login/src/main/resources/webSecurityConfig.xml @@ -15,20 +15,22 @@ - + - + + + diff --git a/spring-security-mvc-login/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-login/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..1d7f9ae497 --- /dev/null +++ b/spring-security-mvc-login/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/RedirectionWebSecurityConfig.xml", "/mvc-servlet.xml" }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-mvc-login/src/test/java/org/baeldung/security/FormLoginUnitTest.java b/spring-security-mvc-login/src/test/java/org/baeldung/security/FormLoginUnitTest.java new file mode 100644 index 0000000000..4b3a091e6c --- /dev/null +++ b/spring-security-mvc-login/src/test/java/org/baeldung/security/FormLoginUnitTest.java @@ -0,0 +1,63 @@ +package org.baeldung.security; + +import org.baeldung.spring.SecSecurityConfig; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import javax.servlet.Filter; + +import static org.junit.Assert.assertTrue; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin; +import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {SecSecurityConfig.class}) +@WebAppConfiguration +public class FormLoginUnitTest { + + @Autowired + private WebApplicationContext context; + + @Autowired + private Filter springSecurityFilterChain; + + private MockMvc mvc; + + @Before + public void setup() { + mvc = MockMvcBuilders + .webAppContextSetup(context) + .addFilters(springSecurityFilterChain) + .build(); + } + + @Test + public void givenValidRequestWithValidCredentials_shouldLoginSuccessfully() throws Exception { + mvc + .perform(formLogin("/perform_login").user("user1").password("user1Pass")) + .andExpect(status().isFound()) + .andExpect(authenticated().withUsername("user1")); + } + + @Test + public void givenValidRequestWithInvalidCredentials_shouldFailWith401() throws Exception { + MvcResult result = mvc + .perform(formLogin("/perform_login").user("random").password("random")).andReturn(); + /*.andExpect(status().isUnauthorized()) + .andDo(print()) + .andExpect(unauthenticated()) + .andReturn();*/ + + assertTrue(result.getResponse().getContentAsString().contains("Bad credentials")); + } +} diff --git a/spring-security-mvc-persisted-remember-me/pom.xml b/spring-security-mvc-persisted-remember-me/pom.xml index f8fa4400c9..8b15e658e8 100644 --- a/spring-security-mvc-persisted-remember-me/pom.xml +++ b/spring-security-mvc-persisted-remember-me/pom.xml @@ -1,19 +1,19 @@ + 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 spring-security-mvc-persisted-remember-me 0.1-SNAPSHOT - spring-security-mvc-persisted-remember-me war - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + @@ -133,7 +133,14 @@ guava ${guava.version} - + + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + @@ -192,28 +199,18 @@ 4.2.6.RELEASE - 5.2.5.Final - 5.1.40 1.4.193 9.4.1212 - 5.3.3.Final 3.1.0 1.2 19.0 - 3.4 - - 4.5.2 - 4.4.5 - - 2.9.0 2.6 - 2.7 1.6.1 diff --git a/spring-security-mvc-persisted-remember-me/src/main/resources/logback.xml b/spring-security-mvc-persisted-remember-me/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-mvc-persisted-remember-me/src/main/resources/logback.xml +++ b/spring-security-mvc-persisted-remember-me/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-mvc-persisted-remember-me/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-persisted-remember-me/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..f1df880862 --- /dev/null +++ b/spring-security-mvc-persisted-remember-me/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import org.baeldung.spring.MvcConfig; +import org.baeldung.spring.PersistenceConfig; +import org.baeldung.spring.SecurityConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { MvcConfig.class, PersistenceConfig.class, SecurityConfig.class }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-mvc-session/pom.xml b/spring-security-mvc-session/pom.xml index da0bede349..85c8475657 100644 --- a/spring-security-mvc-session/pom.xml +++ b/spring-security-mvc-session/pom.xml @@ -1,10 +1,10 @@ 4.0.0 + com.baeldung spring-security-mvc-session 0.1-SNAPSHOT - spring-security-mvc-session war @@ -113,6 +113,14 @@ metrics-core ${codahale.metrics.version} + + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + @@ -162,30 +170,14 @@ 4.2.6.RELEASE - - 5.2.5.Final - 5.1.40 - - 5.3.3.Final 3.0.2 1.2 3.1.0 - - 19.0 - 3.5 - - 4.5.2 - 4.4.5 - - 2.9.0 - 2.6 - 2.7 1.6.1 - \ No newline at end of file diff --git a/spring-security-mvc-session/src/main/resources/logback.xml b/spring-security-mvc-session/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-mvc-session/src/main/resources/logback.xml +++ b/spring-security-mvc-session/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..9e74e83a53 --- /dev/null +++ b/spring-security-mvc-session/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import org.baeldung.spring.MvcConfig; +import org.baeldung.spring.SecSecurityConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { MvcConfig.class, SecSecurityConfig.class }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-mvc-socket/README.md b/spring-security-mvc-socket/README.md index 5ae9d4f4cd..6c2ad7b985 100644 --- a/spring-security-mvc-socket/README.md +++ b/spring-security-mvc-socket/README.md @@ -1,2 +1,10 @@ +To build the project, run the command: mvn clean install. This will build a war file in the target folder that you can deploye on a server like Tomcat. + +Alternatively, run the project from an IDE. + +To login, use credentials from the data.sql file in src/main/resource, eg: user/password. + + ### Relevant Articles: - [Intro to Security and WebSockets](http://www.baeldung.com/spring-security-websockets) +- [Spring WebSockets: Build an User Chat](https://www.baeldung.com/spring-websockets-send-message-to-user) diff --git a/spring-security-mvc-socket/pom.xml b/spring-security-mvc-socket/pom.xml index 5cd2c080d2..d1b8365077 100644 --- a/spring-security-mvc-socket/pom.xml +++ b/spring-security-mvc-socket/pom.xml @@ -1,7 +1,8 @@ - + 4.0.0 + com.baeldung.springsecuredsockets spring-security-mvc-socket 1.0.0 @@ -9,11 +10,11 @@ war - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + @@ -55,12 +56,12 @@ org.springframework.security spring-security-web - ${springsecurity.version} + ${spring-security.version} org.springframework.security spring-security-config - ${springsecurity.version} + ${spring-security.version} @@ -94,14 +95,14 @@ org.springframework.security spring-security-messaging - ${springsecurity.version} + ${spring-security.version} org.slf4j jcl-over-slf4j - ${slf4j.version} + ${org.slf4j.version} ch.qos.logback @@ -147,9 +148,18 @@ jackson-annotations ${jackson.version} + + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + + - + org.apache.tomcat.maven @@ -169,18 +179,16 @@ - spring-security-mvc-socket - 4.2.6.RELEASE - 2.8.7 - 1.7.25 5.2.10.Final + 4.2.3.RELEASE 1.11.3.RELEASE 1.4.196 1.2.3 + 2.8.7 \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/Constants.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/Constants.java new file mode 100644 index 0000000000..77bcf7f343 --- /dev/null +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/Constants.java @@ -0,0 +1,8 @@ +package com.baeldung.springsecuredsockets; + +public class Constants { + public static final String SECURED_CHAT_HISTORY = "/secured/history"; + public static final String SECURED_CHAT = "/secured/chat"; + public static final String SECURED_CHAT_ROOM = "/secured/room"; + public static final String SECURED_CHAT_SPECIFIC_USER = "/secured/user/queue/specific-user"; +} diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/AppConfig.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/AppConfig.java index da687a328a..afb1970b25 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/AppConfig.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/AppConfig.java @@ -51,6 +51,6 @@ public class AppConfig extends WebMvcConfigurerAdapter { // View H2 @Bean(initMethod="start", destroyMethod="stop") public Server h2Console () throws SQLException { - return Server.createWebServer("-web","-webAllowOthers","-webDaemon","-webPort", "8082"); + return Server.createWebServer("-web","-webAllowOthers","-webDaemon","-webPort", "8084"); } } \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SecurityConfig.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SecurityConfig.java index d7b57d1829..be00662e3e 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SecurityConfig.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SecurityConfig.java @@ -88,7 +88,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .authorizeRequests() .antMatchers("/", "/index", "/authenticate") .permitAll() - .antMatchers("/secured/**/**", "/secured/socket", "/secured/success") + .antMatchers("/secured/**/**", "/secured/**/**/**", "/secured/socket", "/secured/success") .authenticated() .anyRequest().authenticated() .and() diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SocketBrokerConfig.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SocketBrokerConfig.java index 5affbd4c0e..9b19de7b5a 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SocketBrokerConfig.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SocketBrokerConfig.java @@ -1,5 +1,10 @@ package com.baeldung.springsecuredsockets.config; +import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT; +import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_HISTORY; +import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_ROOM; +import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_SPECIFIC_USER; + import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; @@ -7,7 +12,6 @@ import org.springframework.web.socket.config.annotation.AbstractWebSocketMessage import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; - @Configuration @EnableWebSocketMessageBroker @ComponentScan("com.baeldung.springsecuredsockets.controllers") @@ -15,13 +19,15 @@ public class SocketBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer @Override public void configureMessageBroker(MessageBrokerRegistry config) { - config.enableSimpleBroker("/secured/history"); + config.enableSimpleBroker(SECURED_CHAT_HISTORY, SECURED_CHAT_SPECIFIC_USER); config.setApplicationDestinationPrefixes("/spring-security-mvc-socket"); + config.setUserDestinationPrefix("/secured/user"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/secured/chat").withSockJS(); + registry.addEndpoint(SECURED_CHAT_ROOM).withSockJS(); + registry.addEndpoint(SECURED_CHAT).withSockJS(); } } diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SocketSecurityConfig.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SocketSecurityConfig.java index a37dfb7672..c833e70d47 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SocketSecurityConfig.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SocketSecurityConfig.java @@ -15,7 +15,7 @@ public class SocketSecurityConfig extends AbstractSecurityWebSocketMessageBroker @Override protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { messages - .simpDestMatchers("/secured/**").authenticated() + .simpDestMatchers("/secured/**", "/secured/**/**").authenticated() .anyMessage().authenticated(); } } \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/WebAppInitializer.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/WebAppInitializer.java index 20311426c7..84c045a75a 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/WebAppInitializer.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/WebAppInitializer.java @@ -1,6 +1,5 @@ package com.baeldung.springsecuredsockets.config; -import org.hibernate.cfg.Configuration; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/controllers/SocketController.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/controllers/SocketController.java index 68c5e306d8..6a74009c16 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/controllers/SocketController.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/controllers/SocketController.java @@ -1,11 +1,19 @@ package com.baeldung.springsecuredsockets.controllers; +import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT; +import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_HISTORY; +import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_ROOM; +import static com.baeldung.springsecuredsockets.Constants.SECURED_CHAT_SPECIFIC_USER; + import com.baeldung.springsecuredsockets.transfer.socket.Message; import com.baeldung.springsecuredsockets.transfer.socket.OutputMessage; +import java.security.Principal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.handler.annotation.Header; import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Controller; @@ -19,10 +27,19 @@ public class SocketController { private SimpMessagingTemplate simpMessagingTemplate; private static final Logger log = LoggerFactory.getLogger(SocketController.class); - @MessageMapping("/secured/chat") - @SendTo("/secured/history") - public OutputMessage send(Message msg) throws Exception { + @MessageMapping(SECURED_CHAT) + @SendTo(SECURED_CHAT_HISTORY) + public OutputMessage sendAll(Message msg) throws Exception { OutputMessage out = new OutputMessage(msg.getFrom(), msg.getText(), new SimpleDateFormat("HH:mm").format(new Date())); return out; } + + /** + * Example of sending message to specific user using 'convertAndSendToUser()' and '/queue' + */ + @MessageMapping(SECURED_CHAT_ROOM) + public void sendSpecific(@Payload Message msg, Principal user, @Header("simpSessionId") String sessionId) throws Exception { + OutputMessage out = new OutputMessage(msg.getFrom(), msg.getText(), new SimpleDateFormat("HH:mm").format(new Date())); + simpMessagingTemplate.convertAndSendToUser(msg.getTo(), SECURED_CHAT_SPECIFIC_USER, out); + } } diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/security/CustomDaoAuthenticationProvider.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/security/CustomDaoAuthenticationProvider.java index 576495bedf..5b246ac380 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/security/CustomDaoAuthenticationProvider.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/security/CustomDaoAuthenticationProvider.java @@ -8,7 +8,6 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; public class CustomDaoAuthenticationProvider extends DaoAuthenticationProvider { diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/transfer/socket/Message.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/transfer/socket/Message.java index 024b386164..fd5d632fce 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/transfer/socket/Message.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/transfer/socket/Message.java @@ -3,6 +3,7 @@ package com.baeldung.springsecuredsockets.transfer.socket; public class Message { private String from; + private String to; private String text; public String getFrom() { @@ -11,6 +12,13 @@ public class Message { 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; } diff --git a/spring-security-mvc-socket/src/main/resources/logback.xml b/spring-security-mvc-socket/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-mvc-socket/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/denied.jsp b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/denied.jsp index d61148b04f..e4c40da0a8 100644 --- a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/denied.jsp +++ b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/denied.jsp @@ -4,15 +4,20 @@ - - Spring Secured Sockets - " rel="stylesheet"> - - - -

    ACCESS DENIED!

    -
    -
    - Click to login. - + + + Spring Secured Sockets + " rel="stylesheet"> + " rel="stylesheet"> + + + + +
    +
    +

    ACCESS DENIED!

    + Click to login. +
    +
    + \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/index.jsp index d83338680e..d1435e8c2b 100644 --- a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/index.jsp +++ b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/index.jsp @@ -4,27 +4,32 @@ - - Spring Secured Sockets - " rel="stylesheet"> - - - - - - - - - - - - -

    Welcome!

    -
    - {{greeting}} -
    -
    - Click to login. - + + Spring Secured Sockets + " rel="stylesheet"> + " rel="stylesheet"> + + + + + + + + + + + + + + +
    +
    +

    Welcome!

    + {{greeting}} + Click to login. +
    +
    + + \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/login.jsp b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/login.jsp index d50059c674..76e3334bbe 100644 --- a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/login.jsp +++ b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/login.jsp @@ -4,42 +4,50 @@ - - Spring Secured Sockets - " rel="stylesheet"> - - - - - - - - - - - - - - -

    JSP Login Form


    -
    - - - - - - - - - - - - -
    User:
    Password:
    -
    + + Spring Secured Sockets + " rel="stylesheet"> + " rel="stylesheet"> + + + + + + + + + + + + + + + +
    +
    + +

    JSP Login Form

    +
    + + + + + + + + + + + + +
    User:
    Password:
    +
    + +
    +
    + + + - - - \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/socket.jsp b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/socket.jsp index b5807d74a6..ccd48672a1 100644 --- a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/socket.jsp +++ b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/socket.jsp @@ -4,48 +4,56 @@ - - Spring Secured Sockets - " rel="stylesheet"> - - - - - - - - - - - - - - -

    Socket Chat

    - -
    -
    - -
    -
    -
    - - - -
    -
    -
    - - -

    -
    -
    + + Spring Secured Sockets + " rel="stylesheet"> + " rel="stylesheet"> -Click to go back! -Click to start over (you will still be authenticated)! + + + + + + + + + + + + + + + + +
    +
    +

    Socket Chat

    +
    +

    (Chat With Everyone)

    + + + +
    +
    +

    (Chat With A Specific User)

    + + + +
    +
    +

    (Send and See Messages)

    + + +
    + +
    + Click to go back! + Click to start over (you will still be authenticated)! +
    +
    + + + - - - \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/success.jsp b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/success.jsp index 27e8f7aa44..4cff3f7a25 100644 --- a/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/success.jsp +++ b/spring-security-mvc-socket/src/main/webapp/WEB-INF/jsp/success.jsp @@ -4,28 +4,33 @@ - - Spring Secured Sockets - " rel="stylesheet"> - - - - - - - - - - - - -

    Congrats! You've logged in.

    + + Spring Secured Sockets + " rel="stylesheet"> + " rel="stylesheet"> - Click to chat! - Click to start over (you will still be authenticated)! + + + - - - + + + + + + + + + +
    + +
    + + + \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/indexController.js b/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/indexController.js index 04c02e339b..5de3dcc78b 100644 --- a/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/indexController.js +++ b/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/indexController.js @@ -1,12 +1,13 @@ 'use strict'; angularApp - .controller('indexController', function ($scope) { - $scope.greeting = ''; +.controller('indexController', function ($scope) { - $scope.initialize = function () { - $scope.greeting = "Howdy!" - }; + $scope.greeting = ''; - $scope.initialize(); - }); \ No newline at end of file + $scope.initialize = function () { + $scope.greeting = "Howdy!" + }; + + $scope.initialize(); +}); \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/loginController.js b/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/loginController.js deleted file mode 100644 index 07187d5327..0000000000 --- a/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/loginController.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; - -angularApp - .controller('loginController', function ($scope) { - - }); diff --git a/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/socketController.js b/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/socketController.js index 395bf85c4a..ff000c251e 100644 --- a/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/socketController.js +++ b/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/socketController.js @@ -1,37 +1,52 @@ 'use strict'; angularApp - .controller('socketController', function ($scope, SocketService) { +.controller('socketController', function ($scope, SocketService) { - $scope.stompClient = null; - $scope.sendEndpoint = '/secured/chat'; - $scope.subscribeEndpoint = '/secured/history'; - $scope.elems = { - connect: 'connect', - from: 'from', - text: 'text', - disconnect: 'disconnect', - conversationDiv: 'conversationDiv', - response: 'response' - }; + /** + * URL mapping endpoints. + */ - $scope.connect = function (context) { - $scope.sendEndpoint = '/secured/chat'; - $scope.sendEndpoint = context + $scope.sendEndpoint ; - $scope.stompClient = SocketService.connect($scope.sendEndpoint, $scope.elems); - }; + var SECURED_CHAT = '/secured/chat'; + var SECURED_CHAT_HISTORY = '/secured/history'; + var SECURED_CHAT_ROOM = '/secured/room'; + var SECURED_CHAT_SPECIFIC_USER = '/secured/user/queue/specific-user'; - $scope.subscribe = function () { - $scope.stompClient.subscribe($scope.subscribeEndpoint, function (msgOut) { - SocketService.messageOut(JSON.parse(msgOut.body), $scope.elems); - }); - }; + var opts = { + from: 'from', + to: 'to', + text: 'text', + disconnect: 'disconnect', + conversationDiv: 'conversationDiv', + response: 'response' + }; - $scope.disconnect = function () { - SocketService.disconnect($scope.elems, $scope.stompClient); - }; + $scope.sendEndpoint = ''; + $scope.stompClient = null; - $scope.sendMessage = function () { - SocketService.sendMessage( $scope.elems, $scope.stompClient, $scope.sendEndpoint); - }; - }); \ No newline at end of file + /** + * Broadcast to All Users. + */ + + $scope.connectAll = function (context) { + $scope.sendEndpoint = context + SECURED_CHAT; + $scope.stompClient = SocketService.connect($scope.sendEndpoint , opts, true); + }; + + $scope.subscribeAll = function () { SocketService.subscribeToAll($scope.stompClient, SECURED_CHAT_HISTORY, opts); }; + + /** + * Broadcast to Specific User. + */ + + $scope.connectSpecific = function (context) { + $scope.sendEndpoint = context + SECURED_CHAT_ROOM; + $scope.stompClient = SocketService.connect(context + SECURED_CHAT_ROOM, opts, false); + }; + + $scope.subscribeSpecific = function () { SocketService.subscribeToSpecific($scope.stompClient, SECURED_CHAT_SPECIFIC_USER, opts); }; + + $scope.disconnect = function () { SocketService.disconnect(opts, $scope.stompClient); }; + + $scope.sendMessage = function () { SocketService.sendMessage(opts, $scope.stompClient, $scope.sendEndpoint); }; +}); \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/successController.js b/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/successController.js index ccb972202d..6926239202 100644 --- a/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/successController.js +++ b/spring-security-mvc-socket/src/main/webapp/resources/scripts/controllers/successController.js @@ -1,13 +1,12 @@ 'use strict'; angularApp - .controller('successController', function ($scope) { +.controller('successController', function ($scope) { + $scope.successMsg = ''; - $scope.successMsg = ''; + $scope.initialize = function () { + $scope.successMsg = "You've logged in!"; + }; - $scope.initialize = function () { - $scope.successMsg = "You've logged in!"; - }; - - $scope.initialize(); - }); + $scope.initialize(); +}); diff --git a/spring-security-mvc-socket/src/main/webapp/resources/scripts/routes/router.js b/spring-security-mvc-socket/src/main/webapp/resources/scripts/routes/router.js index 70644f996d..004c7b331a 100644 --- a/spring-security-mvc-socket/src/main/webapp/resources/scripts/routes/router.js +++ b/spring-security-mvc-socket/src/main/webapp/resources/scripts/routes/router.js @@ -1,19 +1,16 @@ 'use strict'; angularApp - .config(function ($routeProvider) { - $routeProvider - .when('/index', { - controller: 'indexController' - }) - .when('/login', { - controller: 'loginController' - }) - .when('/sockets', { - controller: 'socketController' - }) - .when('/success', { - controller: 'successController' - }) - .otherwise('/index'); - }); \ No newline at end of file +.config(function ($routeProvider) { + $routeProvider + .when('/index', { + controller: 'indexController' + }) + .when('/sockets', { + controller: 'socketController' + }) + .when('/success', { + controller: 'successController' + }) + .otherwise('/index'); +}); \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/scripts/services/SocketService.js b/spring-security-mvc-socket/src/main/webapp/resources/scripts/services/SocketService.js index 56930808a3..ba3f397f89 100644 --- a/spring-security-mvc-socket/src/main/webapp/resources/scripts/services/SocketService.js +++ b/spring-security-mvc-socket/src/main/webapp/resources/scripts/services/SocketService.js @@ -1,46 +1,99 @@ 'use strict'; +var idHelper = function (context) { + return document.getElementById(context); +}; + function SocketService() { - var that = this, - idHelper = function(context) { - return document.getElementById(context); - }; - that.setConnected = function (elems, connected) { - idHelper(elems.connect).disabled = connected; - idHelper(elems.disconnect).disabled = !connected; - idHelper(elems.conversationDiv).style.visibility = connected ? 'visible' : 'hidden'; - idHelper(elems.response).innerHTML = ''; + var that = this; + + that.sessionId = ''; + + /** + * Generic methods. + */ + + that.setConnected = function (opts, connected) { + idHelper('connectAll').disabled = connected; + idHelper('connectSpecific').disabled = connected; + idHelper(opts.disconnect).disabled = !connected; + idHelper(opts.response).innerHTML = ''; + idHelper('subscribeAll').disabled = !connected; + idHelper('subscribeSpecific').disabled = !connected; + }; + + that.connect = function (endpoint, opts, isBroadcastAll) { + var socket = new SockJS(endpoint), stompClient = Stomp.over(socket); + stompClient.connect({}, function (frame) { + that.setConnected(opts, true); + + if (!isBroadcastAll) { + var url = stompClient.ws._transport.url; + console.log(stompClient.ws._transport.url); + url = url.replace("ws://localhost:8080/spring-security-mvc-socket/secured/room/", ""); + url = url.replace("/websocket", ""); + url = url.replace(/^[0-9]+\//, ""); + console.log("Your current session is: " + url); + that.sessionId = url; + } + + }); + return stompClient; + }; + + that.disconnect = function (opts, stompClient) { + if (stompClient !== null && stompClient !== undefined) { stompClient.disconnect(); } + that.setConnected(opts, false); + }; + + that.sendMessage = function (opts, stompClient, endpoint) { + var to = idHelper(opts.to).value; + var from = idHelper(opts.from).value; + + var msg = { + 'from': (from === undefined || from === null ) ? to : from, + 'to': (to === undefined || to === null ) ? "ALL" : to, + 'text': idHelper(opts.text).value }; - that.connect = function (endpoint, elems) { - var socket = new SockJS(endpoint), stompClient = Stomp.over(socket); - stompClient.connect({}, function (frame) { - that.setConnected(elems, true); - }); - return stompClient; - }; + console.log(JSON.stringify(msg)); + stompClient.send(endpoint, {}, JSON.stringify(msg)); + }; - that.disconnect = function (elems, stompClient) { - if (stompClient !== null && stompClient !== undefined) stompClient.disconnect(); - that.setConnected(elems, false); - }; + that.messageOut = function (msg, opts) { + var r = idHelper(opts.response), p = document.createElement('p'); + p.style.wordWrap = 'break-word'; + p.appendChild(document.createTextNode(msg.from + ': ' + msg.text + ' (' + msg.time + ')')); + r.appendChild(p); + }; + + /** + * Broadcast to All Users. + */ + + that.subscribeToAll = function(client, url, opts) { + idHelper('subscribeAll').disabled = true; + idHelper('subscribeSpecific').disabled = true; + client.subscribe(url, function (msgOut) { + that.messageOut(JSON.parse(msgOut.body), opts); + }); + }; + + /** + * Broadcast to Specific User. + */ + + that.subscribeToSpecific = function(client, url, opts) { + idHelper('subscribeAll').disabled = true; + idHelper('subscribeSpecific').disabled = true; + client.subscribe(url + "-user" + that.sessionId, function (msgOut) { + that.messageOut(JSON.parse(msgOut.body), opts); + }); + }; - that.sendMessage = function (elems, stompClient, endpoint) { - stompClient.send(endpoint, {}, - JSON.stringify({ - 'from': idHelper(elems.from).value, - 'text': idHelper(elems.text).value - })); - }; - that.messageOut = function (msg, elems) { - var r = idHelper(elems.response), p = document.createElement('p'); - p.style.wordWrap = 'break-word'; - p.appendChild(document.createTextNode(msg.from + ': ' + msg.text + ' (' + msg.time + ')')); - r.appendChild(p); - }; } angularApp - .service('SocketService', SocketService); \ No newline at end of file +.service('SocketService', SocketService); \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/styles/app.css b/spring-security-mvc-socket/src/main/webapp/resources/styles/app.css new file mode 100644 index 0000000000..ee2cb4d717 --- /dev/null +++ b/spring-security-mvc-socket/src/main/webapp/resources/styles/app.css @@ -0,0 +1,70 @@ +@import url('https://fonts.googleapis.com/css?family=Poiret+One'); + +html, body, main { + padding: 0; + margin: 0; + position: absolute; + height: 100%; + width: 100%; + color: white; + font-family: 'Poiret One', sans-serif; + opacity:.95; +} + +main { + background-size: cover; +} + +main > div.wrapper { + position: relative; + left: 15%; + top: 15%; + width: 40%; +} + +h1 { + text-transform: uppercase; + font-size: 48px; + letter-spacing: 2px; +} + +span, a { + font-size: 24px; + letter-spacing: 1px; +} + +a { + text-decoration: none; + color: white; +} + +a:hover { + color: lightgray; +} + +input { + width: 225px; + background: none !important; + border-radius: 25px; + background-color: #fff; + color: white; + outline: none; + margin-left: 2px; + padding-left: 25px; + padding-bottom: 9px; + padding-top: 9px; +} + +button { + width: 100px; + align-content: center; + text-align: center; + background: transparent; + border-radius: 25px; + padding: 6px; + color: white; +} + +button:hover { + opacity: .6; +} \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/styles/denied.css b/spring-security-mvc-socket/src/main/webapp/resources/styles/denied.css new file mode 100644 index 0000000000..3956715e4a --- /dev/null +++ b/spring-security-mvc-socket/src/main/webapp/resources/styles/denied.css @@ -0,0 +1,3 @@ +main { + background-color: black; +} diff --git a/spring-security-mvc-socket/src/main/webapp/resources/styles/index.css b/spring-security-mvc-socket/src/main/webapp/resources/styles/index.css new file mode 100644 index 0000000000..b6da4814b7 --- /dev/null +++ b/spring-security-mvc-socket/src/main/webapp/resources/styles/index.css @@ -0,0 +1,7 @@ +main { + background-color: black; +} + +span, a { + top: 175px; +} \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/styles/login.css b/spring-security-mvc-socket/src/main/webapp/resources/styles/login.css new file mode 100644 index 0000000000..197f3e41bb --- /dev/null +++ b/spring-security-mvc-socket/src/main/webapp/resources/styles/login.css @@ -0,0 +1,17 @@ +main { + background-color: black; +} + +input[type="submit"] { + width: 100px; + align-content: center; + text-align: center; + background: transparent; + border-radius: 25px; + padding: 6px; + color: white; +} + +input[type="submit"]:hover { + opacity:.6; +} \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/styles/socket.css b/spring-security-mvc-socket/src/main/webapp/resources/styles/socket.css new file mode 100644 index 0000000000..aa483fd684 --- /dev/null +++ b/spring-security-mvc-socket/src/main/webapp/resources/styles/socket.css @@ -0,0 +1,19 @@ +main { + background-color: black; +} + +div#all, div#specific, div#conversationDiv { + border: 1px solid white; + border-radius: 25px; + padding: 15px; + margin: 15px +} + +button[disabled=true] { + color: lightgray; + border: 1px solid lightgray; +} + +button[disabled=true]:hover { + opacity: 1; +} \ No newline at end of file diff --git a/spring-security-mvc-socket/src/main/webapp/resources/styles/success.css b/spring-security-mvc-socket/src/main/webapp/resources/styles/success.css new file mode 100644 index 0000000000..3956715e4a --- /dev/null +++ b/spring-security-mvc-socket/src/main/webapp/resources/styles/success.css @@ -0,0 +1,3 @@ +main { + background-color: black; +} diff --git a/spring-security-mvc-socket/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-socket/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..00202a98cb --- /dev/null +++ b/spring-security-mvc-socket/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,24 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.springsecuredsockets.config.AppConfig; +import com.baeldung.springsecuredsockets.config.DataStoreConfig; +import com.baeldung.springsecuredsockets.config.SecurityConfig; +import com.baeldung.springsecuredsockets.config.SocketBrokerConfig; +import com.baeldung.springsecuredsockets.config.SocketSecurityConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { AppConfig.class, DataStoreConfig.class, SecurityConfig.class, + SocketBrokerConfig.class, SocketSecurityConfig.class }) +@WebAppConfiguration +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-openid/pom.xml b/spring-security-openid/pom.xml index 89e0977c05..4343996e02 100644 --- a/spring-security-openid/pom.xml +++ b/spring-security-openid/pom.xml @@ -1,21 +1,18 @@ + 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 spring-security-openid - 0.0.1-SNAPSHOT war - spring-security-openid Spring OpenID sample project - org.springframework.boot - spring-boot-starter-parent - 2.0.0.M7 - + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 @@ -52,27 +49,6 @@ - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - 2.2.1.RELEASE 1.0.9.RELEASE diff --git a/spring-security-openid/src/main/resources/logback.xml b/spring-security-openid/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-openid/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-openid/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-openid/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..79a725dcae --- /dev/null +++ b/spring-security-openid/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.SpringOpenidApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringOpenidApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-react/.gitignore b/spring-security-react/.gitignore new file mode 100644 index 0000000000..7bb0610394 --- /dev/null +++ b/spring-security-react/.gitignore @@ -0,0 +1,121 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea + +# CMake +cmake-build-debug/ +cmake-build-release/ + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Eclipse template + +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + +# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) +!/.mvn/wrapper/maven-wrapper.jar +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* diff --git a/spring-security-react/README.md b/spring-security-react/README.md new file mode 100644 index 0000000000..1a845f0daa --- /dev/null +++ b/spring-security-react/README.md @@ -0,0 +1,17 @@ +========= + +## Spring Security React Example Project + +### The Course + +The "Learn Spring Security" Classes: http://github.learnspringsecurity.com + +### Relevant Articles: + +* [Spring Security Login Page with React](http://www.baeldung.com/spring-security-login-react) + +### Build the Project + +``` +mvn clean install +``` diff --git a/spring-security-react/pom.xml b/spring-security-react/pom.xml new file mode 100644 index 0000000000..32817945be --- /dev/null +++ b/spring-security-react/pom.xml @@ -0,0 +1,191 @@ + + 4.0.0 + spring-security-react + 0.1-SNAPSHOT + + spring-security-react + war + + + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + + + + + + + + org.springframework.security + spring-security-web + ${org.springframework.security.version} + + + org.springframework.security + spring-security-config + ${org.springframework.security.version} + + + org.springframework.security + spring-security-taglibs + ${org.springframework.security.version} + + + + + + org.springframework + spring-core + ${org.springframework.version} + + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework + spring-beans + ${org.springframework.version} + + + org.springframework + spring-aop + ${org.springframework.version} + + + + org.springframework + spring-web + ${org.springframework.version} + + + org.springframework + spring-webmvc + ${org.springframework.version} + + + + + + javax.servlet + javax.servlet-api + ${javax.servlet.version} + provided + + + javax.servlet + jstl + ${jstl.version} + runtime + + + + + org.springframework.boot + spring-boot-starter-test + 1.5.10.RELEASE + test + + + + + + spring-security-react + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + + WEB-INF/view/react/node/**, + WEB-INF/view/react/node_modules/**, + WEB-INF/view/react/public/**, + WEB-INF/view/react/src/**, + WEB-INF/view/react/* + + + + + + com.github.eirslett + frontend-maven-plugin + ${frontend-maven-plugin.version} + + ${node.version} + ${npm.version} + src/main/webapp/WEB-INF/view/react + + + + install node and npm + + install-node-and-npm + + + + npm install + + npm + + + + npm run build + + npm + + + run build + + + + + + + org.eclipse.jetty + jetty-maven-plugin + 9.4.11.v20180605 + + + + + + + + + 4.3.6.RELEASE + 4.2.1.RELEASE + + + 3.1.0 + 1.2 + + + 19.0 + 3.5 + + + 2.6 + 2.7 + 1.6 + 9.4.11.v20180605 + + + v8.11.3 + 6.1.0 + + + + \ No newline at end of file diff --git a/spring-security-react/src/main/java/org/baeldung/spring/MvcConfig.java b/spring-security-react/src/main/java/org/baeldung/spring/MvcConfig.java new file mode 100644 index 0000000000..f970b84585 --- /dev/null +++ b/spring-security-react/src/main/java/org/baeldung/spring/MvcConfig.java @@ -0,0 +1,55 @@ +package org.baeldung.spring; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.view.JstlView; + +@EnableWebMvc +@Configuration +public class MvcConfig extends WebMvcConfigurerAdapter { + + public MvcConfig() { + super(); + } + + // API + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + super.addViewControllers(registry); + + registry.addViewController("/anonymous.html"); + + registry.addViewController("/login.html"); + registry.addViewController("/homepage.html"); + registry.addViewController("/admin/adminpage.html"); + registry.addViewController("/accessDenied"); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/view/react/build/static/"); + + registry.addResourceHandler("/*.js").addResourceLocations("/WEB-INF/view/react/build/"); + registry.addResourceHandler("/*.json").addResourceLocations("/WEB-INF/view/react/build/"); + registry.addResourceHandler("/*.ico").addResourceLocations("/WEB-INF/view/react/build/"); + registry.addResourceHandler("/index.html").addResourceLocations("/WEB-INF/view/react/build/index.html"); + } + + @Bean + public ViewResolver viewResolver() { + final InternalResourceViewResolver bean = new InternalResourceViewResolver(); + + bean.setViewClass(JstlView.class); + bean.setPrefix("/WEB-INF/view/"); + bean.setSuffix(".jsp"); + + return bean; + } +} \ No newline at end of file diff --git a/spring-security-react/src/main/java/org/baeldung/spring/SecSecurityConfig.java b/spring-security-react/src/main/java/org/baeldung/spring/SecSecurityConfig.java new file mode 100644 index 0000000000..c64b433544 --- /dev/null +++ b/spring-security-react/src/main/java/org/baeldung/spring/SecSecurityConfig.java @@ -0,0 +1,56 @@ +package org.baeldung.spring; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpMethod; +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; + +@Configuration +@EnableWebSecurity +@Profile("!https") +public class SecSecurityConfig extends WebSecurityConfigurerAdapter { + + public SecSecurityConfig() { + super(); + } + + @Override + protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + // @formatter:off + auth.inMemoryAuthentication() + .withUser("user1").password("user1Pass").roles("USER") + .and() + .withUser("user2").password("user2Pass").roles("USER") + .and() + .withUser("admin").password("admin0Pass").roles("ADMIN"); + // @formatter:on + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + // @formatter:off + http + .csrf().disable() + .authorizeRequests() + .antMatchers("/admin/**").hasRole("ADMIN") + .antMatchers("/anonymous*").anonymous() + .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico").permitAll() + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/index.html") + .loginProcessingUrl("/perform_login") + .defaultSuccessUrl("/homepage.html",true) + .failureUrl("/index.html?error=true") + .and() + .logout() + .logoutUrl("/perform_logout") + .deleteCookies("JSESSIONID"); + // @formatter:on + } + + +} diff --git a/spring-security-react/src/main/resources/logback.xml b/spring-security-react/src/main/resources/logback.xml new file mode 100644 index 0000000000..25f3f36d1a --- /dev/null +++ b/spring-security-react/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-security-react/src/main/webapp/WEB-INF/mvc-servlet.xml new file mode 100644 index 0000000000..4ba9642448 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/mvc-servlet.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/upload.jsp b/spring-security-react/src/main/webapp/WEB-INF/view/accessDenied.jsp similarity index 55% rename from out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/upload.jsp rename to spring-security-react/src/main/webapp/WEB-INF/view/accessDenied.jsp index 3601322ef0..45820cf43d 100644 --- a/out/production/main180/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/upload.jsp +++ b/spring-security-react/src/main/webapp/WEB-INF/view/accessDenied.jsp @@ -1,16 +1,15 @@ <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -Insert title here +Access Denied -
    - -
    - -
    +

    Sorry, you do not have permission to view this page.

    + +Click ">here to go back to the Homepage. \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/admin/adminpage.jsp b/spring-security-react/src/main/webapp/WEB-INF/view/admin/adminpage.jsp new file mode 100644 index 0000000000..813ef02d1d --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/admin/adminpage.jsp @@ -0,0 +1,15 @@ +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> + + + + +

    This is the body of the sample admin page

    + + This page is only visible to an admin +
    + + ">Logout + + + \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/anonymous.jsp b/spring-security-react/src/main/webapp/WEB-INF/view/anonymous.jsp new file mode 100644 index 0000000000..d4e9c0289b --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/anonymous.jsp @@ -0,0 +1,10 @@ +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + + + + +

    Anonymous page

    + + ">To Login + + \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-security-react/src/main/webapp/WEB-INF/view/homepage.jsp new file mode 100644 index 0000000000..c9d88cbc9b --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/homepage.jsp @@ -0,0 +1,26 @@ +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> + + + + +

    This is the body of the sample view

    + + + This text is only visible to a user +

    + ">Restricted Admin Page +

    +
    + + + This text is only visible to an admin +
    + ">Admin Page +
    +
    + + ">Logout + + + \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/.babelrc b/spring-security-react/src/main/webapp/WEB-INF/view/react/.babelrc new file mode 100644 index 0000000000..2f01e1d615 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["env"] +} \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/.eslintignore b/spring-security-react/src/main/webapp/WEB-INF/view/react/.eslintignore new file mode 100644 index 0000000000..48912d244b --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/.eslintignore @@ -0,0 +1,2 @@ +build +node_modules \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/.eslintrc b/spring-security-react/src/main/webapp/WEB-INF/view/react/.eslintrc new file mode 100644 index 0000000000..c977d77e77 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/.eslintrc @@ -0,0 +1,22 @@ +{ + "rules": { + "linebreak-style": [2, "unix"], + "semi":"off", + "no-console": "off" + }, + "ecmaFeatures": { + "jsx": true + }, + "env": { + "es6": true, + "browser": true, + "node": true, + "mocha": true + }, + "plugins": ["react"], + "parser": "babel-eslint", + "parserOptions": { + "sourceType": "module" + }, + "extends": ["eslint:recommended", "plugin:react/recommended"] +} \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/.gitignore b/spring-security-react/src/main/webapp/WEB-INF/view/react/.gitignore new file mode 100644 index 0000000000..146fcfd8bb --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/.gitignore @@ -0,0 +1,22 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +node_modules +node + +# development +build + +# testing +coverage + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/package-lock.json b/spring-security-react/src/main/webapp/WEB-INF/view/react/package-lock.json new file mode 100644 index 0000000000..46f3a86c20 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/package-lock.json @@ -0,0 +1,10253 @@ +{ + "name": "react", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=" + }, + "acorn": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==" + }, + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "requires": { + "acorn": "^4.0.3" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "acorn-globals": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", + "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", + "requires": { + "acorn": "^4.0.4" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + } + } + }, + "address": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", + "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==" + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=" + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "requires": { + "string-width": "^2.0.0" + } + }, + "ansi-escapes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + } + } + }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.7.1.tgz", + "integrity": "sha1-Jsu1r/ZBRLCoJb4YRuCxbPoAsR4=", + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "requires": { + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=" + }, + "autoprefixer": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.6.tgz", + "integrity": "sha512-C9yv/UF3X+eJTi/zvfxuyfxmLibYrntpF3qoJYrMeQwgUJOZrZvpJiMG2FMQ3qnhWtF/be4pYONBBw95ZGe3vA==", + "requires": { + "browserslist": "^2.5.1", + "caniuse-lite": "^1.0.30000748", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.13", + "postcss-value-parser": "^3.2.3" + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" + }, + "axobject-query": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz", + "integrity": "sha1-YvWdvFnJ+SQnWco0mWDnov48NsA=", + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "babel-eslint": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", + "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", + "requires": { + "babel-code-frame": "^6.22.0", + "babel-traverse": "^6.23.1", + "babel-types": "^6.23.0", + "babylon": "^6.17.0" + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-builder-react-jsx": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", + "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "esutils": "^2.0.2" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-20.0.3.tgz", + "integrity": "sha1-5KA7E9wQOJ4UD8ZF0J/8TO0wFnE=", + "requires": { + "babel-core": "^6.0.0", + "babel-plugin-istanbul": "^4.0.0", + "babel-preset-jest": "^20.0.3" + } + }, + "babel-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz", + "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==", + "requires": { + "find-cache-dir": "^1.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.1.0.tgz", + "integrity": "sha512-tTfZbM9Ecwj3GK50mnPrUpinTwA4xXmDiQGCk/aBYbvl1+X8YqldK86wZ1owVJ4u3mrKbRlXMma80J18qwiaTQ==", + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-istanbul": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", + "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.13.0", + "find-up": "^2.1.0", + "istanbul-lib-instrument": "^1.10.1", + "test-exclude": "^4.2.1" + } + }, + "babel-plugin-jest-hoist": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz", + "integrity": "sha1-r+3IU70/jcNUjqZx++adA8wsF2c=" + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=" + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=" + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" + }, + "babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=" + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "requires": { + "babel-plugin-syntax-flow": "^6.18.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-react-constant-elements": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-constant-elements/-/babel-plugin-transform-react-constant-elements-6.23.0.tgz", + "integrity": "sha1-LxGb9NLN1F65uqrldAU8YE9hR90=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", + "requires": { + "babel-helper-builder-react-jsx": "^6.24.1", + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-preset-env": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", + "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^2.1.2", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "requires": { + "babel-plugin-transform-flow-strip-types": "^6.22.0" + } + }, + "babel-preset-jest": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz", + "integrity": "sha1-y6yq3stdaJyh4d4TYOv8ZoYsF4o=", + "requires": { + "babel-plugin-jest-hoist": "^20.0.3" + } + }, + "babel-preset-react": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", + "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", + "requires": { + "babel-plugin-syntax-jsx": "^6.3.13", + "babel-plugin-transform-react-display-name": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-plugin-transform-react-jsx-self": "^6.22.0", + "babel-plugin-transform-react-jsx-source": "^6.22.0", + "babel-preset-flow": "^6.23.0" + } + }, + "babel-preset-react-app": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-3.1.2.tgz", + "integrity": "sha512-/sh5Qd5T08PYa6t4kuCdKh9tXp6/m/Jwyx7PJTqugsYMfsDUJMlBXOs5EwFODHprzjWrmQ0SydnMZu9FY4MZYg==", + "requires": { + "babel-plugin-dynamic-import-node": "1.1.0", + "babel-plugin-syntax-dynamic-import": "6.18.0", + "babel-plugin-transform-class-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-object-rest-spread": "6.26.0", + "babel-plugin-transform-react-constant-elements": "6.23.0", + "babel-plugin-transform-react-jsx": "6.24.1", + "babel-plugin-transform-react-jsx-self": "6.22.0", + "babel-plugin-transform-react-jsx-source": "6.22.0", + "babel-plugin-transform-regenerator": "6.26.0", + "babel-plugin-transform-runtime": "6.23.0", + "babel-preset-env": "1.6.1", + "babel-preset-react": "6.24.1" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + }, + "dependencies": { + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" + } + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" + } + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", + "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", + "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "requires": { + "caniuse-lite": "^1.0.30000792", + "electron-to-chromium": "^1.3.30" + } + }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + } + } + }, + "caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "requires": { + "browserslist": "^1.3.6", + "caniuse-db": "^1.0.30000529", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + } + } + } + }, + "caniuse-db": { + "version": "1.0.30000861", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000861.tgz", + "integrity": "sha1-byeEChMMEMCx4A+rdynB+vj0zNM=" + }, + "caniuse-lite": { + "version": "1.0.30000861", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000861.tgz", + "integrity": "sha512-aeEQ4kyd41qCl8XFbCjWgVBI3EOd66M9sC43MFn0kuD/vcrNqvoIAlKon4xdp8yMCYvVjdCltI3lgArj8I6cNA==" + }, + "capture-stack-trace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" + }, + "case-sensitive-paths-webpack-plugin": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.1.1.tgz", + "integrity": "sha1-PSnO2MHxJL9vU4Rvs/WJRzH9yQk=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "requires": { + "is-extglob": "^2.1.1" + } + } + } + }, + "ci-info": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz", + "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" + }, + "clap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", + "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "requires": { + "chalk": "^1.1.3" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-css": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz", + "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=", + "requires": { + "source-map": "0.5.x" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "requires": { + "q": "^1.1.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "requires": { + "clone": "^1.0.2", + "color-convert": "^1.3.0", + "color-string": "^0.3.0" + } + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=" + }, + "color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "requires": { + "color-name": "^1.0.0" + } + }, + "colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "requires": { + "color": "^0.11.0", + "css-color-names": "0.0.4", + "has": "^1.0.1" + } + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", + "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "compare-versions": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.3.0.tgz", + "integrity": "sha512-MAAAIOdi2s4Gl6rZ76PNcUa9IOYB+5ICdT41o5uMRf09aEu/F9RK+qhe8RjXNPwcTjGV7KU7h2P/fljThFVqyQ==" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "requires": { + "date-now": "^0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + }, + "content-type-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", + "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==" + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.4.3", + "minimist": "^1.2.0", + "object-assign": "^4.1.0", + "os-homedir": "^1.0.1", + "parse-json": "^2.2.0", + "require-from-string": "^1.1.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" + }, + "css-loader": { + "version": "0.28.7", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.7.tgz", + "integrity": "sha512-GxMpax8a/VgcfRrVy0gXD6yLd5ePYbXX/5zGgTVYp4wXtJklS8Z2VaUArJgc//f6/Dzil7BaJObdSv8eKKCPgg==", + "requires": { + "babel-code-frame": "^6.11.0", + "css-selector-tokenizer": "^0.7.0", + "cssnano": ">=2.6.1 <4", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash.camelcase": "^4.3.0", + "object-assign": "^4.0.1", + "postcss": "^5.0.6", + "postcss-modules-extract-imports": "^1.0.0", + "postcss-modules-local-by-default": "^1.0.1", + "postcss-modules-scope": "^1.0.0", + "postcss-modules-values": "^1.1.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "requires": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" + }, + "dependencies": { + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + } + } + }, + "css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=" + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=" + }, + "cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "requires": { + "autoprefixer": "^6.3.1", + "decamelize": "^1.1.2", + "defined": "^1.0.0", + "has": "^1.0.1", + "object-assign": "^4.0.1", + "postcss": "^5.0.14", + "postcss-calc": "^5.2.0", + "postcss-colormin": "^2.1.8", + "postcss-convert-values": "^2.3.4", + "postcss-discard-comments": "^2.0.4", + "postcss-discard-duplicates": "^2.0.1", + "postcss-discard-empty": "^2.0.1", + "postcss-discard-overridden": "^0.1.1", + "postcss-discard-unused": "^2.2.1", + "postcss-filter-plugins": "^2.0.0", + "postcss-merge-idents": "^2.1.5", + "postcss-merge-longhand": "^2.0.1", + "postcss-merge-rules": "^2.0.3", + "postcss-minify-font-values": "^1.0.2", + "postcss-minify-gradients": "^1.0.1", + "postcss-minify-params": "^1.0.4", + "postcss-minify-selectors": "^2.0.4", + "postcss-normalize-charset": "^1.1.0", + "postcss-normalize-url": "^3.0.7", + "postcss-ordered-values": "^2.1.0", + "postcss-reduce-idents": "^2.2.2", + "postcss-reduce-initial": "^1.0.0", + "postcss-reduce-transforms": "^1.0.3", + "postcss-svgo": "^2.1.1", + "postcss-unique-selectors": "^2.0.2", + "postcss-value-parser": "^3.2.3", + "postcss-zindex": "^2.0.1" + }, + "dependencies": { + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "requires": { + "browserslist": "^1.7.6", + "caniuse-db": "^1.0.30000634", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^5.2.16", + "postcss-value-parser": "^3.2.3" + } + }, + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "requires": { + "clap": "^1.0.9", + "source-map": "^0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "cssom": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.3.tgz", + "integrity": "sha512-pjE/I/NSp3iyeoxXN5QaoJpgzYUMj2dJHx9OSufoTliJLDx+kuOQaMCJW8OwvrKJswhXUHnHN6eUmUSETN0msg==" + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "requires": { + "cssom": "0.3.x" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "^1.0.1" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "^0.10.9" + } + }, + "damerau-levenshtein": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz", + "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "requires": { + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "requires": { + "repeating": "^2.0.0" + } + }, + "detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-converter": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", + "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", + "requires": { + "utila": "~0.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=" + } + } + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "requires": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" + } + } + }, + "dom-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/dom-urls/-/dom-urls-1.1.0.tgz", + "integrity": "sha1-AB3fgWKM0ecGElxxdvU8zsVdkY4=", + "requires": { + "urijs": "^1.16.1" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" + }, + "domhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", + "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "requires": { + "is-obj": "^1.0.0" + } + }, + "dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + }, + "dotenv-expand": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz", + "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=" + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "electron-to-chromium": { + "version": "1.3.50", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.50.tgz", + "integrity": "sha1-dDi3b5K0G5GfP73TUPvQdX2s3fc=" + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", + "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==" + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "object-assign": "^4.0.1", + "tapable": "^0.2.7" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.10.0.tgz", + "integrity": "sha512-fjUOf8johsv23WuIKdNQU4P9t9jhQ4Qzx6pC2uW890OloK3Zs1ZAoCNpg/2larNF501jLl3UNy0kIRcF6VI22g==", + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + } + } + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "requires": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.10.0.tgz", + "integrity": "sha512-MMVl8P/dYUFZEvolL8PYt7qc5LNdS2lwheq9BYa5Y07FblhcZqFyaUqlS8TW5QITGex21tV4Lk0a3fK8lsJIkA==", + "requires": { + "ajv": "^5.2.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.0.1", + "doctrine": "^2.0.0", + "eslint-scope": "^3.7.1", + "espree": "^3.5.1", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^9.17.0", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "^4.0.1", + "text-table": "~0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-config-react-app": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-2.1.0.tgz", + "integrity": "sha512-8QZrKWuHVC57Fmu+SsKAVxnI9LycZl7NFQ4H9L+oeISuCXhYdXqsOOIVSjQFW6JF5MXZLFE+21Syhd7mF1IRZQ==" + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-loader": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.9.0.tgz", + "integrity": "sha512-40aN976qSNPyb9ejTqjEthZITpls1SVKtwguahmH1dzGCwQU/vySE+xX33VZmD8csU0ahVNCtFlsPgKqRBiqgg==", + "requires": { + "loader-fs-cache": "^1.0.0", + "loader-utils": "^1.0.2", + "object-assign": "^4.0.1", + "object-hash": "^1.1.4", + "rimraf": "^2.6.1" + } + }, + "eslint-module-utils": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", + "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "requires": { + "find-up": "^1.0.0" + } + } + } + }, + "eslint-plugin-flowtype": { + "version": "2.39.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.39.1.tgz", + "integrity": "sha512-RiQv+7Z9QDJuzt+NO8sYgkLGT+h+WeCrxP7y8lI7wpU41x3x/2o3PGtHk9ck8QnA9/mlbNcy/hG0eKvmd7npaA==", + "requires": { + "lodash": "^4.15.0" + } + }, + "eslint-plugin-import": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", + "requires": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.1.1", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "^2.0.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.1.1.tgz", + "integrity": "sha512-5I9SpoP7gT4wBFOtXT8/tXNPYohHBVfyVfO17vkbC7r9kEIxYJF12D3pKqhk8+xnk12rfxKClS3WCFpVckFTPQ==", + "requires": { + "aria-query": "^0.7.0", + "array-includes": "^3.0.3", + "ast-types-flow": "0.0.7", + "axobject-query": "^0.1.0", + "damerau-levenshtein": "^1.0.0", + "emoji-regex": "^6.1.0", + "jsx-ast-utils": "^1.4.0" + } + }, + "eslint-plugin-react": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.10.0.tgz", + "integrity": "sha512-18rzWn4AtbSUxFKKM7aCVcj5LXOhOKdwBino3KKWy4psxfPW0YtIbE8WNRDUdyHFL50BeLb6qFd4vpvNYyp7hw==", + "dev": true, + "requires": { + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1", + "prop-types": "^15.6.2" + }, + "dependencies": { + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, + "requires": { + "array-includes": "^3.0.3" + } + } + } + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exec-sh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", + "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", + "requires": { + "merge": "^1.2.0" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extract-text-webpack-plugin": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", + "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", + "requires": { + "async": "^2.4.1", + "loader-utils": "^1.1.0", + "schema-utils": "^0.3.0", + "webpack-sources": "^1.0.1" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastparse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=" + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "requires": { + "bser": "^2.0.0" + } + }, + "fbjs": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", + "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", + "requires": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "file-loader": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.5.tgz", + "integrity": "sha512-RzGHDatcVNpGISTvCpfUfOGpYuSR7HSsSg87ki+wF6rw1Hm0RALPTiAdsxAq1UwLf0RRhbe22/eHK6nhXspiOQ==", + "requires": { + "loader-utils": "^1.0.2", + "schema-utils": "^0.3.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "filesize": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.11.tgz", + "integrity": "sha512-ZH7loueKBoDb7yG9esn1U+fgq7BzlzW6NRi5/rMdxIZ05dj7GFD/Xc5rq2CDt5Yq86CyfSYVyx4242QQNZbx1g==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "requires": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + } + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "requires": { + "ini": "^1.3.4" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" + }, + "gzip-size": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", + "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", + "requires": { + "duplexer": "^0.1.1" + } + }, + "handlebars": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "requires": { + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "requires": { + "amdefine": ">=0.0.4" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "optional": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "optional": true + } + } + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "optional": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.4.tgz", + "integrity": "sha512-A6RlQvvZEtFS5fLU43IDu0QUmBy+fDO9VMdTXvufKwIkt/rFfvICAViCax5fbDO4zdNzaC3/27ZhKUok5bAJyw==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.1.tgz", + "integrity": "sha512-Ba4+0M4YvIDUUsprMjhVTU1yN9F2/LJSAl69ZpzaLT4l4j5mwTS6jqqW9Ojvj6lKz/veqPzpJBqGbXspOb533A==" + }, + "html-comment-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=" + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-minifier": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.17.tgz", + "integrity": "sha512-O+StuKL0UWfwX5Zv4rFxd60DPcT5DVjGq1AlnP6VQ8wzudft/W4hx5Wl98aSYNwFBHY6XWJreRw/BehX4l+diQ==", + "requires": { + "camel-case": "3.0.x", + "clean-css": "4.1.x", + "commander": "2.15.x", + "he": "1.1.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + } + } + }, + "html-webpack-plugin": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.29.0.tgz", + "integrity": "sha1-6Yf0IYU9O2k4yMTIFxhC5f0XryM=", + "requires": { + "bluebird": "^3.4.7", + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "toposort": "^1.0.0" + }, + "dependencies": { + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + } + } + }, + "htmlparser2": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", + "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", + "requires": { + "domelementtype": "1", + "domhandler": "2.1", + "domutils": "1.1", + "readable-stream": "1.0" + }, + "dependencies": { + "domutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", + "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", + "requires": { + "domelementtype": "1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "requires": { + "postcss": "^6.0.1" + } + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "^2.0.0" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" + }, + "is-ci": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", + "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "requires": { + "ci-info": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + }, + "is-root": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz", + "integrity": "sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-api": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz", + "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==", + "requires": { + "async": "^2.1.4", + "compare-versions": "^3.1.0", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-hook": "^1.2.0", + "istanbul-lib-instrument": "^1.10.1", + "istanbul-lib-report": "^1.1.4", + "istanbul-lib-source-maps": "^1.2.4", + "istanbul-reports": "^1.3.0", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz", + "integrity": "sha512-8O2T/3VhrQHn0XcJbP1/GN7kXMiRAlPi+fj3uEHrjBD8Oz7Py0prSC25C09NuAZS6bgW1NNKAvCSHZXB0irSGA==", + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.0", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "istanbul-lib-coverage": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", + "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==" + }, + "istanbul-lib-hook": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.1.tgz", + "integrity": "sha512-eLAMkPG9FU0v5L02lIkcj/2/Zlz9OuluaXikdr5iStk8FDbSwAixTK9TkYxbF0eNnzAJTwM2fkV2A1tpsIp4Jg==", + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz", + "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==", + "requires": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.0", + "semver": "^5.3.0" + } + }, + "istanbul-lib-report": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz", + "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==", + "requires": { + "istanbul-lib-coverage": "^1.2.0", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.3.tgz", + "integrity": "sha512-fDa0hwU/5sDXwAklXgAoCJCOsFsBplVQ6WBldz5UwaqOzmDhUK4nfuR7/G//G2lERlblUNJB8P6e8cXq3a7MlA==", + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.1.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "istanbul-reports": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz", + "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==", + "requires": { + "handlebars": "^4.0.3" + } + }, + "jest": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-20.0.4.tgz", + "integrity": "sha1-PdJgwpidba1nix6cxNkZRPbWAqw=", + "requires": { + "jest-cli": "^20.0.4" + }, + "dependencies": { + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "jest-cli": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-20.0.4.tgz", + "integrity": "sha1-5TKxnYiuW8bEF+iwWTpv6VSx3JM=", + "requires": { + "ansi-escapes": "^1.4.0", + "callsites": "^2.0.0", + "chalk": "^1.1.3", + "graceful-fs": "^4.1.11", + "is-ci": "^1.0.10", + "istanbul-api": "^1.1.1", + "istanbul-lib-coverage": "^1.0.1", + "istanbul-lib-instrument": "^1.4.2", + "istanbul-lib-source-maps": "^1.1.0", + "jest-changed-files": "^20.0.3", + "jest-config": "^20.0.4", + "jest-docblock": "^20.0.3", + "jest-environment-jsdom": "^20.0.3", + "jest-haste-map": "^20.0.4", + "jest-jasmine2": "^20.0.4", + "jest-message-util": "^20.0.3", + "jest-regex-util": "^20.0.3", + "jest-resolve-dependencies": "^20.0.3", + "jest-runtime": "^20.0.4", + "jest-snapshot": "^20.0.3", + "jest-util": "^20.0.3", + "micromatch": "^2.3.11", + "node-notifier": "^5.0.2", + "pify": "^2.3.0", + "slash": "^1.0.0", + "string-length": "^1.0.1", + "throat": "^3.0.0", + "which": "^1.2.12", + "worker-farm": "^1.3.1", + "yargs": "^7.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + } + } + }, + "jest-changed-files": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-20.0.3.tgz", + "integrity": "sha1-k5TVzGXEOEBhSb7xv01Sto4D4/g=" + }, + "jest-config": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-20.0.4.tgz", + "integrity": "sha1-43kwqyIXyRNgXv8T5712PsSPruo=", + "requires": { + "chalk": "^1.1.3", + "glob": "^7.1.1", + "jest-environment-jsdom": "^20.0.3", + "jest-environment-node": "^20.0.3", + "jest-jasmine2": "^20.0.4", + "jest-matcher-utils": "^20.0.3", + "jest-regex-util": "^20.0.3", + "jest-resolve": "^20.0.4", + "jest-validate": "^20.0.3", + "pretty-format": "^20.0.3" + } + }, + "jest-diff": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-20.0.3.tgz", + "integrity": "sha1-gfKI/Z5nXw+yPHXxwrGURf5YZhc=", + "requires": { + "chalk": "^1.1.3", + "diff": "^3.2.0", + "jest-matcher-utils": "^20.0.3", + "pretty-format": "^20.0.3" + } + }, + "jest-docblock": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-20.0.3.tgz", + "integrity": "sha1-F76phDQswz2DxQ++FUXqDvqkRxI=" + }, + "jest-environment-jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz", + "integrity": "sha1-BIqKwS7iJfcZBBdxODS7mZeH3pk=", + "requires": { + "jest-mock": "^20.0.3", + "jest-util": "^20.0.3", + "jsdom": "^9.12.0" + } + }, + "jest-environment-node": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-20.0.3.tgz", + "integrity": "sha1-1Ii8RhKvLCRumG6K52caCZFj1AM=", + "requires": { + "jest-mock": "^20.0.3", + "jest-util": "^20.0.3" + } + }, + "jest-haste-map": { + "version": "20.0.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-20.0.5.tgz", + "integrity": "sha512-0IKAQjUvuZjMCNi/0VNQQF74/H9KB67hsHJqGiwTWQC6XO5Azs7kLWm+6Q/dwuhvDUvABDOBMFK2/FwZ3sZ07Q==", + "requires": { + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.11", + "jest-docblock": "^20.0.3", + "micromatch": "^2.3.11", + "sane": "~1.6.0", + "worker-farm": "^1.3.1" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + } + } + }, + "jest-jasmine2": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-20.0.4.tgz", + "integrity": "sha1-/MWxQReA2RHQQpAu8YWehS5g1eE=", + "requires": { + "chalk": "^1.1.3", + "graceful-fs": "^4.1.11", + "jest-diff": "^20.0.3", + "jest-matcher-utils": "^20.0.3", + "jest-matchers": "^20.0.3", + "jest-message-util": "^20.0.3", + "jest-snapshot": "^20.0.3", + "once": "^1.4.0", + "p-map": "^1.1.1" + } + }, + "jest-matcher-utils": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz", + "integrity": "sha1-s6a443yld4A7CDKpixZPRLeBVhI=", + "requires": { + "chalk": "^1.1.3", + "pretty-format": "^20.0.3" + } + }, + "jest-matchers": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-matchers/-/jest-matchers-20.0.3.tgz", + "integrity": "sha1-ymnbHDLbWm9wf6XgQBq7VXAN/WA=", + "requires": { + "jest-diff": "^20.0.3", + "jest-matcher-utils": "^20.0.3", + "jest-message-util": "^20.0.3", + "jest-regex-util": "^20.0.3" + } + }, + "jest-message-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-20.0.3.tgz", + "integrity": "sha1-auwoRDBvyw5udNV5bBAG2W/dgxw=", + "requires": { + "chalk": "^1.1.3", + "micromatch": "^2.3.11", + "slash": "^1.0.0" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + } + } + }, + "jest-mock": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-20.0.3.tgz", + "integrity": "sha1-i8Bw6QQUqhVcEajWTIaaDVxx2lk=" + }, + "jest-regex-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-20.0.3.tgz", + "integrity": "sha1-hburXRM+RGJbGfr4xqpRItCF12I=" + }, + "jest-resolve": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-20.0.4.tgz", + "integrity": "sha1-lEiz6La6/BVHlETGSZBFt//ll6U=", + "requires": { + "browser-resolve": "^1.11.2", + "is-builtin-module": "^1.0.0", + "resolve": "^1.3.2" + } + }, + "jest-resolve-dependencies": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz", + "integrity": "sha1-bhSntxevDyyzZnxUneQK8Bexcjo=", + "requires": { + "jest-regex-util": "^20.0.3" + } + }, + "jest-runtime": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-20.0.4.tgz", + "integrity": "sha1-osgCIZxCA/dU3xQE5JAYYWnRJNg=", + "requires": { + "babel-core": "^6.0.0", + "babel-jest": "^20.0.3", + "babel-plugin-istanbul": "^4.0.0", + "chalk": "^1.1.3", + "convert-source-map": "^1.4.0", + "graceful-fs": "^4.1.11", + "jest-config": "^20.0.4", + "jest-haste-map": "^20.0.4", + "jest-regex-util": "^20.0.3", + "jest-resolve": "^20.0.4", + "jest-util": "^20.0.3", + "json-stable-stringify": "^1.0.1", + "micromatch": "^2.3.11", + "strip-bom": "3.0.0", + "yargs": "^7.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + } + } + }, + "jest-snapshot": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-20.0.3.tgz", + "integrity": "sha1-W4R+GtsaTZCFKn+fElCG4YfHZWY=", + "requires": { + "chalk": "^1.1.3", + "jest-diff": "^20.0.3", + "jest-matcher-utils": "^20.0.3", + "jest-util": "^20.0.3", + "natural-compare": "^1.4.0", + "pretty-format": "^20.0.3" + } + }, + "jest-util": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-20.0.3.tgz", + "integrity": "sha1-DAf32A2C9OWmfG+LnD/n9lz9Mq0=", + "requires": { + "chalk": "^1.1.3", + "graceful-fs": "^4.1.11", + "jest-message-util": "^20.0.3", + "jest-mock": "^20.0.3", + "jest-validate": "^20.0.3", + "leven": "^2.1.0", + "mkdirp": "^0.5.1" + } + }, + "jest-validate": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-20.0.3.tgz", + "integrity": "sha1-0M/R3k9XnymEhJJcKA+PHZTsPKs=", + "requires": { + "chalk": "^1.1.3", + "jest-matcher-utils": "^20.0.3", + "leven": "^2.1.0", + "pretty-format": "^20.0.3" + } + }, + "js-base64": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.5.tgz", + "integrity": "sha512-aUnNwqMOXw3yvErjMPSQu6qIIzUmT1e5KcU1OZxRDU1g/am6mzBvcrmLAYwzmB59BHPrh5/tKaiF4OPhqRWESQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "requires": { + "argparse": "^1.0.7", + "esprima": "^2.6.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "jsdom": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz", + "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=", + "requires": { + "abab": "^1.0.3", + "acorn": "^4.0.4", + "acorn-globals": "^3.1.0", + "array-equal": "^1.0.0", + "content-type-parser": "^1.0.1", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.2.37 < 0.3.0", + "escodegen": "^1.6.1", + "html-encoding-sniffer": "^1.0.1", + "nwmatcher": ">= 1.3.9 < 2.0.0", + "parse5": "^1.5.1", + "request": "^2.79.0", + "sax": "^1.2.1", + "symbol-tree": "^3.2.1", + "tough-cookie": "^2.3.2", + "webidl-conversions": "^4.0.0", + "whatwg-encoding": "^1.0.1", + "whatwg-url": "^4.3.0", + "xml-name-validator": "^2.0.1" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "requires": { + "package-json": "^4.0.0" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "loader-fs-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz", + "integrity": "sha1-VuC/CL2XCLJqdltoUJhAyN7J/bw=", + "requires": { + "find-cache-dir": "^0.1.1", + "mkdirp": "0.5.1" + }, + "dependencies": { + "find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "requires": { + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "requires": { + "find-up": "^1.0.0" + } + } + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=" + }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "requires": { + "lodash._reinterpolate": "~3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "requires": { + "lodash._reinterpolate": "~3.0.0" + } + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "^3.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-expression-evaluator": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=" + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "merge": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", + "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "requires": { + "mime-db": "~1.33.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "neo-async": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", + "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.0", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "node-notifier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz", + "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==", + "requires": { + "growly": "^1.3.0", + "semver": "^5.4.1", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "requires": { + "boolbase": "~1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "nwmatcher": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", + "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.0.tgz", + "integrity": "sha512-05KzQ70lSeGSrZJQXE5wNDiTkBJDlUT/myi6RX9dVIvz7a7Qh4oH93BQdiPMn27nldYvVQCKMUaM83AfizZlsQ==" + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "opn": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz", + "integrity": "sha512-Jd/GpzPyHF4P2/aNOVmS3lfMSWV9J7cOhCG1s08XCEAsPkB7lp6ddiU0J7XzyQRDUh8BqJ7PchfINjR8jyofRQ==", + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==" + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "requires": { + "no-case": "^2.2.0" + } + }, + "parse-asn1": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pbkdf2": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", + "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "requires": { + "find-up": "^2.1.0" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "requires": { + "postcss": "^5.0.2", + "postcss-message-helpers": "^2.0.0", + "reduce-css-calc": "^1.2.6" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "requires": { + "colormin": "^1.0.5", + "postcss": "^5.0.13", + "postcss-value-parser": "^3.2.3" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "requires": { + "postcss": "^5.0.11", + "postcss-value-parser": "^3.1.2" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-discard-comments": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "requires": { + "postcss": "^5.0.14" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "requires": { + "postcss": "^5.0.4" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-discard-empty": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "requires": { + "postcss": "^5.0.14" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "requires": { + "postcss": "^5.0.16" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-discard-unused": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "requires": { + "postcss": "^5.0.14", + "uniqs": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-filter-plugins": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz", + "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==", + "requires": { + "postcss": "^5.0.4" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-flexbugs-fixes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-3.2.0.tgz", + "integrity": "sha512-0AuD9HG1Ey3/3nqPWu9yqf7rL0KCPu5VgjDsjf5mzEcuo9H/z8nco/fljKgjsOUrZypa95MI0kS4xBZeBzz2lw==", + "requires": { + "postcss": "^6.0.1" + } + }, + "postcss-load-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "requires": { + "cosmiconfig": "^2.1.0", + "object-assign": "^4.1.0", + "postcss-load-options": "^1.2.0", + "postcss-load-plugins": "^2.3.0" + } + }, + "postcss-load-options": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "requires": { + "cosmiconfig": "^2.1.0", + "object-assign": "^4.1.0" + } + }, + "postcss-load-plugins": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "requires": { + "cosmiconfig": "^2.1.1", + "object-assign": "^4.1.0" + } + }, + "postcss-loader": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.8.tgz", + "integrity": "sha512-KtXBiQ/r/WYW8LxTSJK7h8wLqvCMSub/BqmRnud/Mu8RzwflW9cmXxwsMwbn15TNv287Hcufdb3ZSs7xHKnG8Q==", + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^6.0.0", + "postcss-load-config": "^1.2.0", + "schema-utils": "^0.3.0" + } + }, + "postcss-merge-idents": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "requires": { + "has": "^1.0.1", + "postcss": "^5.0.10", + "postcss-value-parser": "^3.1.1" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "requires": { + "postcss": "^5.0.4" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "requires": { + "browserslist": "^1.5.2", + "caniuse-api": "^1.5.2", + "postcss": "^5.0.4", + "postcss-selector-parser": "^2.2.2", + "vendors": "^1.0.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "requires": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=" + }, + "postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "requires": { + "object-assign": "^4.0.1", + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.2" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "requires": { + "postcss": "^5.0.12", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-minify-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "requires": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.2", + "postcss-value-parser": "^3.0.2", + "uniqs": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "requires": { + "alphanum-sort": "^1.0.2", + "has": "^1.0.1", + "postcss": "^5.0.14", + "postcss-selector-parser": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", + "requires": { + "postcss": "^6.0.1" + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + } + }, + "postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "requires": { + "postcss": "^5.0.5" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-normalize-url": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^1.4.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "requires": { + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.1" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-reduce-idents": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "requires": { + "postcss": "^5.0.4", + "postcss-value-parser": "^3.0.2" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "requires": { + "postcss": "^5.0.4" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "requires": { + "has": "^1.0.1", + "postcss": "^5.0.8", + "postcss-value-parser": "^3.0.1" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "postcss-svgo": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "requires": { + "is-svg": "^2.0.0", + "postcss": "^5.0.14", + "postcss-value-parser": "^3.2.3", + "svgo": "^0.7.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "requires": { + "alphanum-sort": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=" + }, + "postcss-zindex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "requires": { + "has": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "pretty-bytes": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", + "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=" + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "requires": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, + "pretty-format": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-20.0.3.tgz", + "integrity": "sha1-Ag41ClYKH+GpjcO+tsz/s4beixQ=", + "requires": { + "ansi-regex": "^2.1.1", + "ansi-styles": "^3.0.0" + } + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "prop-types": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", + "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", + "requires": { + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.1.28", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.28.tgz", + "integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==" + }, + "public-encrypt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "raf": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz", + "integrity": "sha512-pDP/NMRAXoTfrhCfyfSEwJAKLaxBU9eApMeBPB1TkDouZmvPerIClV8lTAd+uF8ZiTaVl69e1FCxQrAd/VTjGw==", + "requires": { + "performance-now": "^2.1.0" + } + }, + "randomatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", + "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + } + } + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "react": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.4.1.tgz", + "integrity": "sha512-3GEs0giKp6E0Oh/Y9ZC60CmYgUPnp7voH9fbjWsvXtYFb4EWtgQub0ADSq0sJR0BbHc4FThLLtzlcFaFXIorwg==", + "requires": { + "fbjs": "^0.8.16", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.0" + } + }, + "react-dev-utils": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-5.0.1.tgz", + "integrity": "sha512-+y92rG6pmXt3cpcg/NGmG4w/W309tWNSmyyPL8hCMxuCSg2UP/hUg3npACj2UZc8UKVSXexyLrCnxowizGoAsw==", + "requires": { + "address": "1.0.3", + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "cross-spawn": "5.1.0", + "detect-port-alt": "1.1.6", + "escape-string-regexp": "1.0.5", + "filesize": "3.5.11", + "global-modules": "1.0.0", + "gzip-size": "3.0.0", + "inquirer": "3.3.0", + "is-root": "1.0.0", + "opn": "5.2.0", + "react-error-overlay": "^4.0.0", + "recursive-readdir": "2.2.1", + "shell-quote": "1.6.1", + "strip-ansi": "3.0.1", + "text-table": "0.2.0" + }, + "dependencies": { + "sockjs-client": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.5.tgz", + "integrity": "sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM=", + "requires": { + "debug": "^2.6.6", + "inherits": "^2.0.1" + } + } + } + }, + "react-dom": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.4.1.tgz", + "integrity": "sha512-1Gin+wghF/7gl4Cqcvr1DxFX2Osz7ugxSwl6gBqCMpdrxHjIFUS7GYxrFftZ9Ln44FHw0JxCFD9YtZsrbR5/4A==", + "requires": { + "fbjs": "^0.8.16", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.0" + } + }, + "react-error-overlay": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-4.0.0.tgz", + "integrity": "sha512-FlsPxavEyMuR6TjVbSSywovXSEyOg6ZDj5+Z8nbsRl9EkOzAhEIcS+GLoQDC5fz/t9suhUXWmUrOBrgeUvrMxw==" + }, + "react-scripts": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-1.1.4.tgz", + "integrity": "sha512-UVZIujEIT9BGbx+NGvyfS92eOrNIIpqqFi1FP7a0O9l94A/XV7bhPk70SfDKaXZouCX81tFdXo0948DjhCEgGw==", + "requires": { + "autoprefixer": "7.1.6", + "babel-core": "6.26.0", + "babel-eslint": "7.2.3", + "babel-jest": "20.0.3", + "babel-loader": "7.1.2", + "babel-preset-react-app": "^3.1.1", + "babel-runtime": "6.26.0", + "case-sensitive-paths-webpack-plugin": "2.1.1", + "chalk": "1.1.3", + "css-loader": "0.28.7", + "dotenv": "4.0.0", + "dotenv-expand": "4.2.0", + "eslint": "4.10.0", + "eslint-config-react-app": "^2.1.0", + "eslint-loader": "1.9.0", + "eslint-plugin-flowtype": "2.39.1", + "eslint-plugin-import": "2.8.0", + "eslint-plugin-jsx-a11y": "5.1.1", + "eslint-plugin-react": "7.4.0", + "extract-text-webpack-plugin": "3.0.2", + "file-loader": "1.1.5", + "fs-extra": "3.0.1", + "fsevents": "^1.1.3", + "html-webpack-plugin": "2.29.0", + "jest": "20.0.4", + "object-assign": "4.1.1", + "postcss-flexbugs-fixes": "3.2.0", + "postcss-loader": "2.0.8", + "promise": "8.0.1", + "raf": "3.4.0", + "react-dev-utils": "^5.0.1", + "resolve": "1.6.0", + "style-loader": "0.19.0", + "sw-precache-webpack-plugin": "0.11.4", + "url-loader": "0.6.2", + "webpack": "3.8.1", + "webpack-manifest-plugin": "1.3.2", + "whatwg-fetch": "2.0.3" + }, + "dependencies": { + "eslint-plugin-react": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz", + "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==", + "requires": { + "doctrine": "^2.0.0", + "has": "^1.0.1", + "jsx-ast-utils": "^2.0.0", + "prop-types": "^15.5.10" + } + }, + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "requires": { + "array-includes": "^3.0.3" + } + }, + "promise": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.0.1.tgz", + "integrity": "sha1-5F1osAoXZHttpxG/he1u1HII9FA=", + "requires": { + "asap": "~2.0.3" + } + }, + "webpack-dev-server": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.5.tgz", + "integrity": "sha512-LVHg+EPwZLHIlfvokSTgtJqO/vI5CQi89fASb5JEDtVMDjY0yuIEqPPdMiKaBJIB/Ab7v/UN/sYZ7WsZvntQKw==", + "requires": { + "array-includes": "^3.0.3", + "chokidar": "^2.0.0", + "opn": "^5.1.0", + "strip-ansi": "^3.0.0", + "supports-color": "^5.1.0" + } + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "requires": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "recursive-readdir": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.1.tgz", + "integrity": "sha1-kO8jHQd4xc4JPJpI105cVCLROpk=", + "requires": { + "minimatch": "3.0.3" + }, + "dependencies": { + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "requires": { + "brace-expansion": "^1.0.0" + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "requires": { + "balanced-match": "^0.4.2", + "math-expression-evaluator": "^1.2.14", + "reduce-function-call": "^1.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + } + } + }, + "reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "requires": { + "balanced-match": "^0.4.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + } + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "registry-auth-token": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "requires": { + "rc": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + } + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "renderkid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", + "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", + "requires": { + "css-select": "^1.1.0", + "dom-converter": "~0.1", + "htmlparser2": "~3.3.0", + "strip-ansi": "^3.0.0", + "utila": "~0.3" + }, + "dependencies": { + "utila": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", + "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=" + } + } + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "^1.4.1" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "resolve": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", + "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==", + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "^7.0.5" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "^2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "requires": { + "rx-lite": "*" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sane": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-1.6.0.tgz", + "integrity": "sha1-lhDEUjB6E10pwf3+JUcDQYDEZ3U=", + "requires": { + "anymatch": "^1.3.0", + "exec-sh": "^0.2.0", + "fb-watchman": "^1.8.0", + "minimatch": "^3.0.2", + "minimist": "^1.1.1", + "walker": "~1.0.5", + "watch": "~0.10.0" + }, + "dependencies": { + "bser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz", + "integrity": "sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk=", + "requires": { + "node-int64": "^0.4.0" + } + }, + "fb-watchman": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.2.tgz", + "integrity": "sha1-okz0eCf4LTj7Waaa1wt247auc4M=", + "requires": { + "bser": "1.0.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "requires": { + "ajv": "^5.0.0" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "requires": { + "semver": "^5.0.3" + } + }, + "serviceworker-cache-polyfill": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serviceworker-cache-polyfill/-/serviceworker-cache-polyfill-4.0.0.tgz", + "integrity": "sha1-3hnuc77yGrPAdAo3sz22JGS6ves=" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", + "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", + "requires": { + "strip-ansi": "^3.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "^4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "style-loader": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.0.tgz", + "integrity": "sha512-9mx9sC9nX1dgP96MZOODpGC6l1RzQBITI2D5WJhu+wnbrSYVKLGuy14XJSLVQih/0GFrPpjelt+s//VcZQ2Evw==", + "requires": { + "loader-utils": "^1.0.2", + "schema-utils": "^0.3.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "requires": { + "coa": "~1.0.1", + "colors": "~1.1.2", + "csso": "~2.3.1", + "js-yaml": "~3.7.0", + "mkdirp": "~0.5.1", + "sax": "~1.2.1", + "whet.extend": "~0.9.9" + } + }, + "sw-precache": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/sw-precache/-/sw-precache-5.2.1.tgz", + "integrity": "sha512-8FAy+BP/FXE+ILfiVTt+GQJ6UEf4CVHD9OfhzH0JX+3zoy2uFk7Vn9EfXASOtVmmIVbL3jE/W8Z66VgPSZcMhw==", + "requires": { + "dom-urls": "^1.1.0", + "es6-promise": "^4.0.5", + "glob": "^7.1.1", + "lodash.defaults": "^4.2.0", + "lodash.template": "^4.4.0", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "pretty-bytes": "^4.0.2", + "sw-toolbox": "^3.4.0", + "update-notifier": "^2.3.0" + } + }, + "sw-precache-webpack-plugin": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/sw-precache-webpack-plugin/-/sw-precache-webpack-plugin-0.11.4.tgz", + "integrity": "sha1-ppUBflTu1XVVFJOlGdwdqNotxeA=", + "requires": { + "del": "^2.2.2", + "sw-precache": "^5.1.1", + "uglify-js": "^3.0.13" + } + }, + "sw-toolbox": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/sw-toolbox/-/sw-toolbox-3.6.0.tgz", + "integrity": "sha1-Jt8dHHA0hljk3qKIQxkUm3sxg7U=", + "requires": { + "path-to-regexp": "^1.0.1", + "serviceworker-cache-polyfill": "^4.0.0" + } + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" + }, + "table": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "requires": { + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.1.tgz", + "integrity": "sha512-pgZos1vgOHDiC7gKNbZW8eKvCnNXARv2oqrGQT7Hzbq5Azp7aZG6DJzADnkuSq7RH6qkXp4J/m68yPX/2uBHyQ==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.1" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + } + } + }, + "tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=" + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "requires": { + "execa": "^0.7.0" + } + }, + "test-exclude": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.1.tgz", + "integrity": "sha512-qpqlP/8Zl+sosLxBcVKl9vYy26T9NPalxSzzCP/OY6K7j938ui2oKgo+kRZYfxAeIpLqpbVnsHq1tyV70E4lWQ==", + "requires": { + "arrify": "^1.0.1", + "micromatch": "^3.1.8", + "object-assign": "^4.1.0", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "throat": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-3.2.0.tgz", + "integrity": "sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w==" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "ua-parser-js": { + "version": "0.7.18", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz", + "integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA==" + }, + "uglify-js": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.2.tgz", + "integrity": "sha512-/kVQDzwiE9Vy7Y63eMkMozF4jIt0C2+xHctF9YpqNWdE/NLOuMurshkpoYGUlAbeYhACPv0HJPIHJul0Ak4/uw==", + "requires": { + "commander": "~2.15.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "requires": { + "source-map": "^0.5.6", + "uglify-js": "^2.8.29", + "webpack-sources": "^1.0.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + } + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==" + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urijs": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.1.tgz", + "integrity": "sha512-xVrGVi94ueCJNrBSTjWqjvtgvl3cyOTThp2zaMaFNGp3F542TR6sM3f2o8RqZl+AwteClSVmoCyt0ka4RjQOQg==" + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, + "url-loader": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz", + "integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==", + "requires": { + "loader-utils": "^1.0.2", + "mime": "^1.4.1", + "schema-utils": "^0.3.0" + } + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "^1.0.1" + } + }, + "use": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "requires": { + "kind-of": "^6.0.2" + } + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vendors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", + "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "requires": { + "indexof": "0.0.1" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "requires": { + "makeerror": "1.0.x" + } + }, + "watch": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.10.0.tgz", + "integrity": "sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw=" + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "webpack": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.8.1.tgz", + "integrity": "sha512-5ZXLWWsMqHKFr5y0N3Eo5IIisxeEeRAajNq4mELb/WELOR7srdbQk2N5XiyNy2A/AgvlR3AmeBCZJW8lHrolbw==", + "requires": { + "acorn": "^5.0.0", + "acorn-dynamic-import": "^2.0.0", + "ajv": "^5.1.5", + "ajv-keywords": "^2.0.0", + "async": "^2.1.2", + "enhanced-resolve": "^3.4.0", + "escope": "^3.6.0", + "interpret": "^1.0.0", + "json-loader": "^0.5.4", + "json5": "^0.5.1", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "mkdirp": "~0.5.0", + "node-libs-browser": "^2.0.0", + "source-map": "^0.5.3", + "supports-color": "^4.2.1", + "tapable": "^0.2.7", + "uglifyjs-webpack-plugin": "^0.4.6", + "watchpack": "^1.4.0", + "webpack-sources": "^1.0.1", + "yargs": "^8.0.2" + }, + "dependencies": { + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=" + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "^2.0.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "requires": { + "has-flag": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "webpack-manifest-plugin": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-1.3.2.tgz", + "integrity": "sha512-MX60Bv2G83Zks9pi3oLOmRgnPAnwrlMn+lftMrWBm199VQjk46/xgzBi9lPfpZldw2+EI2S+OevuLIaDuxCWRw==", + "requires": { + "fs-extra": "^0.30.0", + "lodash": ">=3.5 <5" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + } + } + }, + "webpack-sources": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "whatwg-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "requires": { + "iconv-lite": "0.4.19" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + } + } + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + }, + "whatwg-url": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", + "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + } + } + }, + "whet.extend": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "widest-line": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz", + "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=", + "requires": { + "string-width": "^2.1.1" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "worker-farm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", + "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + }, + "xml-name-validator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", + "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "requires": { + "camelcase": "^3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + } + } + } + } +} diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/package.json b/spring-security-react/src/main/webapp/WEB-INF/view/react/package.json new file mode 100644 index 0000000000..859d9a6f83 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/package.json @@ -0,0 +1,20 @@ +{ + "name": "react", + "version": "0.1.0", + "private": true, + "dependencies": { + "prop-types": "^15.6.2", + "react": "^16.4.1", + "react-dom": "^16.4.1", + "react-scripts": "1.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + }, + "devDependencies": { + "eslint-plugin-react": "^7.9.1" + } +} diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/public/favicon.ico b/spring-security-react/src/main/webapp/WEB-INF/view/react/public/favicon.ico new file mode 100644 index 0000000000..a11777cc47 Binary files /dev/null and b/spring-security-react/src/main/webapp/WEB-INF/view/react/public/favicon.ico differ diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/public/index.html b/spring-security-react/src/main/webapp/WEB-INF/view/react/public/index.html new file mode 100644 index 0000000000..0c3f78d7b3 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/public/index.html @@ -0,0 +1,30 @@ + + + + + + + + + + Spring Login - React App + + + + +
    +
    +
    + + + diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/public/manifest.json b/spring-security-react/src/main/webapp/WEB-INF/view/react/public/manifest.json new file mode 100644 index 0000000000..ef19ec243e --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": "./index.html", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/src/Form.js b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/Form.js new file mode 100644 index 0000000000..0fded264ac --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/Form.js @@ -0,0 +1,81 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Input from './Input' + +class Form extends Component { + + constructor(props){ + super(props) + if(props.error){ + this.state = { failure: 'wrong username or password!', errcount: 0 } + }else{ + this.state = { errcount: 0 } + } + } + + handleSubmit = (event) => { + event.preventDefault() + if(!this.state.errcount) { + const data = new FormData(this.form) + fetch(this.form.action, { + method: this.form.method, + body: new URLSearchParams(data) + }).then(v => { + if(v.redirected) window.location = v.url + }) + .catch(e => console.warn(e)) + } + } + + handleError = (field, errmsg) => { + if(!field) return + + if(errmsg){ + this.setState((prevState) => ({ + failure: '', + errcount: prevState.errcount + 1, + errmsgs: {...prevState.errmsgs, [field]: errmsg} + })) + } else { + this.setState((prevState) => ({ + failure: '', + errcount: prevState.errcount===1? 0 : prevState.errcount-1, + errmsgs: {...prevState.errmsgs, [field]: ''} + })) + } + } + + renderError = () => { + if(this.state.errcount || this.state.failure) { + const errmsg = this.state.failure || Object.values(this.state.errmsgs).find(v=>v) + console.log(`error: ${errmsg}`) + return
    {errmsg}
    + } + } + + render() { + const inputs = this.props.inputs.map( + ({name, placeholder, type, value, className}, index) => ( + + ) + ) + const errors = this.renderError() + return ( +
    {this.form=fm}} > + {inputs} + {errors} +
    + ) + } +} + +Form.propTypes = { + name: PropTypes.string, + action: PropTypes.string, + method: PropTypes.string, + inputs: PropTypes.array, + error: PropTypes.string +} + +export default Form \ No newline at end of file diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/src/Input.js b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/Input.js new file mode 100644 index 0000000000..caa2f2a499 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/Input.js @@ -0,0 +1,57 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +class Input extends Component { + + constructor(props){ + super(props) + this.state = { + value: props.value? props.value : '', + className: props.className? props.className : '', + error: false + } + } + + inputChange = (event) => { + const value = event.target.value, name = event.target.name + //switch(name) { + // case 'username': this.validate(name, value, /^([a-zA-Z0-9.]{4,})$/, 'invalid username') + // break; + // case 'password': this.validate(name, value, /^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,}$/, 'insecure password') + // break; + // default: + // console.warn(`unknown field ${name}`) + //} + this.setState({ value: value }) + } + + validate = (name, value, validRegex, warnmsg) => { + const invalid = !value || !validRegex.test(value) + if(!this.state.error && invalid) { + this.setState({ className: 'input-error', error: true }) + this.handleError(name, warnmsg) + }else if(this.state.error && !invalid) { + this.setState({ className: '', error: false }) + this.handleError(name) + } + } + + render (){ + const {handleError, ...opts} = this.props + this.handleError = handleError + return ( + + ) + } +} + +Input.propTypes = { + name: PropTypes.string, + placeholder: PropTypes.string, + type: PropTypes.string, + className: PropTypes.string, + handleError: PropTypes.func, + value: PropTypes.string +} + +export default Input diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/src/index.css b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/index.css new file mode 100644 index 0000000000..c840272252 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/index.css @@ -0,0 +1,61 @@ +body { + font-family: "Open Sans", "Roboto", arial, sans-serif; + background: #e9e9e9; +} + +#root { + position: absolute; + top: 50%; + right: 0; + left: 0; + margin-right: auto; + margin-left: auto; + transform: translateY(-50%); + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 110%; + border-radius: .19rem; + box-shadow: 0px .19rem .41rem rgba(0,0,0,.25); +} + +form { + height: 100%; + padding: 1.5rem; + background: #fafafa; +} + +input { + background-color: transparent; + border-top: 0; + border-right: 0; + border-left: 0; + border-radius: 0; + color: #111; + font-size: 1rem; + padding: .3rem .5rem; + margin-bottom: 1rem; + display: block; +} + +.input-error { + border-color: #FF0000; +} + +.error { + color: #FF0000; + padding: .2rem; +} + +.btn { + padding: .5rem 1.5rem; + font-size: .85rem; + font-weight: 600; + text-transform: uppercase; + color: #fff; + background: #111; + border-radius: .25rem; + margin: 0; +} diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/src/index.js b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/index.js new file mode 100644 index 0000000000..4a125c565d --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/index.js @@ -0,0 +1,25 @@ +import React from 'react' +import ReactDOM from 'react-dom' +import './index.css' +import Form from './Form' + +const inputs = [{ + name: "username", + placeholder: "username", + type: "text" +},{ + name: "password", + placeholder: "password", + type: "password" +},{ + type: "submit", + value: "Submit", + className: "btn" +}] + +const props = {name: 'loginForm', method: 'POST', action: '/perform_login', inputs: inputs} + +const params = new URLSearchParams(window.location.search) + +ReactDOM.render(
    , document.getElementById('container')) + diff --git a/spring-security-react/src/main/webapp/WEB-INF/view/react/src/registerServiceWorker.js b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/registerServiceWorker.js new file mode 100644 index 0000000000..a3e6c0cfc1 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/view/react/src/registerServiceWorker.js @@ -0,0 +1,117 @@ +// In production, we register a service worker to serve assets from local cache. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on the "N+1" visit to a page, since previously +// cached resources are updated in the background. + +// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. +// This link also includes instructions on opting out of this behavior. + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +export default function register() { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Lets check if a service worker still exists or not. + checkValidServiceWorker(swUrl); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://goo.gl/SC7cgQ' + ); + }); + } else { + // Is not local host. Just register service worker + registerValidSW(swUrl); + } + }); + } +} + +function registerValidSW(swUrl) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and + // the fresh content will have been added to the cache. + // It's the perfect time to display a "New content is + // available; please refresh." message in your web app. + console.log('New content is available; please refresh.'); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + } + } + }; + }; + }) + .catch(error => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + if ( + response.status === 404 || + response.headers.get('content-type').indexOf('javascript') === -1 + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(registration => { + registration.unregister(); + }); + } +} diff --git a/spring-security-react/src/main/webapp/WEB-INF/web.xml b/spring-security-react/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..eef48ec9b3 --- /dev/null +++ b/spring-security-react/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,57 @@ + + + + Spring MVC Application + + + + contextClass + + org.springframework.web.context.support.AnnotationConfigWebApplicationContext + + + + contextConfigLocation + org.baeldung.spring + + + + org.springframework.web.context.ContextLoaderListener + + + + + mvc + org.springframework.web.servlet.DispatcherServlet + 1 + + + mvc + / + + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + springSecurityFilterChain + /* + + + + 403 + /accessDenied + + + + + + + + + \ No newline at end of file diff --git a/spring-security-react/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-react/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..a921976fc3 --- /dev/null +++ b/spring-security-react/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.baeldung.spring.MvcConfig; +import org.baeldung.spring.SecSecurityConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { MvcConfig.class, SecSecurityConfig.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-rest-basic-auth/pom.xml b/spring-security-rest-basic-auth/pom.xml index a30b783842..61a144db0c 100644 --- a/spring-security-rest-basic-auth/pom.xml +++ b/spring-security-rest-basic-auth/pom.xml @@ -1,19 +1,19 @@ + 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 spring-security-rest-basic-auth 0.2-SNAPSHOT - spring-security-rest-basic-auth war - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 + @@ -22,12 +22,12 @@ org.springframework.security spring-security-web - ${org.springframework.security.version} + ${spring.version} org.springframework.security spring-security-config - ${org.springframework.security.version} + ${spring.version} @@ -96,7 +96,7 @@ com.fasterxml.jackson.core jackson-databind - ${jackson.version} + ${jackson-databind.version} @@ -270,33 +270,21 @@ - - 4.2.6.RELEASE - - - 5.2.5.Final - 5.1.40 4.4.5 4.5.3 - 5.3.3.Final 1.2 3.1.0 - 2.8.5 19.0 - 3.5 - - 2.9.0 2.6 1.6.1 - \ No newline at end of file diff --git a/spring-security-rest-basic-auth/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java b/spring-security-rest-basic-auth/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java index 2ff0e30f94..7ca2a80c52 100644 --- a/spring-security-rest-basic-auth/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java +++ b/spring-security-rest-basic-auth/src/main/java/org/baeldung/filter/CustomWebSecurityConfigurerAdapter.java @@ -2,11 +2,14 @@ package org.baeldung.filter; import org.baeldung.security.RestAuthenticationEntryPoint; 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.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; @Configuration @@ -20,7 +23,7 @@ public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAda auth .inMemoryAuthentication() .withUser("user1") - .password("user1Pass") + .password(passwordEncoder().encode("user1Pass")) .authorities("ROLE_USER"); } @@ -38,4 +41,9 @@ public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAda http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } } diff --git a/spring-security-rest-basic-auth/src/main/java/org/baeldung/spring/WebConfig.java b/spring-security-rest-basic-auth/src/main/java/org/baeldung/spring/WebConfig.java index 8c3d677af6..2305a7b6c2 100644 --- a/spring-security-rest-basic-auth/src/main/java/org/baeldung/spring/WebConfig.java +++ b/spring-security-rest-basic-auth/src/main/java/org/baeldung/spring/WebConfig.java @@ -7,12 +7,13 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration @EnableWebMvc @ComponentScan("org.baeldung.web") -public class WebConfig extends WebMvcConfigurerAdapter { +public class WebConfig implements WebMvcConfigurer { public WebConfig() { super(); @@ -22,7 +23,6 @@ public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(final List> converters) { - super.configureMessageConverters(converters); converters.add(new MappingJackson2HttpMessageConverter()); } diff --git a/spring-security-rest-basic-auth/src/main/resources/logback.xml b/spring-security-rest-basic-auth/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-rest-basic-auth/src/main/resources/logback.xml +++ b/spring-security-rest-basic-auth/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-rest-basic-auth/src/main/resources/webSecurityConfig.xml b/spring-security-rest-basic-auth/src/main/resources/webSecurityConfig.xml index 6dea965d8b..a93dc841b6 100644 --- a/spring-security-rest-basic-auth/src/main/resources/webSecurityConfig.xml +++ b/spring-security-rest-basic-auth/src/main/resources/webSecurityConfig.xml @@ -2,25 +2,27 @@ - + - + + + \ No newline at end of file diff --git a/spring-security-rest-basic-auth/src/main/webapp/WEB-INF/api-servlet.xml b/spring-security-rest-basic-auth/src/main/webapp/WEB-INF/api-servlet.xml index 4ba9642448..1dbff70b83 100644 --- a/spring-security-rest-basic-auth/src/main/webapp/WEB-INF/api-servlet.xml +++ b/spring-security-rest-basic-auth/src/main/webapp/WEB-INF/api-servlet.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > \ No newline at end of file diff --git a/spring-security-rest-basic-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-rest-basic-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..6cf624c179 --- /dev/null +++ b/spring-security-rest-basic-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/WebSecurityConfig.xml" }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java b/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java index c27e306c08..104129b663 100644 --- a/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java +++ b/spring-security-rest-basic-auth/src/test/java/org/baeldung/client/RestClientLiveManualTest.java @@ -8,6 +8,9 @@ import java.io.IOException; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLPeerUnverifiedException; + import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; @@ -16,6 +19,7 @@ import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; import org.junit.Ignore; import org.junit.Test; diff --git a/spring-security-rest-custom/pom.xml b/spring-security-rest-custom/pom.xml index 1ee324bcdb..66ad087bf6 100644 --- a/spring-security-rest-custom/pom.xml +++ b/spring-security-rest-custom/pom.xml @@ -1,10 +1,10 @@ + 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 spring-security-rest-custom 0.1-SNAPSHOT - spring-security-rest-custom war @@ -201,8 +201,6 @@ 19.0 3.5 1.2 - 4.4.5 - 4.5.2 1.6.1 diff --git a/spring-security-rest-custom/src/main/resources/logback.xml b/spring-security-rest-custom/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-rest-custom/src/main/resources/logback.xml +++ b/spring-security-rest-custom/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-rest/pom.xml b/spring-security-rest/pom.xml index e6721c9fc7..57ce5ddb92 100644 --- a/spring-security-rest/pom.xml +++ b/spring-security-rest/pom.xml @@ -1,19 +1,19 @@ + 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 spring-security-rest 0.1-SNAPSHOT - spring-security-rest war - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + @@ -275,24 +275,17 @@ - - 4.2.6.RELEASE 0.21.0.RELEASE - - 5.2.5.Final - 5.1.40 - - 5.3.3.Final 3.1.0 1.1.0.Final 1.2 @@ -307,17 +300,11 @@ 2.9.0 - 2.7.0 - - 4.4.5 - 4.5.2 - - 2.9.0 + 2.9.2 2.6 1.6.1 - diff --git a/spring-security-rest/src/main/resources/logback.xml b/spring-security-rest/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-security-rest/src/main/resources/logback.xml +++ b/spring-security-rest/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-security-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..e2e9f2af2b --- /dev/null +++ b/spring-security-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import org.baeldung.spring.ClientWebConfig; +import org.baeldung.spring.SecurityJavaConfig; +import org.baeldung.spring.WebConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { ClientWebConfig.class, SecurityJavaConfig.class, WebConfig.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-sso/pom.xml b/spring-security-sso/pom.xml index f68b9addac..764e899640 100644 --- a/spring-security-sso/pom.xml +++ b/spring-security-sso/pom.xml @@ -9,10 +9,10 @@ pom - parent-boot-1 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-1 + ../parent-boot-2 @@ -22,7 +22,9 @@ - 3.0.1 - - + 3.1.0 + 2.3.3.RELEASE + 2.0.1.RELEASE + + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/pom.xml b/spring-security-sso/spring-security-sso-auth-server/pom.xml index 0d0086beb0..1d57248b30 100644 --- a/spring-security-sso/spring-security-sso-auth-server/pom.xml +++ b/spring-security-sso/spring-security-sso-auth-server/pom.xml @@ -1,7 +1,8 @@ - + 4.0.0 + spring-security-sso-auth-server - spring-security-sso-auth-server war @@ -21,6 +22,7 @@ org.springframework.security.oauth spring-security-oauth2 + ${oauth.version} diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java index 20cde21073..07057c3875 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java @@ -2,19 +2,20 @@ package org.baeldung.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; -import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; + @Configuration @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { - @Autowired - private AuthenticationManager authenticationManager; - + + @Autowired + private BCryptPasswordEncoder passwordEncoder; + @Override public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.tokenKeyAccess("permitAll()") @@ -25,17 +26,14 @@ public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("SampleClientId") - .secret("secret") + .secret(passwordEncoder.encode("secret")) .authorizedGrantTypes("authorization_code") .scopes("user_info") .autoApprove(true) + .redirectUris("http://localhost:8082/ui/login","http://localhost:8083/ui2/login","http://localhost:8082/login") // .accessTokenValiditySeconds(3600) ; // 1 hour } - @Override - public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception { - endpoints.authenticationManager(authenticationManager); - } } diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java index 5b0b39b444..b74d2f144c 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; @SpringBootApplication diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java index a568c22eec..5cebf4f4d2 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java @@ -1,18 +1,17 @@ package org.baeldung.config; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.core.annotation.Order; 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.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @Configuration +@Order(1) public class SecurityConfig extends WebSecurityConfigurerAdapter { - - @Autowired - private AuthenticationManager authenticationManager; - + @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http.requestMatchers() @@ -28,11 +27,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off - auth.parentAuthenticationManager(authenticationManager) - .inMemoryAuthentication() + auth.inMemoryAuthentication() .withUser("john") - .password("123") + .password(passwordEncoder().encode("123")) .roles("USER"); } // @formatter:on + @Bean + public BCryptPasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } } diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties index 32a0993b04..066123118f 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties @@ -1,4 +1,3 @@ server.port=8081 -server.context-path=/auth -security.basic.enabled=false +server.servlet.context-path=/auth #logging.level.org.springframework=DEBUG \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/resources/logback.xml b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/test/AuthServerIntegrationTest.java b/spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 88% rename from spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/test/AuthServerIntegrationTest.java rename to spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 9e2d6feca1..66ee232b10 100644 --- a/spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/test/AuthServerIntegrationTest.java +++ b/spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.test; +package org.baeldung; import org.baeldung.config.AuthorizationServerApplication; import org.junit.Test; @@ -9,7 +9,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = AuthorizationServerApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) -public class AuthServerIntegrationTest { +public class SpringContextIntegrationTest { @Test public void whenLoadApplication_thenSuccess() { diff --git a/spring-security-sso/spring-security-sso-ui-2/pom.xml b/spring-security-sso/spring-security-sso-ui-2/pom.xml index a2323a044d..afe7b59822 100644 --- a/spring-security-sso/spring-security-sso-ui-2/pom.xml +++ b/spring-security-sso/spring-security-sso-ui-2/pom.xml @@ -1,8 +1,8 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - spring-security-sso-ui-2 + spring-security-sso-ui-2 spring-security-sso-ui-2 war @@ -25,8 +25,9 @@ - org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${oauth-auto.version} diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java index a222224c59..0c20853aed 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.web.context.request.RequestContextListener; diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java index f9119e20f5..de81ada9e0 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + @EnableOAuth2Sso @Configuration public class UiSecurityConfig extends WebSecurityConfigurerAdapter { diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml index 6b0d3db5ad..97c8de7839 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml @@ -1,6 +1,7 @@ server: port: 8083 - context-path: /ui2 + servlet: + context-path: /ui2 session: cookie: name: UI2SESSION diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/logback.xml b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/test/UiIntegrationTest.java b/spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 88% rename from spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/test/UiIntegrationTest.java rename to spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 6386eac0b8..2fb0210929 100644 --- a/spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/test/UiIntegrationTest.java +++ b/spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.test; +package org.baeldung; import org.baeldung.config.UiApplication; import org.junit.Test; @@ -9,7 +9,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = UiApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) -public class UiIntegrationTest { +public class SpringContextIntegrationTest { @Test public void whenLoadApplication_thenSuccess() { diff --git a/spring-security-sso/spring-security-sso-ui/pom.xml b/spring-security-sso/spring-security-sso-ui/pom.xml index dbb167b61c..deb0e081be 100644 --- a/spring-security-sso/spring-security-sso-ui/pom.xml +++ b/spring-security-sso/spring-security-sso-ui/pom.xml @@ -1,8 +1,8 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - spring-security-sso-ui + spring-security-sso-ui spring-security-sso-ui war @@ -23,11 +23,13 @@ org.springframework.boot spring-boot-starter-security - + - org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure + ${oauth-auto.version} + org.springframework.boot diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java index e186046e83..07d875d805 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java +++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java @@ -2,7 +2,7 @@ package org.baeldung.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.web.context.request.RequestContextListener; diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java index f9119e20f5..de81ada9e0 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java +++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + @EnableOAuth2Sso @Configuration public class UiSecurityConfig extends WebSecurityConfigurerAdapter { diff --git a/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml b/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml index bb4bd92033..d1d9ea6ebc 100644 --- a/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml +++ b/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml @@ -1,6 +1,7 @@ server: port: 8082 - context-path: /ui + servlet: + context-path: /ui session: cookie: name: UISESSION diff --git a/spring-security-sso/spring-security-sso-ui/src/main/resources/logback.xml b/spring-security-sso/spring-security-sso-ui/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/test/UiIntegrationTest.java b/spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 88% rename from spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/test/UiIntegrationTest.java rename to spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 6386eac0b8..2fb0210929 100644 --- a/spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/test/UiIntegrationTest.java +++ b/spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.test; +package org.baeldung; import org.baeldung.config.UiApplication; import org.junit.Test; @@ -9,7 +9,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = UiApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) -public class UiIntegrationTest { +public class SpringContextIntegrationTest { @Test public void whenLoadApplication_thenSuccess() { diff --git a/spring-security-stormpath/pom.xml b/spring-security-stormpath/pom.xml index 71a7123c2c..5c5783eec5 100644 --- a/spring-security-stormpath/pom.xml +++ b/spring-security-stormpath/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung spring-security-stormpath @@ -7,14 +7,6 @@ 1.0-SNAPSHOT spring-security-stormpath http://maven.apache.org - - - parent-boot-1 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-1 - - abhinabkanrar@gmail.com @@ -24,6 +16,13 @@ + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 + + org.springframework.boot @@ -69,10 +68,4 @@ - - UTF-8 - UTF-8 - 1.8 - - diff --git a/spring-security-stormpath/src/main/resources/logback.xml b/spring-security-stormpath/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-stormpath/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-thymeleaf/README.MD b/spring-security-thymeleaf/README.MD index 36007bce62..c5deeb9946 100644 --- a/spring-security-thymeleaf/README.MD +++ b/spring-security-thymeleaf/README.MD @@ -4,3 +4,4 @@ Jira BAEL-1556 ### Relevant Articles: - [Spring Security with Thymeleaf](http://www.baeldung.com/spring-security-thymeleaf) +- [Working with Select and Option in Thymeleaf](http://www.baeldung.com/thymeleaf-select-option) diff --git a/spring-security-thymeleaf/pom.xml b/spring-security-thymeleaf/pom.xml index 28d6126b55..5b7715bdeb 100644 --- a/spring-security-thymeleaf/pom.xml +++ b/spring-security-thymeleaf/pom.xml @@ -1,7 +1,8 @@ + 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 spring-security-thymeleaf 0.0.1-SNAPSHOT @@ -55,10 +56,4 @@ - - UTF-8 - UTF-8 - 1.8 - - diff --git a/spring-security-thymeleaf/src/main/resources/logback.xml b/spring-security-thymeleaf/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-thymeleaf/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-x509/keystore/Makefile b/spring-security-x509/keystore/Makefile index 5321be9de3..63498fea76 100644 --- a/spring-security-x509/keystore/Makefile +++ b/spring-security-x509/keystore/Makefile @@ -85,4 +85,4 @@ add-client: clean: # Remove generated artifacts - find . ! -name Makefile -type f -exec rm -f {} \; + find . \( -name "$(CLIENTNAME)*" -o -name "$(HOSTNAME)*" -o -name "$(KEYSTORE)" -o -name "$(TRUSTSTORE)" -o -name ca.crt \) -type f -exec rm -f {} \; diff --git a/spring-security-x509/pom.xml b/spring-security-x509/pom.xml index d6a4b5693b..0cee3b3129 100644 --- a/spring-security-x509/pom.xml +++ b/spring-security-x509/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung spring-security-x509 diff --git a/spring-security-x509/spring-security-x509-basic-auth/pom.xml b/spring-security-x509/spring-security-x509-basic-auth/pom.xml index 56600302e0..67f2b4fbcd 100644 --- a/spring-security-x509/spring-security-x509-basic-auth/pom.xml +++ b/spring-security-x509/spring-security-x509-basic-auth/pom.xml @@ -1,14 +1,12 @@ - + 4.0.0 - basic-secured-server + spring-security-x509-basic-auth 0.0.1-SNAPSHOT jar - - basic-secured-server + Spring Security x.509 Basic Authentication Spring x.509 Authentication Demo diff --git a/spring-security-x509/spring-security-x509-basic-auth/src/main/resources/logback.xml b/spring-security-x509/spring-security-x509-basic-auth/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-x509/spring-security-x509-basic-auth/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-x509/spring-security-x509-basic-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-x509/spring-security-x509-basic-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7ec6125f84 --- /dev/null +++ b/spring-security-x509/spring-security-x509-basic-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.security.x509.X509AuthenticationServer; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = X509AuthenticationServer.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-x509/spring-security-x509-client-auth/pom.xml b/spring-security-x509/spring-security-x509-client-auth/pom.xml index ea5521c93d..5cb4001a94 100644 --- a/spring-security-x509/spring-security-x509-client-auth/pom.xml +++ b/spring-security-x509/spring-security-x509-client-auth/pom.xml @@ -1,14 +1,12 @@ - + 4.0.0 - client-auth-server + spring-security-x509-client-auth 0.0.1-SNAPSHOT jar - - client-auth-server + Spring Security x.509 Client Authentication Spring x.509 Client Authentication Demo diff --git a/spring-security-x509/spring-security-x509-client-auth/src/main/resources/logback.xml b/spring-security-x509/spring-security-x509-client-auth/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-security-x509/spring-security-x509-client-auth/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-security-x509/spring-security-x509-client-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-x509/spring-security-x509-client-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..7ec6125f84 --- /dev/null +++ b/spring-security-x509/spring-security-x509-client-auth/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.security.x509.X509AuthenticationServer; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = X509AuthenticationServer.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-session/README.md b/spring-session/README.md index 0d802a4715..30f70996cf 100644 --- a/spring-session/README.md +++ b/spring-session/README.md @@ -4,3 +4,4 @@ ### Relevant Articles: - [Introduction to Spring Session](http://www.baeldung.com/spring-session) +- [Spring Session with JDBC](http://www.baeldung.com/spring-session-jdbc) diff --git a/spring-session/pom.xml b/spring-session/pom.xml index 4c256663b0..28dde40272 100644 --- a/spring-session/pom.xml +++ b/spring-session/pom.xml @@ -1,10 +1,12 @@ - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + org.baeldung spring-session 1.0.0-SNAPSHOT - jar + + spring-session + pom parent-boot-1 @@ -13,23 +15,9 @@ ../parent-boot-1 - - - org.springframework.boot - spring-boot-starter-data-redis - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.session - spring-session - - - org.springframework.boot - spring-boot-starter-web - - + + spring-session-jdbc + spring-session-redis + \ No newline at end of file diff --git a/spring-session/spring-session-jdbc/README.MD b/spring-session/spring-session-jdbc/README.MD new file mode 100644 index 0000000000..9293dfc953 --- /dev/null +++ b/spring-session/spring-session-jdbc/README.MD @@ -0,0 +1,6 @@ +This module is for Spring Session with JDBC tutorial. +Jira BAEL-1911 + +### Relevant Articles: + +- [Spring Session with JDBC](http://www.baeldung.com/spring-session-jdbc) diff --git a/spring-session/spring-session-jdbc/pom.xml b/spring-session/spring-session-jdbc/pom.xml new file mode 100644 index 0000000000..ce6b5f5908 --- /dev/null +++ b/spring-session/spring-session-jdbc/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + com.baeldung + spring-session-jdbc + 0.0.1-SNAPSHOT + jar + spring-session-jdbc + Spring Session with JDBC tutorial + + + 1.4.197 + + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.session + spring-session-jdbc + + + com.h2database + h2 + ${h2.version} + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + \ No newline at end of file diff --git a/spring-session/spring-session-jdbc/src/main/java/com/baeldung/springsessionjdbc/SpringSessionJdbcApplication.java b/spring-session/spring-session-jdbc/src/main/java/com/baeldung/springsessionjdbc/SpringSessionJdbcApplication.java new file mode 100644 index 0000000000..a3bc17aa49 --- /dev/null +++ b/spring-session/spring-session-jdbc/src/main/java/com/baeldung/springsessionjdbc/SpringSessionJdbcApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.springsessionjdbc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringSessionJdbcApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringSessionJdbcApplication.class, args); + } +} diff --git a/spring-session/spring-session-jdbc/src/main/java/com/baeldung/springsessionjdbc/controller/SpringSessionJdbcController.java b/spring-session/spring-session-jdbc/src/main/java/com/baeldung/springsessionjdbc/controller/SpringSessionJdbcController.java new file mode 100644 index 0000000000..509a5f292b --- /dev/null +++ b/spring-session/spring-session-jdbc/src/main/java/com/baeldung/springsessionjdbc/controller/SpringSessionJdbcController.java @@ -0,0 +1,45 @@ +package com.baeldung.springsessionjdbc.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.ArrayList; +import java.util.List; + +@Controller +public class SpringSessionJdbcController { + + @GetMapping("/") + public String index(Model model, HttpSession session) { + List favoriteColors = getFavColors(session); + model.addAttribute("favoriteColors", favoriteColors); + model.addAttribute("sessionId", session.getId()); + return "index"; + } + + @PostMapping("/saveColor") + public String saveMessage(@RequestParam("color") String color, HttpServletRequest request) { + List favoriteColors = getFavColors(request.getSession()); + if (!StringUtils.isEmpty(color)) { + favoriteColors.add(color); + request + .getSession() + .setAttribute("favoriteColors", favoriteColors); + } + return "redirect:/"; + } + + private List getFavColors(HttpSession session) { + List favoriteColors = (List) session.getAttribute("favoriteColors"); + if (favoriteColors == null) { + favoriteColors = new ArrayList<>(); + } + return favoriteColors; + } +} diff --git a/spring-session/spring-session-jdbc/src/main/resources/application.properties b/spring-session/spring-session-jdbc/src/main/resources/application.properties new file mode 100644 index 0000000000..119638de31 --- /dev/null +++ b/spring-session/spring-session-jdbc/src/main/resources/application.properties @@ -0,0 +1,3 @@ +spring.session.store-type=jdbc +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console \ No newline at end of file diff --git a/spring-session/spring-session-jdbc/src/main/resources/logback.xml b/spring-session/spring-session-jdbc/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-session/spring-session-jdbc/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-session/spring-session-jdbc/src/test/java/com/baeldung/springsessionjdbc/SpringSessionJdbcIntegrationTest.java b/spring-session/spring-session-jdbc/src/test/java/com/baeldung/springsessionjdbc/SpringSessionJdbcIntegrationTest.java new file mode 100644 index 0000000000..2dcc0b3af8 --- /dev/null +++ b/spring-session/spring-session-jdbc/src/test/java/com/baeldung/springsessionjdbc/SpringSessionJdbcIntegrationTest.java @@ -0,0 +1,91 @@ +package com.baeldung.springsessionjdbc; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class SpringSessionJdbcIntegrationTest { + + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Before + public void setup() throws ClassNotFoundException { + Class.forName("org.h2.Driver"); + } + + @Test + public void givenApiHasStarted_whenH2DbIsQueried_thenSessionTablesAreEmpty() throws SQLException { + Assert.assertEquals(0, getSessionIdsFromDatabase().size()); + Assert.assertEquals(0, getSessionAttributeBytesFromDatabase().size()); + } + + @Test + public void givenGetInvoked_whenH2DbIsQueried_thenOneSessionIsCreated() throws SQLException { + assertThat(this.testRestTemplate.getForObject("http://localhost:" + port + "/", String.class)).isNotEmpty(); + Assert.assertEquals(1, getSessionIdsFromDatabase().size()); + } + + @Test + public void givenPostInvoked_whenH2DbIsQueried_thenSessionAttributeIsRetrieved() throws ClassNotFoundException, SQLException, IOException { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("color", "red"); + this.testRestTemplate.postForObject("http://localhost:" + port + "/saveColor", map, String.class); + List queryResponse = getSessionAttributeBytesFromDatabase(); + Assert.assertEquals(1, queryResponse.size()); + ObjectInput in = new ObjectInputStream(new ByteArrayInputStream(queryResponse.get(0))); + List obj = (List) in.readObject(); //Deserialize byte[] to object + Assert.assertEquals("red", obj.get(0)); + } + + private List getSessionIdsFromDatabase() throws SQLException { + List result = new ArrayList<>(); + ResultSet rs = getResultSet("SELECT * FROM SPRING_SESSION"); + while (rs.next()) { + result.add(rs.getString("SESSION_ID")); + } + return result; + } + + private List getSessionAttributeBytesFromDatabase() throws SQLException { + List result = new ArrayList<>(); + ResultSet rs = getResultSet("SELECT * FROM SPRING_SESSION_ATTRIBUTES"); + while (rs.next()) { + result.add(rs.getBytes("ATTRIBUTE_BYTES")); + } + return result; + } + + private ResultSet getResultSet(String sql) throws SQLException { + Connection conn = DriverManager.getConnection("jdbc:h2:mem:testdb", "sa", ""); + Statement stat = conn.createStatement(); + return stat.executeQuery(sql); + } + +} diff --git a/spring-session/spring-session-jdbc/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-session/spring-session-jdbc/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..b921f76a0d --- /dev/null +++ b/spring-session/spring-session-jdbc/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.springsessionjdbc.SpringSessionJdbcApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringSessionJdbcApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-session/spring-session-redis/README.md b/spring-session/spring-session-redis/README.md new file mode 100644 index 0000000000..0d802a4715 --- /dev/null +++ b/spring-session/spring-session-redis/README.md @@ -0,0 +1,6 @@ +========= + +## Spring Session Examples + +### Relevant Articles: +- [Introduction to Spring Session](http://www.baeldung.com/spring-session) diff --git a/spring-mvc-email/pom.xml b/spring-session/spring-session-redis/pom.xml similarity index 54% rename from spring-mvc-email/pom.xml rename to spring-session/spring-session-redis/pom.xml index 40d83046ef..00da656226 100644 --- a/spring-mvc-email/pom.xml +++ b/spring-session/spring-session-redis/pom.xml @@ -2,39 +2,43 @@ 4.0.0 - - org.baeldung.spring - spring-mvc-email - 1.0 - spring-mvc-email - war + spring-session-redis + 1.0.0-SNAPSHOT + jar parent-boot-1 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-1 + ../../parent-boot-1 + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.session + spring-session + org.springframework.boot spring-boot-starter-web - org.springframework.boot - spring-boot-starter-tomcat - - - - org.springframework.boot - spring-boot-starter-mail - - - - javax.servlet - jstl + com.github.kstyrc + embedded-redis + ${embedded-redis.version} + + + 0.6 + - + \ No newline at end of file diff --git a/spring-session/src/main/java/com/baeldung/spring/session/SecurityConfig.java b/spring-session/spring-session-redis/src/main/java/com/baeldung/spring/session/SecurityConfig.java similarity index 100% rename from spring-session/src/main/java/com/baeldung/spring/session/SecurityConfig.java rename to spring-session/spring-session-redis/src/main/java/com/baeldung/spring/session/SecurityConfig.java diff --git a/spring-session/src/main/java/com/baeldung/spring/session/SessionConfig.java b/spring-session/spring-session-redis/src/main/java/com/baeldung/spring/session/SessionConfig.java similarity index 100% rename from spring-session/src/main/java/com/baeldung/spring/session/SessionConfig.java rename to spring-session/spring-session-redis/src/main/java/com/baeldung/spring/session/SessionConfig.java diff --git a/spring-session/src/main/java/com/baeldung/spring/session/SessionController.java b/spring-session/spring-session-redis/src/main/java/com/baeldung/spring/session/SessionController.java similarity index 100% rename from spring-session/src/main/java/com/baeldung/spring/session/SessionController.java rename to spring-session/spring-session-redis/src/main/java/com/baeldung/spring/session/SessionController.java diff --git a/spring-session/src/main/java/com/baeldung/spring/session/SessionWebApplication.java b/spring-session/spring-session-redis/src/main/java/com/baeldung/spring/session/SessionWebApplication.java similarity index 100% rename from spring-session/src/main/java/com/baeldung/spring/session/SessionWebApplication.java rename to spring-session/spring-session-redis/src/main/java/com/baeldung/spring/session/SessionWebApplication.java diff --git a/spring-session/spring-session-redis/src/main/resources/application.properties b/spring-session/spring-session-redis/src/main/resources/application.properties new file mode 100644 index 0000000000..49886b3b70 --- /dev/null +++ b/spring-session/spring-session-redis/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.redis.host=localhost +spring.redis.port=6379 \ No newline at end of file diff --git a/spring-session/spring-session-redis/src/main/resources/logback.xml b/spring-session/spring-session-redis/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-session/spring-session-redis/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java b/spring-session/spring-session-redis/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java similarity index 67% rename from spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java rename to spring-session/spring-session-redis/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java index 84dd2bc139..f739aeb3ab 100644 --- a/spring-session/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java +++ b/spring-session/spring-session-redis/src/test/java/com/baeldung/spring/session/SessionControllerIntegrationTest.java @@ -1,27 +1,55 @@ package com.baeldung.spring.session; -import org.junit.Before; -import org.junit.Test; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; -import redis.clients.jedis.Jedis; - -import java.util.Set; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.util.Set; + +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import redis.clients.jedis.Jedis; +import redis.embedded.RedisServer; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SessionWebApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) public class SessionControllerIntegrationTest { private Jedis jedis; + private static RedisServer redisServer; private TestRestTemplate testRestTemplate; private TestRestTemplate testRestTemplateWithAuth; private String testUrl = "http://localhost:8080/"; + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new RedisServer(6379); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } + @Before public void clearRedisData() { + testRestTemplate = new TestRestTemplate(); - testRestTemplateWithAuth = new TestRestTemplate("admin", "password", null); + testRestTemplateWithAuth = new TestRestTemplate("admin", "password"); jedis = new Jedis("localhost", 6379); jedis.flushAll(); diff --git a/spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..a62e728826 --- /dev/null +++ b/spring-session/spring-session-redis/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.session.SessionWebApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SessionWebApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-sleuth/pom.xml b/spring-sleuth/pom.xml index 418edeaec7..a9a8d3e96e 100644 --- a/spring-sleuth/pom.xml +++ b/spring-sleuth/pom.xml @@ -1,6 +1,6 @@ + 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 spring-sleuth diff --git a/spring-sleuth/src/main/resources/logback.xml b/spring-sleuth/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-sleuth/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-sleuth/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-sleuth/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..ef722ecba0 --- /dev/null +++ b/spring-sleuth/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.session.SleuthWebApp; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SleuthWebApp.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-social-login/pom.xml b/spring-social-login/pom.xml index d08600a8e4..6b7b90443a 100644 --- a/spring-social-login/pom.xml +++ b/spring-social-login/pom.xml @@ -1,6 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + spring-social-login spring-social-login war diff --git a/spring-social-login/src/main/resources/logback.xml b/spring-social-login/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-social-login/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-social-login/src/test/java/org/baeldung/test/ApplicationIntegrationTest.java b/spring-social-login/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 87% rename from spring-social-login/src/test/java/org/baeldung/test/ApplicationIntegrationTest.java rename to spring-social-login/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 43aaea18b1..29ed401118 100644 --- a/spring-social-login/src/test/java/org/baeldung/test/ApplicationIntegrationTest.java +++ b/spring-social-login/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.test; +package org.baeldung; import org.baeldung.config.Application; import org.junit.Test; @@ -9,7 +9,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT) -public class ApplicationIntegrationTest { +public class SpringContextIntegrationTest { @Test public void whenLoadApplication_thenSuccess() { diff --git a/spring-spel/pom.xml b/spring-spel/pom.xml index 8e805ed6ac..4af318fde2 100644 --- a/spring-spel/pom.xml +++ b/spring-spel/pom.xml @@ -1,10 +1,11 @@ + 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 - spel + spring-spel 1.0-SNAPSHOT + Spring SpEL com.baeldung diff --git a/spring-spel/src/main/resources/logback.xml b/spring-spel/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-spel/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-spel/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-spel/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..f394374a94 --- /dev/null +++ b/spring-spel/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"classpath:applicationContext.xml"}) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-state-machine/pom.xml b/spring-state-machine/pom.xml index 2755b6e45a..5d15e4dfad 100644 --- a/spring-state-machine/pom.xml +++ b/spring-state-machine/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-state-machine diff --git a/spring-state-machine/src/main/resources/logback.xml b/spring-state-machine/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-state-machine/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-state-machine/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-state-machine/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..72292a5089 --- /dev/null +++ b/spring-state-machine/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,23 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.statemachine.config.ForkJoinStateMachineConfiguration; +import com.baeldung.spring.statemachine.config.HierarchicalStateMachineConfiguration; +import com.baeldung.spring.statemachine.config.JunctionStateMachineConfiguration; +import com.baeldung.spring.statemachine.config.SimpleEnumStateMachineConfiguration; +import com.baeldung.spring.statemachine.config.SimpleStateMachineConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { SimpleStateMachineConfiguration.class, SimpleEnumStateMachineConfiguration.class, + JunctionStateMachineConfiguration.class, HierarchicalStateMachineConfiguration.class, + ForkJoinStateMachineConfiguration.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-static-resources/pom.xml b/spring-static-resources/pom.xml index a00d03d2a1..3ca7783682 100644 --- a/spring-static-resources/pom.xml +++ b/spring-static-resources/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung spring-static-resources @@ -11,8 +11,8 @@ com.baeldung parent-spring-5 - 0.0.1-SNAPSHOT - ../parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 @@ -140,7 +140,6 @@ handlebars ${handlebars.version} - @@ -174,9 +173,9 @@ - org.apache.maven.plugins - maven-war-plugin - 3.2.2 + org.apache.maven.plugins + maven-war-plugin + 3.2.2 @@ -189,8 +188,6 @@ - 1.8 - 5.0.6.RELEASE diff --git a/spring-static-resources/src/main/resources/logback.xml b/spring-static-resources/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-static-resources/src/main/resources/logback.xml +++ b/spring-static-resources/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-swagger-codegen/pom.xml b/spring-swagger-codegen/pom.xml index 09b7b61156..8e551d850f 100644 --- a/spring-swagger-codegen/pom.xml +++ b/spring-swagger-codegen/pom.xml @@ -1,7 +1,6 @@ + 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 spring-swagger-codegen 0.0.1-SNAPSHOT pom diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/README.md b/spring-swagger-codegen/spring-swagger-codegen-api-client/README.md index b1b7a63a9c..455a69b2f3 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/README.md +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/README.md @@ -153,3 +153,5 @@ It's recommended to create an instance of `ApiClient` per thread in a multithrea apiteam@swagger.io + + diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml index f0f58b86b8..06a92ffae7 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml @@ -1,26 +1,17 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.baeldung + spring-swagger-codegen-api-client jar spring-swagger-codegen-api-client - 0.0.1-SNAPSHOT https://github.com/swagger-api/swagger-codegen Swagger Java - - com.baeldung - spring-swagger-codegen - 0.0.1-SNAPSHOT - scm:git:git@github.com:swagger-api/swagger-codegen.git scm:git:git@github.com:swagger-api/swagger-codegen.git https://github.com/swagger-api/swagger-codegen - - 2.2.0 - @@ -29,7 +20,6 @@ repo - Swagger @@ -39,44 +29,20 @@ + + com.baeldung + spring-swagger-codegen + 0.0.1-SNAPSHOT + ../../spring-swagger-codegen + + - - org.apache.maven.plugins - maven-surefire-plugin - 2.12 - - - - loggerPath - conf/log4j.properties - - - -Xms512m -Xmx1500m - methods - pertest - - - - maven-dependency-plugin - - - package - - copy-dependencies - - - ${project.build.directory}/lib - - - - - org.apache.maven.plugins maven-jar-plugin - 2.2 + ${maven-jar-plugin.version} @@ -92,7 +58,7 @@ org.codehaus.mojo build-helper-maven-plugin - 1.10 + ${build-helper-maven-plugin.version} add_sources @@ -123,7 +89,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.10.4 + ${maven-javadoc-plugin.version} attach-javadocs @@ -136,7 +102,7 @@ org.apache.maven.plugins maven-source-plugin - 2.2.1 + ${maven-source-plugin.version} attach-sources @@ -157,7 +123,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.5 + ${maven-gpg-plugin.version} sign-artifacts @@ -218,22 +184,17 @@ joda-time ${jodatime-version} - - - - junit - junit - ${junit-version} - test - + - UTF-8 1.5.15 4.3.9.RELEASE 2.8.9 2.9.9 - 1.0.0 - 4.12 + 2.2 + 1.5 + 2.2.1 + 2.10.4 + 1.10 diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/resources/logback.xml b/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml index c9e0f5e27f..4aff696828 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml +++ b/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml @@ -1,41 +1,46 @@ + 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 spring-swagger-codegen-app - 0.0.1-SNAPSHOT - + - org.springframework.boot - spring-boot-starter-parent - 1.5.10.RELEASE + com.baeldung + spring-swagger-codegen + 0.0.1-SNAPSHOT + ../../spring-swagger-codegen com.baeldung spring-swagger-codegen-api-client - 0.0.1-SNAPSHOT + ${spring-swagger-codegen-api-client.version} org.springframework.boot spring-boot-starter-web + ${spring.version} + + + org.springframework.boot + spring-boot-starter-test + ${spring.version} + test - - 1.8 - - - org.springframework.boot spring-boot-maven-plugin + ${spring.version} - \ No newline at end of file + + 0.0.1-SNAPSHOT + 1.5.10.RELEASE + + diff --git a/spring-swagger-codegen/spring-swagger-codegen-app/src/main/resources/logback.xml b/spring-swagger-codegen/spring-swagger-codegen-app/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-swagger-codegen/spring-swagger-codegen-app/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-swagger-codegen/spring-swagger-codegen-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-swagger-codegen/spring-swagger-codegen-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..2143dc7f4d --- /dev/null +++ b/spring-swagger-codegen/spring-swagger-codegen-app/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.petstore.app.PetStoreApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = PetStoreApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-thymeleaf/README.md b/spring-thymeleaf/README.md index 99f46c2f39..f9e7dd90a7 100644 --- a/spring-thymeleaf/README.md +++ b/spring-thymeleaf/README.md @@ -16,6 +16,8 @@ - [Iteration in Thymeleaf](http://www.baeldung.com/thymeleaf-iteration) - [Working With Arrays in Thymeleaf](http://www.baeldung.com/thymeleaf-arrays) - [Spring with Thymeleaf Pagination for a List](http://www.baeldung.com/spring-thymeleaf-pagination) +- [Working with Select and Option in Thymeleaf](http://www.baeldung.com/thymeleaf-select-option) +- [Working With Custom HTML Attributes in Thymeleaf](https://www.baeldung.com/thymeleaf-custom-html-attributes) ### Build the Project diff --git a/spring-thymeleaf/pom.xml b/spring-thymeleaf/pom.xml index 61d41e5f20..0926728aba 100644 --- a/spring-thymeleaf/pom.xml +++ b/spring-thymeleaf/pom.xml @@ -1,5 +1,5 @@ + 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 spring-thymeleaf @@ -8,8 +8,9 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 @@ -17,7 +18,7 @@ org.springframework spring-context - ${org.springframework-version} + ${spring.version} @@ -29,19 +30,38 @@ org.springframework spring-webmvc - ${org.springframework-version} + ${spring.version} + + + org.springframework.data + spring-data-commons + ${spring-data.version} + + + + javax.validation + validation-api + ${javax.validation-version} + + + org.hibernate.validator + hibernate-validator + ${hibernate-validator.version} + + org.springframework.security spring-security-web - ${springframework-security.version} + ${spring-security.version} org.springframework.security spring-security-config - ${springframework-security.version} + ${spring-security.version} + org.thymeleaf @@ -50,10 +70,9 @@ org.thymeleaf - thymeleaf-spring4 + thymeleaf-spring5 ${org.thymeleaf-version} - nz.net.ultraq.thymeleaf thymeleaf-layout-dialect @@ -64,47 +83,30 @@ thymeleaf-extras-java8time ${org.thymeleaf.extras-version} + javax.servlet javax.servlet-api - ${javax.servlet-version} + ${javax.servlet-api.version} provided - - - javax.validation - validation-api - ${javax.validation-version} - - - org.hibernate - hibernate-validator - ${hibernate-validator.version} - - + org.springframework spring-test - ${org.springframework-version} + ${spring.version} test - org.springframework.security spring-security-test - ${springframework-security.version} + ${spring-security.version} test - - - - org.springframework.data - spring-data-commons - ${springFramework-data.version} - + @@ -117,6 +119,7 @@ false + org.codehaus.cargo cargo-maven2-plugin @@ -136,6 +139,7 @@ + org.apache.tomcat.maven tomcat7-maven-plugin @@ -160,23 +164,14 @@ - 1.8 - - 4.3.4.RELEASE - 4.2.0.RELEASE - 2.0.7.RELEASE - 3.1.0 - + 2.0.9.RELEASE 3.0.9.RELEASE - 3.0.0.RELEASE - 2.1.2 - - 1.1.0.Final - 5.3.3.Final - 5.2.5.Final + 3.0.1.RELEASE + 2.3.0 + 2.0.1.Final + 6.0.11.Final - 2.6 1.6.1 2.2 diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/WorkingWithArraysInThymeleafApplication.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/WorkingWithArraysInThymeleafApplication.java new file mode 100644 index 0000000000..bce0660fda --- /dev/null +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/WorkingWithArraysInThymeleafApplication.java @@ -0,0 +1,12 @@ +// package com.baeldung.thymeleaf; + +// import org.springframework.boot.SpringApplication; +// import org.springframework.boot.autoconfigure.SpringBootApplication; + +// @SpringBootApplication +// public class WorkingWithArraysInThymeleafApplication { + +// public static void main(String[] args) { +// SpringApplication.run(WorkingWithArraysInThymeleafApplication.class, args); +// } +// } diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java index 2e76877199..34a59ea391 100644 --- a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java @@ -2,6 +2,9 @@ package com.baeldung.thymeleaf.config; import java.util.Locale; +import nz.net.ultraq.thymeleaf.LayoutDialect; +import nz.net.ultraq.thymeleaf.decorators.strategies.GroupingStrategy; + import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; @@ -15,23 +18,20 @@ import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import org.springframework.web.servlet.i18n.SessionLocaleResolver; -import org.thymeleaf.TemplateEngine; import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect; -import org.thymeleaf.spring4.SpringTemplateEngine; -import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver; -import org.thymeleaf.spring4.view.ThymeleafViewResolver; +import org.thymeleaf.spring5.ISpringTemplateEngine; +import org.thymeleaf.spring5.SpringTemplateEngine; +import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; +import org.thymeleaf.spring5.view.ThymeleafViewResolver; import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templateresolver.ITemplateResolver; import com.baeldung.thymeleaf.formatter.NameFormatter; import com.baeldung.thymeleaf.utils.ArrayUtil; -import nz.net.ultraq.thymeleaf.LayoutDialect; -import nz.net.ultraq.thymeleaf.decorators.strategies.GroupingStrategy; - @Configuration @EnableWebMvc @ComponentScan({ "com.baeldung.thymeleaf" }) @@ -39,10 +39,11 @@ import nz.net.ultraq.thymeleaf.decorators.strategies.GroupingStrategy; * Java configuration file that is used for Spring MVC and Thymeleaf * configurations */ -public class WebMVCConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware { +public class WebMVCConfig implements WebMvcConfigurer, ApplicationContextAware { private ApplicationContext applicationContext; + @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @@ -77,7 +78,7 @@ public class WebMVCConfig extends WebMvcConfigurerAdapter implements Application return resolver; } - private TemplateEngine templateEngine(ITemplateResolver templateResolver) { + private ISpringTemplateEngine templateEngine(ITemplateResolver templateResolver) { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.addDialect(new LayoutDialect(new GroupingStrategy())); engine.addDialect(new Java8TimeDialect()); diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java index 46bff38a3f..ea51ca3cd9 100644 --- a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java @@ -27,7 +27,7 @@ public class WebMVCSecurity extends WebSecurityConfigurerAdapter { @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER"); + auth.inMemoryAuthentication().withUser("user1").password("{noop}user1Pass").authorities("ROLE_USER"); } @Override diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/CourseRegistrationController.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/CourseRegistrationController.java new file mode 100644 index 0000000000..2d2b5906e1 --- /dev/null +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/CourseRegistrationController.java @@ -0,0 +1,30 @@ +package com.baeldung.thymeleaf.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.baeldung.thymeleaf.model.Course; + +/** + * Handles requests for the student model. + * + */ +@Controller +public class CourseRegistrationController { + + @RequestMapping(value = "/registerCourse", method = RequestMethod.POST) + public String register(@ModelAttribute Course course, Model model) { + model.addAttribute("successMessage", "You have successfully registered for course: " + course.getName() + "."); + return "courseRegistration.html"; + } + + @RequestMapping(value = "/registerCourse", method = RequestMethod.GET) + public String register(Model model) { + model.addAttribute("course", new Course()); + return "courseRegistration.html"; + } + +} diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ThymeleafArrayController.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ThymeleafArrayController.java new file mode 100644 index 0000000000..8276cc4376 --- /dev/null +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/ThymeleafArrayController.java @@ -0,0 +1,17 @@ +package com.baeldung.thymeleaf.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class ThymeleafArrayController { + @GetMapping("/arrays") + public String arrayController(Model model) { + String[] continents = {"Africa", "Antarctica", "Asia", "Australia", "Europe", "North America", "Sourth America"}; + + model.addAttribute("continents", continents); + + return "continents"; + } +} diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Course.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Course.java new file mode 100644 index 0000000000..df2e9cd097 --- /dev/null +++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Course.java @@ -0,0 +1,52 @@ +package com.baeldung.thymeleaf.model; + +import java.util.Date; + +public class Course { + + private String name; + private String description; + private Date startDate; + private Date endDate; + private String teacher; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public String getTeacher() { + return teacher; + } + + public void setTeacher(String teacher) { + this.teacher = teacher; + } +} diff --git a/spring-thymeleaf/src/main/resources/logback.xml b/spring-thymeleaf/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/spring-thymeleaf/src/main/resources/logback.xml +++ b/spring-thymeleaf/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/spring-thymeleaf/src/main/resources/templates/continents.html b/spring-thymeleaf/src/main/resources/templates/continents.html new file mode 100644 index 0000000000..0e7ffa3f58 --- /dev/null +++ b/spring-thymeleaf/src/main/resources/templates/continents.html @@ -0,0 +1,49 @@ + + + + Arrays in Thymeleaf + + + + + +

    THE CONTINENTS

    +

    + We have a total of + continents in this world. Following is a list showing their order + based on the number of population in each of them. +

    + +
      +
    1. +
    2. +
    3. +
    4. +
    5. +
    6. +
    7. +
    + +
      +
    • +
    + +

    + +

    + The greatest + continents. +

    + +

    + Europe is a continent: . +

    + +

    + Array of continents is empty . +

    + + + diff --git a/spring-thymeleaf/src/main/webapp/WEB-INF/views/courseRegistration.html b/spring-thymeleaf/src/main/webapp/WEB-INF/views/courseRegistration.html new file mode 100644 index 0000000000..cfce92d055 --- /dev/null +++ b/spring-thymeleaf/src/main/webapp/WEB-INF/views/courseRegistration.html @@ -0,0 +1,42 @@ + + + +Register for course + + + + +

    Register Here

    + + + + + + + + + + +
    + + + diff --git a/spring-thymeleaf/src/main/webapp/WEB-INF/views/home.html b/spring-thymeleaf/src/main/webapp/WEB-INF/views/home.html index b458f7270c..25ff6a19bb 100644 --- a/spring-thymeleaf/src/main/webapp/WEB-INF/views/home.html +++ b/spring-thymeleaf/src/main/webapp/WEB-INF/views/home.html @@ -24,6 +24,9 @@ + + + diff --git a/spring-thymeleaf/src/test/java/com/baeldung/thymeleaf/controller/FragmentsIntegrationTest.java b/spring-thymeleaf/src/test/java/com/baeldung/thymeleaf/controller/FragmentsIntegrationTest.java index 5bc45d0004..c6158b76b1 100644 --- a/spring-thymeleaf/src/test/java/com/baeldung/thymeleaf/controller/FragmentsIntegrationTest.java +++ b/spring-thymeleaf/src/test/java/com/baeldung/thymeleaf/controller/FragmentsIntegrationTest.java @@ -1,10 +1,22 @@ package com.baeldung.thymeleaf.controller; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import javax.servlet.Filter; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpSession; +import org.springframework.test.context.ContextConfiguration; +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.request.RequestPostProcessor; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -15,21 +27,6 @@ import com.baeldung.thymeleaf.config.WebApp; import com.baeldung.thymeleaf.config.WebMVCConfig; import com.baeldung.thymeleaf.config.WebMVCSecurity; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import javax.servlet.Filter; - -import static org.hamcrest.Matchers.containsString; - @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = { WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class }) diff --git a/spring-thymeleaf/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-thymeleaf/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..c7a0b4fc60 --- /dev/null +++ b/spring-thymeleaf/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,22 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.thymeleaf.config.InitSecurity; +import com.baeldung.thymeleaf.config.WebApp; +import com.baeldung.thymeleaf.config.WebMVCConfig; +import com.baeldung.thymeleaf.config.WebMVCSecurity; + +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-userservice/pom.xml b/spring-userservice/pom.xml index c372beaa3c..7144a57ca6 100644 --- a/spring-userservice/pom.xml +++ b/spring-userservice/pom.xml @@ -1,17 +1,18 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + spring-userservice spring-userservice 0.0.1-SNAPSHOT war - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + @@ -217,11 +218,11 @@ 4.2.6.RELEASE - 1.4.2.RELEASE + 1.5.14.RELEASE 3.21.0-GA - 5.2.5.Final + 5.2.10.Final 5.1.40 1.10.5.RELEASE 1.4.193 @@ -241,8 +242,6 @@ 2.6 - - \ No newline at end of file diff --git a/spring-userservice/src/main/resources/logback.xml b/spring-userservice/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-userservice/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-userservice/src/main/resources/persistence-derby.properties b/spring-userservice/src/main/resources/persistence-derby.properties index e808fdc288..b76c5de12f 100644 --- a/spring-userservice/src/main/resources/persistence-derby.properties +++ b/spring-userservice/src/main/resources/persistence-derby.properties @@ -7,6 +7,6 @@ jdbc.pass=tutorialpass # hibernate.X hibernate.dialect=org.hibernate.dialect.DerbyDialect hibernate.show_sql=false -hibernate.hbm2ddl.auto=create +hibernate.hbm2ddl.auto=update hibernate.cache.use_second_level_cache=false hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/spring-userservice/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-userservice/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..825b89eb10 --- /dev/null +++ b/spring-userservice/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung; + +import org.baeldung.custom.config.MvcConfig; +import org.baeldung.custom.config.PersistenceDerbyJPAConfig; +import org.baeldung.custom.config.SecSecurityConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class }) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java b/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java index f46a3a070f..1cd38228b8 100644 --- a/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java +++ b/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceIntegrationTest.java @@ -1,5 +1,10 @@ package org.baeldung.userservice; +import static org.junit.Assert.assertEquals; + +import java.util.logging.Level; +import java.util.logging.Logger; + import org.baeldung.custom.config.MvcConfig; import org.baeldung.custom.config.PersistenceDerbyJPAConfig; import org.baeldung.custom.config.SecSecurityConfig; @@ -8,22 +13,16 @@ import org.baeldung.web.MyUserDto; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.dao.DuplicateKeyException; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration; -import static org.junit.Assert.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class }) +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class }) @WebAppConfiguration public class CustomUserDetailsServiceIntegrationTest { diff --git a/spring-vault/README.md b/spring-vault/README.md new file mode 100644 index 0000000000..8db065a3dd --- /dev/null +++ b/spring-vault/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Spring Vault](https://www.baeldung.com/spring-vault) diff --git a/spring-vault/pom.xml b/spring-vault/pom.xml new file mode 100644 index 0000000000..31616cdb16 --- /dev/null +++ b/spring-vault/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + com.baeldung + spring-vault + 0.0.1-SNAPSHOT + jar + spring-vault + Spring Vault sample project + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.vault + spring-vault-core + ${spring.vault.core.version} + + + com.fasterxml.jackson.core + jackson-databind + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + + + + + + + + UTF-8 + 2.0.1.RELEASE + + diff --git a/spring-vault/src/main/java/org/baeldung/springvault/Credentials.java b/spring-vault/src/main/java/org/baeldung/springvault/Credentials.java new file mode 100644 index 0000000000..f90ab66a4e --- /dev/null +++ b/spring-vault/src/main/java/org/baeldung/springvault/Credentials.java @@ -0,0 +1,30 @@ +package org.baeldung.springvault; + +public class Credentials { + + private String username; + private String password; + + public Credentials() { + + } + + public Credentials(String username, String password) { + this.username = username; + this.password = password; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + @Override + public String toString() { + return "Credential [username=" + username + ", password=" + password + "]"; + } + +} diff --git a/spring-vault/src/main/java/org/baeldung/springvault/CredentialsService.java b/spring-vault/src/main/java/org/baeldung/springvault/CredentialsService.java new file mode 100644 index 0000000000..87c24bd947 --- /dev/null +++ b/spring-vault/src/main/java/org/baeldung/springvault/CredentialsService.java @@ -0,0 +1,50 @@ +package org.baeldung.springvault; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.vault.authentication.TokenAuthentication; +import org.springframework.vault.client.VaultEndpoint; +import org.springframework.vault.core.VaultTemplate; +import org.springframework.vault.core.env.VaultPropertySource; +import org.springframework.vault.support.VaultResponse; +import org.springframework.vault.support.VaultResponseSupport; + +/** + * Sample service to demonstrate storing and retrieval of secrets. + * + * NOTE: We need to configure Vault and provide the Vault uri in the properties file. + * + */ +@Service +public class CredentialsService { + + @Autowired + private VaultTemplate vaultTemplate; + + /** + * To Secure Credentials + * @param credentials + * @return VaultResponse + * @throws URISyntaxException + */ + public void secureCredentials(Credentials credentials) throws URISyntaxException { + + vaultTemplate.write("credentials/myapp", credentials); + } + + /** + * To Retrieve Credentials + * @return Credentials + * @throws URISyntaxException + */ + public Credentials accessCredentials() throws URISyntaxException { + + VaultResponseSupport response = vaultTemplate.read("credentials/myapp", Credentials.class); + return response.getData(); + } + +} diff --git a/spring-vault/src/main/java/org/baeldung/springvault/SpringVaultApplication.java b/spring-vault/src/main/java/org/baeldung/springvault/SpringVaultApplication.java new file mode 100644 index 0000000000..916a809be5 --- /dev/null +++ b/spring-vault/src/main/java/org/baeldung/springvault/SpringVaultApplication.java @@ -0,0 +1,17 @@ +package org.baeldung.springvault; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Sample application to demonstrate basics of Spring Vault + * + */ +@SpringBootApplication +public class SpringVaultApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringVaultApplication.class, args); + } + +} diff --git a/spring-vault/src/main/java/org/baeldung/springvault/VaultConfig.java b/spring-vault/src/main/java/org/baeldung/springvault/VaultConfig.java new file mode 100644 index 0000000000..106a1a3d42 --- /dev/null +++ b/spring-vault/src/main/java/org/baeldung/springvault/VaultConfig.java @@ -0,0 +1,26 @@ +package org.baeldung.springvault; + +import org.springframework.context.annotation.Configuration; +import org.springframework.vault.authentication.ClientAuthentication; +import org.springframework.vault.authentication.TokenAuthentication; +import org.springframework.vault.client.VaultEndpoint; +import org.springframework.vault.config.AbstractVaultConfiguration; + +/** + * Example class to configure Vault beans using AbstractVaultConfiguration + * + */ +@Configuration +public class VaultConfig extends AbstractVaultConfiguration { + + @Override + public ClientAuthentication clientAuthentication() { + return new TokenAuthentication("00000000-0000-0000-0000-000000000000"); + } + + @Override + public VaultEndpoint vaultEndpoint() { + return VaultEndpoint.create("host", 8020); + } + +} diff --git a/spring-vault/src/main/java/org/baeldung/springvault/VaultEnvironmentConfig.java b/spring-vault/src/main/java/org/baeldung/springvault/VaultEnvironmentConfig.java new file mode 100644 index 0000000000..6c796bc718 --- /dev/null +++ b/spring-vault/src/main/java/org/baeldung/springvault/VaultEnvironmentConfig.java @@ -0,0 +1,21 @@ +package org.baeldung.springvault; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.PropertySource; +import org.springframework.vault.authentication.ClientAuthentication; +import org.springframework.vault.authentication.TokenAuthentication; +import org.springframework.vault.client.VaultEndpoint; +import org.springframework.vault.config.AbstractVaultConfiguration; +import org.springframework.vault.config.EnvironmentVaultConfiguration; + +/** + * Example class to configure Vault beans using EnvironmentVaultConfiguration + * + */ +@Configuration +@PropertySource(value = { "vault-config.properties" }) +@Import(value = EnvironmentVaultConfiguration.class) +public class VaultEnvironmentConfig { + +} diff --git a/spring-vault/src/main/resources/vault-config.properties b/spring-vault/src/main/resources/vault-config.properties new file mode 100644 index 0000000000..68a080ebe8 --- /dev/null +++ b/spring-vault/src/main/resources/vault-config.properties @@ -0,0 +1,2 @@ +vault.uri=https://localhost:8200 +vault.token=00000000-0000-0000-0000-000000000000 \ No newline at end of file diff --git a/spring-vault/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-vault/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..a2d727ea79 --- /dev/null +++ b/spring-vault/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.springvault.SpringVaultApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringVaultApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-vault/src/test/java/org/baeldung/springvault/VaultInitializer.java b/spring-vault/src/test/java/org/baeldung/springvault/VaultInitializer.java new file mode 100644 index 0000000000..c7db5eb199 --- /dev/null +++ b/spring-vault/src/test/java/org/baeldung/springvault/VaultInitializer.java @@ -0,0 +1,113 @@ +package org.baeldung.springvault; + +import java.io.BufferedReader; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Map; + +/** + * + * This is a test class to initialize Vault. + */ +public class VaultInitializer implements Closeable { + + private static final String UNSEAL_KEY = "Unseal Key:"; + private static final String ROOT_TOKEN = "Root Token:"; + + private Process vaultProcess; + private String unSealKey; + private String rootToken; + + public String getRootToken() { + return rootToken; + } + + public String getUnSealKey() { + return unSealKey; + } + + public static final VaultInitializer initializeValut() { + VaultInitializer vaultProcess = new VaultInitializer(); + vaultProcess.start(); + // Secrets is by default enabled. + vaultProcess.enableSecrets(); + return vaultProcess; + } + + @SuppressWarnings("unused") + private void enableSecrets() { + System.out.println("Enabling Secrets at path credentials/myapp..."); + ProcessBuilder pb = new ProcessBuilder("vault", "secrets", "enable", "-path=credentials/myapp", "kv"); + Map map = pb.environment(); + map.put("VAULT_ADDR", "http://127.0.0.1:8200"); + try { + Process p = pb.inheritIO() + .start(); + p.waitFor(); + } catch (IOException e) { + System.out.println("unable to enableSecrets" + e); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void start() { + System.out.println("starting vault"); + // This starts the vault server. + ProcessBuilder pb = new ProcessBuilder("vault", "server", "-dev"); + + try { + vaultProcess = pb.start(); + // wait for initialization to complete. + Thread.sleep(5000); + } catch (IOException e) { + System.out.println("unable to start vault in new process" + e); + } catch (InterruptedException e) { + System.out.println("Thread interrupted " + e); + } + extractUnsealKeyAndToken(); + } + + /** + * To get the root token which is generated every time server is initialized. + */ + private void extractUnsealKeyAndToken() { + BufferedReader reader = new BufferedReader(new InputStreamReader(vaultProcess.getInputStream())); + StringBuilder builder = new StringBuilder(); + String line = null; + boolean tokenExtracted = false; + try { + while ((line = reader.readLine()) != null) { + builder.append(line); + builder.append(System.getProperty("line.separator")); + if (line.contains(UNSEAL_KEY)) { + String tmp = line.replace(UNSEAL_KEY, ""); + unSealKey = tmp.trim(); + } else if (line.contains(ROOT_TOKEN)) { + String tmp = line.replace(ROOT_TOKEN, ""); + rootToken = tmp.trim(); + tokenExtracted = true; + } + if (tokenExtracted) + break; + System.out.println(line); + } + } catch (IOException e) { + System.out.println("unable to read vault output" + e); + } + + String result = builder.toString(); + + System.out.println("Unseal Key {}" + unSealKey); + System.out.println("Root Token {}" + rootToken); + System.out.println(result); + } + + @Override + public void close() throws IOException { + + System.out.println("stoping vault"); + vaultProcess.destroy(); + } +} diff --git a/spring-vault/src/test/java/org/baeldung/springvault/VaultIntegrationTest.java b/spring-vault/src/test/java/org/baeldung/springvault/VaultIntegrationTest.java new file mode 100644 index 0000000000..75c700ee26 --- /dev/null +++ b/spring-vault/src/test/java/org/baeldung/springvault/VaultIntegrationTest.java @@ -0,0 +1,80 @@ +package org.baeldung.springvault; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.annotation.Order; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.vault.authentication.TokenAuthentication; +import org.springframework.vault.client.VaultEndpoint; +import org.springframework.vault.core.VaultTemplate; +import org.springframework.vault.support.VaultResponse; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = CredentialsService.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = VaultTestConfiguration.class, loader = AnnotationConfigContextLoader.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class VaultIntegrationTest { + + @Autowired + private CredentialsService credentialsService; + + /** + * Test to secure credentials. + * + * @throws URISyntaxException + */ + @Test + public void givenCredentials_whenSecureCredentials_thenCredentialsSecured() throws URISyntaxException { + try { + // Given + Credentials credentials = new Credentials("username", "password"); + + // When + credentialsService.secureCredentials(credentials); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + /** + * Test to access credentials + * @throws URISyntaxException + */ + @Test + public void whenAccessCredentials_thenCredentialsRetrieved() throws URISyntaxException { + + // Given + Credentials credentials = credentialsService.accessCredentials(); + + // Then + assertNotNull(credentials); + assertEquals("username", credentials.getUsername()); + assertEquals("password", credentials.getPassword()); + } + +} diff --git a/spring-vault/src/test/java/org/baeldung/springvault/VaultTestConfiguration.java b/spring-vault/src/test/java/org/baeldung/springvault/VaultTestConfiguration.java new file mode 100644 index 0000000000..09a1445788 --- /dev/null +++ b/spring-vault/src/test/java/org/baeldung/springvault/VaultTestConfiguration.java @@ -0,0 +1,29 @@ +package org.baeldung.springvault; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.vault.authentication.TokenAuthentication; +import org.springframework.vault.client.VaultEndpoint; +import org.springframework.vault.core.VaultTemplate; + +@Configuration +public class VaultTestConfiguration { + + @Bean + public VaultInitializer vaultInitializer() { + VaultInitializer vaultInitializer = VaultInitializer.initializeValut(); + return vaultInitializer; + } + + @Bean + public VaultTemplate vaultTemplate() throws URISyntaxException { + + VaultInitializer vaultInitializer = vaultInitializer(); + VaultTemplate vaultTemplate = new VaultTemplate(VaultEndpoint.from(new URI("http://localhost:8200")), new TokenAuthentication(vaultInitializer.getRootToken())); + return vaultTemplate; + + } +} diff --git a/spring-vertx/pom.xml b/spring-vertx/pom.xml index 449e94b15e..790eeff128 100644 --- a/spring-vertx/pom.xml +++ b/spring-vertx/pom.xml @@ -1,20 +1,18 @@ + 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 - vertx-spring - 0.0.1-SNAPSHOT + + spring-vertx jar - spring-vertx + Spring Vertx A demo project with vertx spring integration - org.springframework.boot - spring-boot-starter-parent - 1.5.3.RELEASE - - + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-1 @@ -57,31 +55,10 @@ org.springframework.boot spring-boot-maven-plugin
    - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/JdbcTest.java - **/*LiveTest.java - - - - - UTF-8 - UTF-8 - 1.8 3.4.1 diff --git a/spring-vertx/src/main/resources/logback.xml b/spring-vertx/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-vertx/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-vertx/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-vertx/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..b1f7b39f7e --- /dev/null +++ b/spring-vertx/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,17 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.vertxspring.VertxSpringApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = VertxSpringApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-webflux-amqp/README.md b/spring-webflux-amqp/README.md new file mode 100644 index 0000000000..5cd3391c3e --- /dev/null +++ b/spring-webflux-amqp/README.md @@ -0,0 +1,4 @@ +### Relevant Articles: +================================ + +- [Spring AMQP in Reactive Applications](http://www.baeldung.com/spring-amqp-reactive) diff --git a/spring-webflux-amqp/pom.xml b/spring-webflux-amqp/pom.xml index 75fafd7b10..4faa165c50 100755 --- a/spring-webflux-amqp/pom.xml +++ b/spring-webflux-amqp/pom.xml @@ -1,75 +1,66 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - org.baeldung.spring - spring-webflux-amqp - 1.0.0-SNAPSHOT - jar + org.baeldung.spring + spring-webflux-amqp + 1.0.0-SNAPSHOT + jar + spring-webflux-amqp + Spring WebFlux AMQP Sample - spring-webflux-amqp - Spring WebFlux AMQP Sample - parent-boot-2 com.baeldung 0.0.1-SNAPSHOT ../parent-boot-2 - + + + org.springframework.boot + spring-boot-starter-amqp + + + org.springframework.boot + spring-boot-starter-webflux + - - UTF-8 - UTF-8 - 1.8 - + + org.springframework.boot + spring-boot-configuration-processor + true + - - - org.springframework.boot - spring-boot-starter-amqp - - - org.springframework.boot - spring-boot-starter-webflux - + + org.springframework.boot + spring-boot-starter-test + test + - - 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 - - + + io.projectreactor + reactor-test + test + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + org.springframework.boot + spring-boot-starter-integration + + - + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + spring-snapshots Spring Snapshots @@ -88,5 +79,4 @@ - diff --git a/spring-webflux-amqp/src/main/resources/logback.xml b/spring-webflux-amqp/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-webflux-amqp/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-webflux-amqp/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-webflux-amqp/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..35efff49c2 --- /dev/null +++ b/spring-webflux-amqp/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.spring.amqp.SpringWebfluxAmqpApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringWebfluxAmqpApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-zuul/pom.xml b/spring-zuul/pom.xml index 37bdb09367..35e419cdc7 100644 --- a/spring-zuul/pom.xml +++ b/spring-zuul/pom.xml @@ -1,6 +1,7 @@ + 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 spring-zuul 1.0.0-SNAPSHOT @@ -23,7 +24,6 @@ spring-zuul - org.apache.maven.plugins maven-war-plugin @@ -32,22 +32,17 @@ false
    - - 1.2.3.RELEASE - 3.5 - 2.6 -
    \ No newline at end of file diff --git a/spring-zuul/spring-zuul-foos-resource/pom.xml b/spring-zuul/spring-zuul-foos-resource/pom.xml index 58274c523a..70e39db4aa 100644 --- a/spring-zuul/spring-zuul-foos-resource/pom.xml +++ b/spring-zuul/spring-zuul-foos-resource/pom.xml @@ -1,6 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + spring-zuul-foos-resource spring-zuul-foos-resource war @@ -16,13 +17,11 @@ org.springframework.boot spring-boot-starter-web - org.apache.commons commons-lang3 ${commons-lang3.version} - diff --git a/spring-zuul/spring-zuul-foos-resource/src/main/resources/logback.xml b/spring-zuul/spring-zuul-foos-resource/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-zuul/spring-zuul-foos-resource/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-zuul/spring-zuul-foos-resource/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-zuul/spring-zuul-foos-resource/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..623966373b --- /dev/null +++ b/spring-zuul/spring-zuul-foos-resource/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.ResourceServerApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ResourceServerApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-zuul/spring-zuul-ui/pom.xml b/spring-zuul/spring-zuul-ui/pom.xml index 42c18a46c7..6090f5f8b8 100644 --- a/spring-zuul/spring-zuul-ui/pom.xml +++ b/spring-zuul/spring-zuul-ui/pom.xml @@ -1,8 +1,8 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - spring-zuul-ui + spring-zuul-ui spring-zuul-ui war @@ -12,33 +12,26 @@ 1.0.0-SNAPSHOT - org.springframework.cloud spring-cloud-starter-zuul ${spring-cloud.version} - - - + org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-thymeleaf - org.springframework spring-test test - org.hamcrest hamcrest-core @@ -49,13 +42,11 @@ hamcrest-library test - org.mockito mockito-core test - diff --git a/spring-zuul/spring-zuul-ui/src/main/resources/logback.xml b/spring-zuul/spring-zuul-ui/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-zuul/spring-zuul-ui/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-zuul/spring-zuul-ui/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-zuul/spring-zuul-ui/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..a3d49627e5 --- /dev/null +++ b/spring-zuul/spring-zuul-ui/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package org.baeldung; + +import org.baeldung.config.UiApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = UiApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/sse-jaxrs/pom.xml b/sse-jaxrs/pom.xml new file mode 100644 index 0000000000..ac9bff937f --- /dev/null +++ b/sse-jaxrs/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + com.baeldung.sse + sse-jaxrs + 1.0-SNAPSHOT + pom + + + 1.8 + 1.8 + + + + sse-jaxrs-server + sse-jaxrs-client + + + diff --git a/sse-jaxrs/sse-jaxrs-client/pom.xml b/sse-jaxrs/sse-jaxrs-client/pom.xml new file mode 100644 index 0000000000..a9068e133f --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-client/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + + com.baeldung.sse + sse-jaxrs + 1.0-SNAPSHOT + + + sse-jaxrs-client + + + 3.2.0 + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + singleEvent + + java + + + com.baeldung.sse.jaxrs.client.SseClientApp + + + + broadcast + + java + + + com.baeldung.sse.jaxrs.client.SseClientBroadcastApp + + + + + + + + + + org.apache.cxf + cxf-rt-rs-client + ${cxf-version} + + + org.apache.cxf + cxf-rt-rs-sse + ${cxf-version} + + + + diff --git a/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java b/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java new file mode 100644 index 0000000000..5d42b3a243 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java @@ -0,0 +1,48 @@ +package com.baeldung.sse.jaxrs.client; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.sse.InboundSseEvent; +import javax.ws.rs.sse.SseEventSource; +import java.util.function.Consumer; + +public class SseClientApp { + + private static final String url = "http://127.0.0.1:9080/sse-jaxrs-server/sse/stock/prices"; + + public static void main(String... args) throws Exception { + + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(url); + try (SseEventSource eventSource = SseEventSource.target(target).build()) { + + eventSource.register(onEvent, onError, onComplete); + eventSource.open(); + + //Consuming events for one hour + Thread.sleep(60 * 60 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + client.close(); + System.out.println("End"); + } + + // A new event is received + private static Consumer onEvent = (inboundSseEvent) -> { + String data = inboundSseEvent.readData(); + System.out.println(data); + }; + + //Error + private static Consumer onError = (throwable) -> { + throwable.printStackTrace(); + }; + + //Connection close and there is nothing to receive + private static Runnable onComplete = () -> { + System.out.println("Done!"); + }; + +} diff --git a/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java b/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java new file mode 100644 index 0000000000..9afc187a6d --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java @@ -0,0 +1,52 @@ +package com.baeldung.sse.jaxrs.client; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.sse.InboundSseEvent; +import javax.ws.rs.sse.SseEventSource; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +public class SseClientBroadcastApp { + + private static final String subscribeUrl = "http://localhost:9080/sse-jaxrs-server/sse/stock/subscribe"; + + + public static void main(String... args) throws Exception { + + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(subscribeUrl); + try (final SseEventSource eventSource = SseEventSource.target(target) + .reconnectingEvery(5, TimeUnit.SECONDS) + .build()) { + eventSource.register(onEvent, onError, onComplete); + eventSource.open(); + System.out.println("Wainting for incoming event ..."); + + //Consuming events for one hour + Thread.sleep(60 * 60 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + client.close(); + System.out.println("End"); + } + + // A new event is received + private static Consumer onEvent = (inboundSseEvent) -> { + String data = inboundSseEvent.readData(); + System.out.println(data); + }; + + //Error + private static Consumer onError = (throwable) -> { + throwable.printStackTrace(); + }; + + //Connection close and there is nothing to receive + private static Runnable onComplete = () -> { + System.out.println("Done!"); + }; + +} diff --git a/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml b/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/sse-jaxrs/sse-jaxrs-server/pom.xml b/sse-jaxrs/sse-jaxrs-server/pom.xml new file mode 100644 index 0000000000..1e89c70e13 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/pom.xml @@ -0,0 +1,85 @@ + + + 4.0.0 + + + com.baeldung.sse + sse-jaxrs + 1.0-SNAPSHOT + + + sse-jaxrs-server + war + + + 2.4.2 + false + 18.0.0.2 + + + + ${artifactId} + + + net.wasdev.wlp.maven.plugins + liberty-maven-plugin + ${liberty-maven-plugin.version} + + + io.openliberty + openliberty-webProfile8 + ${openliberty-version} + zip + + project + true + src/main/liberty/config/server.xml + + + + install-server + prepare-package + + install-server + create-server + install-feature + + + + install-apps + package + + install-apps + + + + + + + + + + + javax.ws.rs + javax.ws.rs-api + 2.1 + provided + + + javax.enterprise + cdi-api + 2.0 + provided + + + javax.json.bind + javax.json.bind-api + 1.0 + provided + + + + + diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java b/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java new file mode 100644 index 0000000000..058d19f045 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java @@ -0,0 +1,8 @@ +package com.baeldung.sse.jaxrs; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +@ApplicationPath("sse") +public class AppConfig extends Application { +} diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java b/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java new file mode 100644 index 0000000000..1f60168a1b --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java @@ -0,0 +1,119 @@ +package com.baeldung.sse.jaxrs; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.sse.OutboundSseEvent; +import javax.ws.rs.sse.Sse; +import javax.ws.rs.sse.SseBroadcaster; +import javax.ws.rs.sse.SseEventSink; + +@ApplicationScoped +@Path("stock") +public class SseResource { + + @Inject + private StockService stockService; + + private Sse sse; + private SseBroadcaster sseBroadcaster; + private OutboundSseEvent.Builder eventBuilder; + + @Context + public void setSse(Sse sse) { + this.sse = sse; + this.eventBuilder = sse.newEventBuilder(); + this.sseBroadcaster = sse.newBroadcaster(); + } + + @GET + @Path("prices") + @Produces("text/event-stream") + public void getStockPrices(@Context SseEventSink sseEventSink, + @HeaderParam(HttpHeaders.LAST_EVENT_ID_HEADER) @DefaultValue("-1") int lastReceivedId) { + + int lastEventId = 1; + if (lastReceivedId != -1) { + lastEventId = ++lastReceivedId; + } + boolean running = true; + while (running) { + Stock stock = stockService.getNextTransaction(lastEventId); + if (stock != null) { + OutboundSseEvent sseEvent = this.eventBuilder + .name("stock") + .id(String.valueOf(lastEventId)) + .mediaType(MediaType.APPLICATION_JSON_TYPE) + .data(Stock.class, stock) + .reconnectDelay(3000) + .comment("price change") + .build(); + sseEventSink.send(sseEvent); + lastEventId++; + } + //Simulate connection close + if (lastEventId % 5 == 0) { + sseEventSink.close(); + break; + } + + try { + //Wait 5 seconds + Thread.sleep(5 * 1000); + } catch (InterruptedException ex) { + // ... + } + //Simulatae a while boucle break + running = lastEventId <= 2000; + } + sseEventSink.close(); + } + + @GET + @Path("subscribe") + @Produces(MediaType.SERVER_SENT_EVENTS) + public void listen(@Context SseEventSink sseEventSink) { + sseEventSink.send(sse.newEvent("Welcome !")); + this.sseBroadcaster.register(sseEventSink); + sseEventSink.send(sse.newEvent("You are registred !")); + } + + @GET + @Path("publish") + public void broadcast() { + Runnable r = new Runnable() { + @Override + public void run() { + int lastEventId = 0; + boolean running = true; + while (running) { + lastEventId++; + Stock stock = stockService.getNextTransaction(lastEventId); + if (stock != null) { + OutboundSseEvent sseEvent = eventBuilder + .name("stock") + .id(String.valueOf(lastEventId)) + .mediaType(MediaType.APPLICATION_JSON_TYPE) + .data(Stock.class, stock) + .reconnectDelay(3000) + .comment("price change") + .build(); + sseBroadcaster.broadcast(sseEvent); + } + try { + //Wait 5 seconds + Thread.currentThread().sleep(5 * 1000); + } catch (InterruptedException ex) { + // ... + } + //Simulatae a while boucle break + running = lastEventId <= 2000; + } + } + }; + new Thread(r).start(); + } +} diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java b/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java new file mode 100644 index 0000000000..a186b32771 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java @@ -0,0 +1,50 @@ +package com.baeldung.sse.jaxrs; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +public class Stock { + private Integer id; + private String name; + private BigDecimal price; + LocalDateTime dateTime; + + public Stock(Integer id, String name, BigDecimal price, LocalDateTime dateTime) { + this.id = id; + this.name = name; + this.price = price; + this.dateTime = dateTime; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public LocalDateTime getDateTime() { + return dateTime; + } + + public void setDateTime(LocalDateTime dateTime) { + this.dateTime = dateTime; + } +} diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java b/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java new file mode 100644 index 0000000000..15818ead5d --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java @@ -0,0 +1,78 @@ +package com.baeldung.sse.jaxrs; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Initialized; +import javax.enterprise.event.Event; +import javax.enterprise.event.Observes; +import javax.inject.Inject; +import javax.inject.Named; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +@ApplicationScoped +@Named +public class StockService { + + private static final BigDecimal UP = BigDecimal.valueOf(1.05f); + private static final BigDecimal DOWN = BigDecimal.valueOf(0.95f); + + List stockNames = Arrays.asList("GOOG", "IBM", "MS", "GOOG", "YAHO"); + List stocksDB = new ArrayList<>(); + private AtomicInteger counter = new AtomicInteger(0); + + public void init(@Observes @Initialized(ApplicationScoped.class) Object init) { + //Open price + System.out.println("@Start Init ..."); + stockNames.forEach(stockName -> { + stocksDB.add(new Stock(counter.incrementAndGet(), stockName, generateOpenPrice(), LocalDateTime.now())); + }); + + Runnable runnable = new Runnable() { + @Override + public void run() { + //Simulate Change price and put every x seconds + while (true) { + int indx = new Random().nextInt(stockNames.size()); + String stockName = stockNames.get(indx); + BigDecimal price = getLastPrice(stockName); + BigDecimal newprice = changePrice(price); + Stock stock = new Stock(counter.incrementAndGet(), stockName, newprice, LocalDateTime.now()); + stocksDB.add(stock); + + int r = new Random().nextInt(30); + try { + Thread.currentThread().sleep(r*1000); + } catch (InterruptedException ex) { + // ... + } + } + } + }; + new Thread(runnable).start(); + System.out.println("@End Init ..."); + } + + public Stock getNextTransaction(Integer lastEventId) { + return stocksDB.stream().filter(s -> s.getId().equals(lastEventId)).findFirst().orElse(null); + } + + BigDecimal generateOpenPrice() { + float min = 70; + float max = 120; + return BigDecimal.valueOf(min + new Random().nextFloat() * (max - min)).setScale(4,RoundingMode.CEILING); + } + + BigDecimal changePrice(BigDecimal price) { + return Math.random() >= 0.5 ? price.multiply(UP).setScale(4,RoundingMode.CEILING) : price.multiply(DOWN).setScale(4,RoundingMode.CEILING); + } + + private BigDecimal getLastPrice(String stockName) { + return stocksDB.stream().filter(stock -> stock.getName().equals(stockName)).findFirst().get().getPrice(); + } +} diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml b/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml new file mode 100644 index 0000000000..9bf66d7795 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml @@ -0,0 +1,7 @@ + + + jaxrs-2.1 + cdi-2.0 + + + diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml b/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000000..4f0b3cdeeb --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml b/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml b/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..b4b8121fdd --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,11 @@ + + + Hello Servlet + + + index.html + + + diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html b/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html new file mode 100644 index 0000000000..9015a7a32c --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html @@ -0,0 +1 @@ +index diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html b/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html new file mode 100644 index 0000000000..5a46e2a5d3 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html @@ -0,0 +1,38 @@ + + + + Server-Sent Event Broadcasting + + +

    Stock prices :

    +
    +
      +
    +
    + + + \ No newline at end of file diff --git a/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html b/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html new file mode 100644 index 0000000000..8fddae4717 --- /dev/null +++ b/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html @@ -0,0 +1,38 @@ + + + + Server-Sent Event + + +

    Stock prices :

    +
    +
      +
    +
    + + + \ No newline at end of file diff --git a/static-analysis/pom.xml b/static-analysis/pom.xml index 93d071714e..14853d81f7 100644 --- a/static-analysis/pom.xml +++ b/static-analysis/pom.xml @@ -1,8 +1,8 @@ - + 4.0.0 + com.baeldung static-analysis 1.0-SNAPSHOT diff --git a/static-analysis/src/main/resources/logback.xml b/static-analysis/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/static-analysis/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/static-analysis/src/test/java/com/baeldung/pmd/CntTest.java b/static-analysis/src/test/java/com/baeldung/pmd/CntUnitTest.java similarity index 92% rename from static-analysis/src/test/java/com/baeldung/pmd/CntTest.java rename to static-analysis/src/test/java/com/baeldung/pmd/CntUnitTest.java index ed72602f99..cdbf9f6f5e 100644 --- a/static-analysis/src/test/java/com/baeldung/pmd/CntTest.java +++ b/static-analysis/src/test/java/com/baeldung/pmd/CntUnitTest.java @@ -4,7 +4,7 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; -public class CntTest { +public class CntUnitTest { private Cnt service; diff --git a/stripe/pom.xml b/stripe/pom.xml index ca165934a0..1e13612fb5 100644 --- a/stripe/pom.xml +++ b/stripe/pom.xml @@ -1,7 +1,8 @@ + 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.stripe stripe 0.0.1-SNAPSHOT @@ -25,20 +26,23 @@ org.springframework.boot spring-boot-starter-thymeleaf - org.projectlombok lombok - 1.16.16 - + ${lombok.version} + com.stripe stripe-java - 4.2.0 + ${stripe.version} + + + 1.16.16 + 4.2.0 + diff --git a/stripe/src/main/resources/logback.xml b/stripe/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/stripe/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/structurizr/pom.xml b/structurizr/pom.xml index 1656bb10ec..cbbbf8d68c 100644 --- a/structurizr/pom.xml +++ b/structurizr/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung @@ -13,31 +12,26 @@ 1.0.0-SNAPSHOT - - 1.8 - 1.8 - - com.structurizr structurizr-core - 1.0.0-RC3 + ${structurizr.version} com.structurizr structurizr-spring - 1.0.0-RC3 + ${structurizr.version} com.structurizr structurizr-client - 0.6.0 + ${structurizr-client.version} org.springframework spring-context - 4.3.8.RELEASE + ${spring.version} @@ -51,4 +45,13 @@ http://jcenter.bintray.com + + + 1.8 + 1.8 + 1.0.0-RC3 + 0.6.0 + 4.3.8.RELEASE + + \ No newline at end of file diff --git a/structurizr/src/main/resources/logback.xml b/structurizr/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/structurizr/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/struts-2/pom.xml b/struts-2/pom.xml index 51e5b9a55c..fee68c8303 100644 --- a/struts-2/pom.xml +++ b/struts-2/pom.xml @@ -1,62 +1,44 @@ + 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 - struts + struts-2 0.0.1-SNAPSHOT pom - struts + Struts 2 - com.baeldung - parent-spring-4 - 0.0.1-SNAPSHOT - ../parent-spring-4 - + com.baeldung + parent-spring-4 + 0.0.1-SNAPSHOT + ../parent-spring-4 + - - src/main/java - - - src/main/resources - - - - - - maven-war-plugin - 3.0.0 - - WebContent - - - - org.apache.struts struts2-core - 2.5.5 + ${struts2.version} org.apache.struts struts2-junit-plugin - 2.5.5 + ${struts2.version} org.apache.struts struts2-convention-plugin - 2.5.8 + ${struts2-convention-plugin.version} javax.servlet javax.servlet-api - 3.0.1 + ${servlet.version} org.springframework spring-core - 4.3.6.RELEASE + ${spring.version} commons-logging @@ -65,4 +47,31 @@ + + + src/main/java + + + src/main/resources + + + + + maven-war-plugin + ${maven-war-plugin.version} + + WebContent + + + + + + + 2.5.5 + 2.5.8 + 3.0.1 + 4.3.6.RELEASE + 3.0.0 + + \ No newline at end of file diff --git a/struts-2/src/main/resources/logback.xml b/struts-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/struts-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/README.md b/testing-modules/README.md index d83970f96a..b189b9819e 100644 --- a/testing-modules/README.md +++ b/testing-modules/README.md @@ -12,4 +12,5 @@ - [Hamcrest Object Matchers](http://www.baeldung.com/hamcrest-object-matchers) - [Headers, Cookies and Parameters with REST-assured](http://www.baeldung.com/rest-assured-header-cookie-parameter) - [JSON Schema Validation with REST-assured](http://www.baeldung.com/rest-assured-json-schema) - +- [Testing Callbacks with Mockito](http://www.baeldung.com/mockito-callbacks) +- [Running JUnit Tests in Parallel with Maven](https://www.baeldung.com/maven-junit-parallel-tests) diff --git a/testing-modules/gatling/README.md b/testing-modules/gatling/README.md index 5c81c4bd6a..941ab75f06 100644 --- a/testing-modules/gatling/README.md +++ b/testing-modules/gatling/README.md @@ -1,2 +1,5 @@ ### Relevant Articles: - [Intro to Gatling](http://www.baeldung.com/introduction-to-gatling) + +### Running a simualtion +- To run a simulation use "simulation" profile, command - `mvn install -Psimulation -Dgib.enabled=false` diff --git a/testing-modules/gatling/pom.xml b/testing-modules/gatling/pom.xml index c4aec4d61a..8d4c89ec62 100644 --- a/testing-modules/gatling/pom.xml +++ b/testing-modules/gatling/pom.xml @@ -1,117 +1,135 @@ - - 4.0.0 - org.baeldung - gatling - 1.0-SNAPSHOT + + 4.0.0 + org.baeldung + gatling + 1.0-SNAPSHOT + com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ - - 1.8 - 1.8 - UTF-8 - 2.11.12 - 2.2.5 - 3.2.2 - 2.2.1 - + + + + io.gatling.highcharts + gatling-charts-highcharts + + + io.gatling + gatling-app + + + io.gatling + gatling-recorder + + + org.scala-lang + scala-library + + - - - - io.gatling - gatling-app - ${gatling.version} - - - io.gatling - gatling-recorder - ${gatling.version} - - - io.gatling.highcharts - gatling-charts-highcharts - ${gatling.version} - - - org.scala-lang - scala-library - ${scala.version} - - - + + src/test/scala + + + + net.alchim31.maven + scala-maven-plugin + ${scala-maven-plugin.version} + + + + + + net.alchim31.maven + scala-maven-plugin + + + + testCompile + + + + + -Ydelambdafy:method + -target:jvm-1.8 + -deprecation + -feature + -unchecked + -language:implicitConversions + -language:postfixOps + + + + + + + + + + + simulation + + + + io.gatling + gatling-maven-plugin + ${gatling-maven-plugin.version} + + + test + + execute + + + true + + + + + + + + - - - io.gatling.highcharts - gatling-charts-highcharts - - - io.gatling - gatling-app - - - io.gatling - gatling-recorder - - - org.scala-lang - scala-library - - + + + + io.gatling + gatling-app + ${gatling.version} + + + io.gatling + gatling-recorder + ${gatling.version} + + + io.gatling.highcharts + gatling-charts-highcharts + ${gatling.version} + + + org.scala-lang + scala-library + ${scala.version} + + + + + + 1.8 + 1.8 + UTF-8 + 2.12.6 + 2.3.1 + 3.2.2 + 2.2.4 + - - src/test/scala - - - - net.alchim31.maven - scala-maven-plugin - ${scala-maven-plugin.version} - - - - - - net.alchim31.maven - scala-maven-plugin - - - - testCompile - - - - - -Ydelambdafy:method - -target:jvm-1.8 - -deprecation - -feature - -unchecked - -language:implicitConversions - -language:postfixOps - - - - - - - io.gatling - gatling-maven-plugin - ${gatling-maven-plugin.version} - - - test - - execute - - - - - - diff --git a/testing-modules/groovy-spock/pom.xml b/testing-modules/groovy-spock/pom.xml index 84b27187eb..e0da345eb4 100644 --- a/testing-modules/groovy-spock/pom.xml +++ b/testing-modules/groovy-spock/pom.xml @@ -1,12 +1,11 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 org.spockframework groovy-spock 1.0-SNAPSHOT jar - Spock Framework - Example Project com.baeldung @@ -15,6 +14,20 @@ ../../ + + + org.spockframework + spock-core + ${spock-core.version} + test + + + org.codehaus.groovy + groovy-all + ${groovy-all.version} + + + @@ -33,23 +46,7 @@ - - - org.spockframework - spock-core - ${spock-core.version} - test - - - org.codehaus.groovy - groovy-all - ${groovy-all.version} - - - - UTF-8 - UTF-8 1.0-groovy-2.4 2.4.7 1.5 diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md index 2292c3272a..836848282b 100644 --- a/testing-modules/junit-5/README.md +++ b/testing-modules/junit-5/README.md @@ -1,7 +1,6 @@ ### Relevant Articles: - [The Basics of JUnit 5 – A Preview](http://www.baeldung.com/junit-5-preview) - [A Guide to JUnit 5](http://www.baeldung.com/junit-5) -- [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests) - [A Guide to @RepeatedTest in Junit 5](http://www.baeldung.com/junit-5-repeated-test) - [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests) - [A Guied to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions) @@ -13,3 +12,6 @@ - [@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) +- [The Order of Tests in JUnit](http://www.baeldung.com/junit-5-test-order) +- [Running JUnit Tests Programmatically, from a Java Application](https://www.baeldung.com/junit-tests-run-programmatically-from-java) +- [Testing an Abstract Class With JUnit](https://www.baeldung.com/junit-test-abstract-class) diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index b33fd2fe14..93365264ac 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -1,12 +1,10 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - - + junit-5 1.0-SNAPSHOT - junit-5 Intro to JUnit 5 @@ -17,44 +15,6 @@ ../../ - - - - - src/test/resources - true - - - - - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - - - - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - - - java - - - - - com.baeldung.TestLauncher - - - - - org.junit.platform @@ -73,6 +33,12 @@ ${junit.vintage.version} test + + org.junit.jupiter + junit-jupiter-migrationsupport + ${junit.vintage.version} + test + org.apache.logging.log4j log4j-core @@ -94,22 +60,74 @@ spring-context ${spring.version} - + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + + + junit + junit + + + + + org.powermock + powermock-api-mockito2 + ${powermock.version} + test + + + + + src/test/resources + true + + + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + + + java + + + + + com.baeldung.TestLauncher + + + + + - UTF-8 - 1.8 - 5.1.0 - 1.1.0 + 5.2.0 + 1.2.0 5.2.0 2.8.2 1.4.196 - 2.11.0 - - 3.7.0 - 2.19.1 + 2.8.9 + 1.7.4 + 2.21.0 + 1.6.0 5.0.1.RELEASE - + diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/abstractmethod/AbstractMethodCalling.java b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/abstractmethod/AbstractMethodCalling.java new file mode 100644 index 0000000000..e55c6b98e2 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/abstractmethod/AbstractMethodCalling.java @@ -0,0 +1,17 @@ +/** + * + */ +package com.baeldung.abstractclass.abstractmethod; + +/** + * When method calls abstract method. + */ +public abstract class AbstractMethodCalling { + + public abstract String abstractFunc(); + + public String defaultImpl() { + String res = abstractFunc(); + return (res == null) ? "Default" : (res + " Default"); + } +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/indepedentmethod/AbstractIndependent.java b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/indepedentmethod/AbstractIndependent.java new file mode 100644 index 0000000000..4dce2665d5 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/indepedentmethod/AbstractIndependent.java @@ -0,0 +1,14 @@ +package com.baeldung.abstractclass.indepedentmethod; + +/** + * Test Independent Method + * + */ +public abstract class AbstractIndependent { + + public abstract int abstractFunc(); + + public String defaultImpl() { + return "DEFAULT-1"; + } +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/indepedentmethod/ConcreteImpl.java b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/indepedentmethod/ConcreteImpl.java new file mode 100644 index 0000000000..6e71b88946 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/indepedentmethod/ConcreteImpl.java @@ -0,0 +1,10 @@ +package com.baeldung.abstractclass.indepedentmethod; + +public class ConcreteImpl extends AbstractIndependent { + + @Override + public int abstractFunc() { + return 4; + } + +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/instancefields/AbstractInstanceFields.java b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/instancefields/AbstractInstanceFields.java new file mode 100644 index 0000000000..262f72e393 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/instancefields/AbstractInstanceFields.java @@ -0,0 +1,22 @@ +package com.baeldung.abstractclass.instancefields; + +/** + * Test Independent Method + */ +public abstract class AbstractInstanceFields { + + protected int count; + private boolean active = false; + + public abstract int abstractFunc(); + + public String testFunc() { + String response; + if (count > 5) { + response = "Overflow"; + } else { + response = active ? "Added" : "Blocked"; + } + return response; + } +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/privatemethod/AbstractPrivateMethods.java b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/privatemethod/AbstractPrivateMethods.java new file mode 100644 index 0000000000..fe7fb25931 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/abstractclass/privatemethod/AbstractPrivateMethods.java @@ -0,0 +1,17 @@ +package com.baeldung.abstractclass.privatemethod; + +import java.time.LocalDateTime; + +public abstract class AbstractPrivateMethods { + + public abstract int abstractFunc(); + + public String defaultImpl() { + return getCurrentDateTime() + "DEFAULT-1"; + } + + private String getCurrentDateTime() { + return LocalDateTime.now() + .toString(); + } +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/throwsexception/Calculator.java b/testing-modules/junit-5/src/main/java/com/baeldung/throwsexception/Calculator.java new file mode 100644 index 0000000000..50dbc9c774 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/throwsexception/Calculator.java @@ -0,0 +1,15 @@ +package com.baeldung.throwsexception; + +public class Calculator { + + public double divide(double a, double b) { + if (b == 0) { + throw new DivideByZeroException("Divider cannot be equal to zero!"); + } + return a/b; + } + +} + + + diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/throwsexception/DivideByZeroException.java b/testing-modules/junit-5/src/main/java/com/baeldung/throwsexception/DivideByZeroException.java new file mode 100644 index 0000000000..4413374c99 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/throwsexception/DivideByZeroException.java @@ -0,0 +1,9 @@ +package com.baeldung.throwsexception; + +public class DivideByZeroException extends RuntimeException { + + public DivideByZeroException(String message) { + super(message); + } + +} diff --git a/testing-modules/junit-5/src/main/resources/logback.xml b/testing-modules/junit-5/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/junit-5/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java index 79ba882205..31b6e14d6c 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java @@ -11,14 +11,17 @@ import java.util.Optional; import java.util.function.BooleanSupplier; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; /** * Unit test that demonstrate the different assertions available within JUnit 4 */ +@DisplayName("Test case for assertions") public class AssertionUnitTest { @Test + @DisplayName("Arrays should be equals") public void whenAssertingArraysEquality_thenEqual() { char[] expected = {'J', 'u', 'p', 'i', 't', 'e', 'r'}; char[] actual = "Jupiter".toCharArray(); @@ -27,6 +30,7 @@ public class AssertionUnitTest { } @Test + @DisplayName("The area of two polygons should be equal") public void whenAssertingEquality_thenEqual() { float square = 2 * 2; float rectangle = 2 * 2; diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/NestedUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/NestedUnitTest.java index 7586a2f51a..299cac2480 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/NestedUnitTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/NestedUnitTest.java @@ -10,13 +10,13 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; public class NestedUnitTest { + Stack stack; - boolean isRun = false; @Test @DisplayName("is instantiated with new Stack()") void isInstantiatedWithNew() { - new Stack(); + new Stack<>(); } @Nested @@ -25,7 +25,7 @@ public class NestedUnitTest { @BeforeEach void init() { - stack = new Stack(); + stack = new Stack<>(); } @Test diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/abstractmethod/AbstractMethodCallingUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/abstractmethod/AbstractMethodCallingUnitTest.java new file mode 100644 index 0000000000..7ebd866f3d --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/abstractmethod/AbstractMethodCallingUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.abstractclass.abstractmethod; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +public class AbstractMethodCallingUnitTest { + + private AbstractMethodCalling cls; + + @BeforeEach + public void setup() { + cls = Mockito.mock(AbstractMethodCalling.class); + } + + @Test + public void givenDefaultImpl_whenMockAbstractFunc_thenExpectedBehaviour() { + Mockito + .when(cls.abstractFunc()) + .thenReturn("Abstract"); + Mockito + .doCallRealMethod() + .when(cls) + .defaultImpl(); + + // validate result by mock abstractFunc's behaviour + Assertions.assertEquals("Abstract Default", cls.defaultImpl()); + + // check the value with null response from abstract method + Mockito + .doReturn(null) + .when(cls) + .abstractFunc(); + Assertions.assertEquals("Default", cls.defaultImpl()); + } + +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/indepedentmethod/AbstractIndependentUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/indepedentmethod/AbstractIndependentUnitTest.java new file mode 100644 index 0000000000..db9811e6c1 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/indepedentmethod/AbstractIndependentUnitTest.java @@ -0,0 +1,25 @@ +/** + * + */ +package com.baeldung.abstractclass.indepedentmethod; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +public class AbstractIndependentUnitTest { + + @Test + public void givenNonAbstractMethod_whenConcreteImpl_testCorrectBehaviour() { + ConcreteImpl conClass = new ConcreteImpl(); + String actual = conClass.defaultImpl(); + + Assertions.assertEquals("DEFAULT-1", actual); + } + + @Test + public void givenNonAbstractMethod_whenMockitoMock_testCorrectBehaviour() { + AbstractIndependent absCls = Mockito.mock(AbstractIndependent.class, Mockito.CALLS_REAL_METHODS); + Assertions.assertEquals("DEFAULT-1", absCls.defaultImpl()); + } +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/instancefields/AbstractInstanceFieldsUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/instancefields/AbstractInstanceFieldsUnitTest.java new file mode 100644 index 0000000000..5187ce00ab --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/instancefields/AbstractInstanceFieldsUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.abstractclass.instancefields; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.reflect.Whitebox; + +public class AbstractInstanceFieldsUnitTest { + + @Test + public void givenProtectedInstanceField_whenMockClassCountGt5_thenTestNonAbstractMethod() { + + // mock + AbstractInstanceFields instClass = Mockito.mock(AbstractInstanceFields.class); + Mockito + .doCallRealMethod() + .when(instClass) + .testFunc(); + + // set counter greater than 5 + instClass.count = 7; + + // compare the result + Assertions.assertEquals("Overflow", instClass.testFunc()); + } + + @Test + public void givenNonAbstractMethodAndPrivateField_whenPowerMockitoAndActiveFieldTrue_thenCorrectBehaviour() { + + AbstractInstanceFields instClass = PowerMockito.mock(AbstractInstanceFields.class); + PowerMockito + .doCallRealMethod() + .when(instClass) + .testFunc(); + Whitebox.setInternalState(instClass, "active", true); + + // compare the expected result with actual + Assertions.assertEquals("Added", instClass.testFunc()); + } + +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/privatemethod/AbstractPrivateMethodsUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/privatemethod/AbstractPrivateMethodsUnitTest.java new file mode 100644 index 0000000000..9ce7ff8706 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/abstractclass/privatemethod/AbstractPrivateMethodsUnitTest.java @@ -0,0 +1,41 @@ +/** + * + */ +package com.baeldung.abstractclass.privatemethod; + +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.time.LocalDateTime; + +/** + * Providing custom values for private methods using powermock + * + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(AbstractPrivateMethods.class) +public class AbstractPrivateMethodsUnitTest { + + @Test + public void givenNonAbstractMethodAndCallPrivateMethod_whenMockPrivateMethod_thenVerifyBehaviour() throws Exception { + AbstractPrivateMethods mockClass = PowerMockito.mock(AbstractPrivateMethods.class); + + String dateTime = LocalDateTime + .now() + .toString(); + PowerMockito + .doCallRealMethod() + .when(mockClass) + .defaultImpl(); + PowerMockito + .doReturn(dateTime) + .when(mockClass, "getCurrentDateTime");// .thenReturn(dateTime); + String actual = mockClass.defaultImpl(); + Assertions.assertEquals(dateTime + "DEFAULT-1", actual); + } + +} diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/SortedUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit4vstestng/SortedUnitTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/junit4vstestng/SortedUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/junit4vstestng/SortedUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/SummationServiceIntegrationTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit4vstestng/SummationServiceIntegrationTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/junit4vstestng/SummationServiceIntegrationTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/junit4vstestng/SummationServiceIntegrationTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5vstestng/SummationServiceIntegrationTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5vstestng/SummationServiceIntegrationTest.java new file mode 100644 index 0000000000..92e7a6f5db --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5vstestng/SummationServiceIntegrationTest.java @@ -0,0 +1,53 @@ +package com.baeldung.junit5vstestng; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SummationServiceIntegrationTest { + private static List numbers; + + @BeforeAll + public static void initialize() { + numbers = new ArrayList<>(); + } + + @AfterAll + public static void tearDown() { + numbers = null; + } + + @BeforeEach + public void runBeforeEachTest() { + numbers.add(1); + numbers.add(2); + numbers.add(3); + } + + @AfterEach + public void runAfterEachTest() { + numbers.clear(); + } + + @Test + public void givenNumbers_sumEquals_thenCorrect() { + int sum = numbers.stream() + .reduce(0, Integer::sum); + Assert.assertEquals(6, sum); + } + + @Ignore + @Test + public void givenEmptyList_sumEqualsZero_thenCorrect() { + int sum = numbers.stream() + .reduce(0, Integer::sum); + Assert.assertEquals(6, sum); + } +} diff --git a/junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/methodorders/DefaultOrderOfExecutionUnitTest.java similarity index 88% rename from junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/methodorders/DefaultOrderOfExecutionUnitTest.java index 15b07ee03a..c269a0e9b6 100644 --- a/junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/methodorders/DefaultOrderOfExecutionUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.junit5; +package com.baeldung.methodorders; import static org.junit.Assert.assertEquals; @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.DEFAULT) -public class DefaultOrderOfExecutionTest { +public class DefaultOrderOfExecutionUnitTest { private static StringBuilder output = new StringBuilder(""); @Test diff --git a/junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/methodorders/JVMOrderOfExecutionUnitTest.java similarity index 84% rename from junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/methodorders/JVMOrderOfExecutionUnitTest.java index 189efc8945..c4996dacf3 100644 --- a/junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/methodorders/JVMOrderOfExecutionUnitTest.java @@ -1,11 +1,11 @@ -package com.baeldung.junit5; +package com.baeldung.methodorders; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.JVM) -public class JVMOrderOfExecutionTest { +public class JVMOrderOfExecutionUnitTest { private static StringBuilder output = new StringBuilder(""); diff --git a/junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/methodorders/NameAscendingOrderOfExecutionUnitTest.java similarity index 87% rename from junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/methodorders/NameAscendingOrderOfExecutionUnitTest.java index 88de057fc8..032bc81779 100644 --- a/junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/methodorders/NameAscendingOrderOfExecutionUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.junit5; +package com.baeldung.methodorders; import static org.junit.Assert.assertEquals; @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class NameAscendingOrderOfExecutionTest { +public class NameAscendingOrderOfExecutionUnitTest { private static StringBuilder output = new StringBuilder(""); @Test diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/AssumptionUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssumptionUnitTest.java similarity index 69% rename from testing-modules/junit-5/src/test/java/com/baeldung/AssumptionUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssumptionUnitTest.java index 7d67d93486..80201a3f44 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/AssumptionUnitTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssumptionUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.migration.junit5; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assumptions.assumeFalse; @@ -10,19 +10,19 @@ import org.junit.jupiter.api.Test; public class AssumptionUnitTest { @Test - void trueAssumption() { - assumeTrue(5 > 1); + public void trueAssumption() { + assumeTrue(5 > 1, () -> "5 is greater the 1"); assertEquals(5 + 2, 7); } @Test - void falseAssumption() { - assumeFalse(5 < 1); + public void falseAssumption() { + assumeFalse(5 < 1, () -> "5 is less then 1"); assertEquals(5 + 2, 7); } @Test - void assumptionThat() { + public void assumptionThat() { String someString = "Just a string"; assumingThat(someString.equals("Just a string"), () -> assertEquals(2 + 2, 4)); } diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/FirstUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/FirstUnitTest.java new file mode 100644 index 0000000000..835132240e --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/FirstUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.runfromjava; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class FirstUnitTest { + + @Test + void whenThis_thenThat() { + assertTrue(true); + } + + @Test + void whenSomething_thenSomething() { + assertTrue(true); + } + + @Test + void whenSomethingElse_thenSomethingElse() { + assertTrue(true); + } + +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/RunJUnit5TestsFromJava.java b/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/RunJUnit5TestsFromJava.java new file mode 100644 index 0000000000..309c1bc8c9 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/RunJUnit5TestsFromJava.java @@ -0,0 +1,59 @@ +package com.baeldung.runfromjava; + +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.PrintWriter; + +import static org.junit.platform.engine.discovery.ClassNameFilter.includeClassNamePatterns; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage; + +public class RunJUnit5TestsFromJava { + SummaryGeneratingListener listener = new SummaryGeneratingListener(); + + public void runOne() { + LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder + .request() + .selectors(selectClass(FirstUnitTest.class)) + .build(); + Launcher launcher = LauncherFactory.create(); + TestPlan testPlan = launcher.discover(request); + + launcher.registerTestExecutionListeners(listener); + launcher.execute(request); + } + + public void runAll() { + LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder + .request() + .selectors(selectPackage("com.baeldung.runfromjava")) + .filters(includeClassNamePatterns(".*Test")) + .build(); + Launcher launcher = LauncherFactory.create(); + + TestPlan testPlan = launcher.discover(request); + + launcher.registerTestExecutionListeners(listener); + + launcher.execute(request); + } + + public static void main(String[] args) { + RunJUnit5TestsFromJava runner = new RunJUnit5TestsFromJava(); + runner.runAll(); + + TestExecutionSummary summary = runner.listener.getSummary(); + summary.printTo(new PrintWriter(System.out)); + + runner.runOne(); + + summary = runner.listener.getSummary(); + summary.printTo(new PrintWriter(System.out)); + } +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/SecondUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/SecondUnitTest.java new file mode 100644 index 0000000000..b6a387d852 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/runfromjava/SecondUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.runfromjava; + +import org.junit.jupiter.api.RepeatedTest; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SecondUnitTest { + + @RepeatedTest(10) + void whenSomething_thenSomething() { + assertTrue(true); + } + + @RepeatedTest(5) + void whenSomethingElse_thenSomethingElse() { + assertTrue(true); + } +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/throwsexception/CalculatorUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/throwsexception/CalculatorUnitTest.java new file mode 100644 index 0000000000..ef838ed304 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/throwsexception/CalculatorUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.throwsexception; + +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class CalculatorUnitTest { + + @Test + public void whenDividerIsZero_thenDivideByZeroExceptionIsThrown() { + Calculator calculator = new Calculator(); + + assertThrows(DivideByZeroException.class, + () -> calculator.divide(10, 0)); + } + +} \ No newline at end of file diff --git a/testing-modules/junit-5/src/test/java/org/baeldung/java/customtestname/CustomNameUnitTest.java b/testing-modules/junit-5/src/test/java/org/baeldung/java/customtestname/CustomNameUnitTest.java new file mode 100644 index 0000000000..f04b825c89 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/org/baeldung/java/customtestname/CustomNameUnitTest.java @@ -0,0 +1,17 @@ +package org.baeldung.java.customtestname; + +import static org.junit.Assert.assertNotNull; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class CustomNameUnitTest { + + @ParameterizedTest + @ValueSource(strings = { "Hello", "World" }) + @DisplayName("Test Method to check that the inputs are not nullable") + void givenString_TestNullOrNot(String word) { + assertNotNull(word); + } +} diff --git a/testing-modules/junit-5/src/test/java/org/baeldung/java/parameterisedsource/ParameterizedUnitTest.java b/testing-modules/junit-5/src/test/java/org/baeldung/java/parameterisedsource/ParameterizedUnitTest.java new file mode 100644 index 0000000000..8d09161176 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/org/baeldung/java/parameterisedsource/ParameterizedUnitTest.java @@ -0,0 +1,45 @@ +package org.baeldung.java.parameterisedsource; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.EnumSet; +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + +public class ParameterizedUnitTest { + + @ParameterizedTest + @ValueSource(strings = { "Hello", "World" }) + void givenString_TestNullOrNot(String word) { + assertNotNull(word); + } + + @ParameterizedTest + @EnumSource(value = PizzaDeliveryStrategy.class, names = {"EXPRESS", "NORMAL"}) + void givenEnum_TestContainsOrNot(PizzaDeliveryStrategy timeUnit) { + assertTrue(EnumSet.of(PizzaDeliveryStrategy.EXPRESS, PizzaDeliveryStrategy.NORMAL).contains(timeUnit)); + } + + @ParameterizedTest + @MethodSource("wordDataProvider") + void givenMethodSource_TestInputStream(String argument) { + assertNotNull(argument); + } + + static Stream wordDataProvider() { + return Stream.of("foo", "bar"); + } + + @ParameterizedTest + @CsvSource({ "1, Car", "2, House", "3, Train" }) + void givenCSVSource_TestContent(int id, String word) { + assertNotNull(id); + assertNotNull(word); + } +} diff --git a/testing-modules/junit-5/src/test/java/org/baeldung/java/parameterisedsource/PizzaDeliveryStrategy.java b/testing-modules/junit-5/src/test/java/org/baeldung/java/parameterisedsource/PizzaDeliveryStrategy.java new file mode 100644 index 0000000000..ecfc7b4627 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/org/baeldung/java/parameterisedsource/PizzaDeliveryStrategy.java @@ -0,0 +1,6 @@ +package org.baeldung.java.parameterisedsource; + +public enum PizzaDeliveryStrategy { + EXPRESS, + NORMAL; +} diff --git a/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/SelectClassesSuiteUnitTest.java b/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/SelectClassesSuiteUnitTest.java new file mode 100644 index 0000000000..220897eae7 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/SelectClassesSuiteUnitTest.java @@ -0,0 +1,13 @@ +package org.baeldung.java.suite; + +import org.baeldung.java.suite.childpackage1.Class1UnitTest; +import org.baeldung.java.suite.childpackage2.Class2UnitTest; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.runner.RunWith; + +@RunWith(JUnitPlatform.class) +@SelectClasses({Class1UnitTest.class, Class2UnitTest.class}) +public class SelectClassesSuiteUnitTest { + +} diff --git a/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/SelectPackagesSuiteUnitTest.java b/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/SelectPackagesSuiteUnitTest.java new file mode 100644 index 0000000000..ae887ae43b --- /dev/null +++ b/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/SelectPackagesSuiteUnitTest.java @@ -0,0 +1,11 @@ +package org.baeldung.java.suite; + +import org.junit.platform.runner.JUnitPlatform; +import org.junit.platform.suite.api.SelectPackages; +import org.junit.runner.RunWith; + +@RunWith(JUnitPlatform.class) +@SelectPackages({ "org.baeldung.java.suite.childpackage1", "org.baeldung.java.suite.childpackage2" }) +public class SelectPackagesSuiteUnitTest { + +} diff --git a/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/childpackage1/Class1UnitTest.java b/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/childpackage1/Class1UnitTest.java new file mode 100644 index 0000000000..78469cb971 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/childpackage1/Class1UnitTest.java @@ -0,0 +1,15 @@ +package org.baeldung.java.suite.childpackage1; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.Test; + + +public class Class1UnitTest { + + @Test + public void testCase_InClass1UnitTest() { + assertTrue(true); + } + +} diff --git a/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/childpackage2/Class2UnitTest.java b/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/childpackage2/Class2UnitTest.java new file mode 100644 index 0000000000..4463ecfad9 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/org/baeldung/java/suite/childpackage2/Class2UnitTest.java @@ -0,0 +1,14 @@ +package org.baeldung.java.suite.childpackage2; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.Test; + +public class Class2UnitTest { + + @Test + public void testCase_InClass2UnitTest() { + assertTrue(true); + } + +} diff --git a/testing-modules/junit5-migration/README.md b/testing-modules/junit5-migration/README.md new file mode 100644 index 0000000000..5fe7fc1f16 --- /dev/null +++ b/testing-modules/junit5-migration/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: +- [JUnit4 -> JUnit5 migration guide](http://www.baeldung.com/junit4-junit5-migration-guide) + diff --git a/testing-modules/junit5-migration/pom.xml b/testing-modules/junit5-migration/pom.xml new file mode 100644 index 0000000000..9d9d418774 --- /dev/null +++ b/testing-modules/junit5-migration/pom.xml @@ -0,0 +1,90 @@ + + + + 4.0.0 + + junit5-migration + 1.0-SNAPSHOT + junit5-migration + JUnit 4 -> JUnit 5 migration + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + org.junit.platform + junit-platform-engine + ${junit.platform.version} + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.junit.vintage + junit-vintage-engine + ${junit.vintage.version} + test + + + org.junit.jupiter + junit-jupiter-migrationsupport + ${junit.vintage.version} + test + + + + + + + src/test/resources + true + + + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + + + java + + + + + com.baeldung.TestLauncher + + + + + + + 5.2.0 + 1.2.0 + 5.2.0 + 2.21.0 + 1.6.0 + + + diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AnnotationTestExampleUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AnnotationTestExampleUnitTest.java new file mode 100644 index 0000000000..a5f5c19c65 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AnnotationTestExampleUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.junit4; + +import com.baeldung.junit4.categories.Annotations; +import com.baeldung.junit4.categories.JUnit4UnitTest; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category(value = { Annotations.class, JUnit4UnitTest.class }) +public class AnnotationTestExampleUnitTest { + @Test(expected = Exception.class) + public void shouldRaiseAnException() throws Exception { + throw new Exception("This is my expected exception"); + } + + @Test(timeout = 1) + @Ignore + public void shouldFailBecauseTimeout() throws InterruptedException { + Thread.sleep(10); + } + +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AssertionUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AssertionUnitTest.java new file mode 100644 index 0000000000..8979c9ecbc --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AssertionUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.junit4; + +import org.junit.Assert; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.hamcrest.CoreMatchers.hasItems; +import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; + +@DisplayName("Test case for assertions") +public class AssertionUnitTest { + + @Test + @DisplayName("Arrays should be equals") + public void whenAssertingArraysEquality_thenEqual() { + char[] expected = {'J', 'u', 'p', 'i', 't', 'e', 'r'}; + char[] actual = "Jupiter".toCharArray(); + + assertArrayEquals("Arrays should be equal", expected, actual); + } + + @Test + public void givenMultipleAssertion_whenAssertingAll_thenOK() { + assertEquals("4 is 2 times 2", 4, 2 * 2); + assertEquals("java", "JAVA".toLowerCase()); + assertEquals("null is equal to null", null, null); + } + + @Test + public void testAssertThatHasItems() { + assertThat(Arrays.asList("Java", "Kotlin", "Scala"), hasItems("Java", "Kotlin")); + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AssumeUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AssumeUnitTest.java new file mode 100644 index 0000000000..f7730a3dd8 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/AssumeUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.junit4; + + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; + +public class AssumeUnitTest { + + @Test + public void trueAssumption() { + assumeTrue("5 is greater the 1", 5 > 1); + assertEquals(5 + 2, 7); + } + + @Test + public void falseAssumption() { + assumeFalse("5 is less then 1", 5 < 1); + assertEquals(5 + 2, 7); + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/ExceptionAssertionUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/ExceptionAssertionUnitTest.java new file mode 100644 index 0000000000..38e7f640a2 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/ExceptionAssertionUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.junit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ExceptionAssertionUnitTest { + + @Rule + public ExpectedException exceptionRule = ExpectedException.none(); + + @Test(expected = NullPointerException.class) + public void whenExceptionThrown_thenExpectationSatisfied() { + String test = null; + test.length(); + } + + @Test + public void whenExceptionThrown_thenRuleIsApplied() { + exceptionRule.expect(NumberFormatException.class); + exceptionRule.expectMessage("For input string"); + Integer.parseInt("1a"); + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/RuleExampleUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/RuleExampleUnitTest.java new file mode 100644 index 0000000000..35f96b4f6a --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/RuleExampleUnitTest.java @@ -0,0 +1,16 @@ +package com.baeldung.junit4; + +import org.junit.Rule; +import org.junit.Test; + +public class RuleExampleUnitTest { + + @Rule + public final TraceUnitTestRule traceRuleTests = new TraceUnitTestRule(); + + @Test + public void whenTracingTests() { + System.out.println("This is my test"); + /*...*/ + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/TestAnnotationsUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/TestAnnotationsUnitTest.java new file mode 100644 index 0000000000..89c33cafe6 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/TestAnnotationsUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.junit4; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; + +import java.util.logging.Logger; + +public class TestAnnotationsUnitTest { + + private static final Logger log = Logger.getLogger(TestAnnotationsUnitTest.class.getName()); + + @BeforeClass + static void setup() { + log.info("@BeforeAll - executes once before all test methods in this class"); + } + + @Before + void init() { + log.info("@BeforeEach - executes before each test method in this class"); + } + + @After + void tearDown() { + log.info("@AfterEach - executed after each test method."); + } + + @AfterClass + static void done() { + log.info("@AfterAll - executed after all test methods."); + } + +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/TraceUnitTestRule.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/TraceUnitTestRule.java new file mode 100644 index 0000000000..9f4811da3d --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/TraceUnitTestRule.java @@ -0,0 +1,35 @@ +package com.baeldung.junit4; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.MultipleFailureException; +import org.junit.runners.model.Statement; + +import java.util.ArrayList; +import java.util.List; + +public class TraceUnitTestRule implements TestRule { + + @Override + public Statement apply(Statement base, Description description) { + + return new Statement() { + @Override + public void evaluate() throws Throwable { + List errors = new ArrayList(); + + System.out.println("Starting test ... " + description.getMethodName()); + try { + base.evaluate(); + } catch (Throwable e) { + errors.add(e); + } finally { + System.out.println("... test finished. " + description.getMethodName()); + } + + MultipleFailureException.assertEmpty(errors); + } + }; + } + +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/categories/Annotations.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/categories/Annotations.java new file mode 100644 index 0000000000..22214d95b6 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/categories/Annotations.java @@ -0,0 +1,5 @@ +package com.baeldung.junit4.categories; + +public interface Annotations { + +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/categories/JUnit4UnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/categories/JUnit4UnitTest.java new file mode 100644 index 0000000000..a7474d5f24 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit4/categories/JUnit4UnitTest.java @@ -0,0 +1,5 @@ +package com.baeldung.junit4.categories; + +public interface JUnit4UnitTest { + +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AnnotationTestExampleUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AnnotationTestExampleUnitTest.java new file mode 100644 index 0000000000..16de0be9d8 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AnnotationTestExampleUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +import java.time.Duration; + +@Tag("annotations") +@Tag("junit5") +@RunWith(JUnitPlatform.class) +public class AnnotationTestExampleUnitTest { + @Test + public void shouldRaiseAnException() throws Exception { + Assertions.assertThrows(Exception.class, () -> { + throw new Exception("This is my expected exception"); + }); + } + + @Test + @Disabled + public void shouldFailBecauseTimeout() throws InterruptedException { + Assertions.assertTimeout(Duration.ofMillis(1), () -> Thread.sleep(10)); + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java new file mode 100644 index 0000000000..d1d08c6e62 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DisplayName("Test case for assertions") +public class AssertionUnitTest { + + @Test + @DisplayName("Arrays should be equals") + public void whenAssertingArraysEquality_thenEqual() { + char[] expected = {'J', 'u', 'p', 'i', 't', 'e', 'r'}; + char[] actual = "Jupiter".toCharArray(); + + assertArrayEquals(expected, actual, "Arrays should be equal"); + } + + @Test + @DisplayName("The area of two polygons should be equal") + public void whenAssertingEquality_thenEqual() { + float square = 2 * 2; + float rectangle = 2 * 2; + + assertEquals(square, rectangle); + } + + @Test + public void givenMultipleAssertion_whenAssertingAll_thenOK() { + assertAll( + "heading", + () -> assertEquals(4, 2 * 2, "4 is 2 times 2"), + () -> assertEquals("java", "JAVA".toLowerCase()), + () -> assertEquals(null, null, "null is equal to null") + ); + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssumptionUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssumptionUnitTest.java new file mode 100644 index 0000000000..4f3d827403 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssumptionUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assumptions.*; + +public class AssumptionUnitTest { + + @Test + public void trueAssumption() { + assumeTrue(5 > 1, () -> "5 is greater the 1"); + assertEquals(5 + 2, 7); + } + + @Test + public void falseAssumption() { + assumeFalse(5 < 1, () -> "5 is less then 1"); + assertEquals(5 + 2, 7); + } + + @Test + public void assumptionThat() { + String someString = "Just a string"; + assumingThat(someString.equals("Just a string"), () -> assertEquals(2 + 2, 4)); + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/ConditionalExecutionUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/ConditionalExecutionUnitTest.java new file mode 100644 index 0000000000..7f76e237f1 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/ConditionalExecutionUnitTest.java @@ -0,0 +1,69 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.*; + +import static org.junit.jupiter.api.Assertions.*; + +public class ConditionalExecutionUnitTest { + + @Test + @EnabledOnOs({OS.MAC}) + void whenOperatingSystemIsMac_thenTestIsEnabled() { + assertEquals(5 + 2, 7); + } + + @Test + @DisabledOnOs({OS.WINDOWS}) + void whenOperatingSystemIsWindows_thenTestIsDisabled() { + assertEquals(5 + 2, 7); + } + + @Test + @EnabledOnJre({JRE.JAVA_8}) + void whenRunningTestsOnJRE8_thenTestIsEnabled() { + assertTrue(5 > 4, "5 is greater the 4"); + assertTrue(null == null, "null is equal to null"); + } + + @Test + @DisabledOnJre({JRE.JAVA_10}) + void whenRunningTestsOnJRE10_thenTestIsDisabled() { + assertTrue(5 > 4, "5 is greater the 4"); + assertTrue(null == null, "null is equal to null"); + } + + @Test + @EnabledIfSystemProperty(named = "os.arch", matches = ".*64.*") + public void whenRunningTestsOn64BitArchitectures_thenTestIsDisabled() { + Integer value = 5; // result of an algorithm + + assertNotEquals(0, value, "The result cannot be 0"); + } + + @Test + @DisabledIfSystemProperty(named = "ci-server", matches = "true") + public void whenRunningTestsOnCIServer_thenTestIsDisabled() { + Integer value = 5; // result of an algorithm + + assertNotEquals(0, value, "The result cannot be 0"); + } + + @Test + @EnabledIfEnvironmentVariable(named = "ENV", matches = "staging-server") + public void whenRunningTestsStagingServer_thenTestIsEnabled() { + char[] expected = {'J', 'u', 'p', 'i', 't', 'e', 'r'}; + char[] actual = "Jupiter".toCharArray(); + + assertArrayEquals(expected, actual, "Arrays should be equal"); + } + + @Test + @DisabledIfEnvironmentVariable(named = "ENV", matches = ".*development.*") + public void whenRunningTestsDevelopmentEnvironment_thenTestIsDisabled() { + char[] expected = {'J', 'u', 'p', 'i', 't', 'e', 'r'}; + char[] actual = "Jupiter".toCharArray(); + + assertArrayEquals(expected, actual, "Arrays should be equal"); + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/NestedUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/NestedUnitTest.java new file mode 100644 index 0000000000..9eeff471ba --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/NestedUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.*; + +import java.util.EmptyStackException; +import java.util.Stack; + +public class NestedUnitTest { + + Stack stack; + + @Test + @DisplayName("is instantiated with new Stack()") + void isInstantiatedWithNew() { + new Stack<>(); + } + + @Nested + @DisplayName("when new") + class WhenNew { + + @BeforeEach + void init() { + stack = new Stack<>(); + } + + @Test + @DisplayName("is empty") + void isEmpty() { + Assertions.assertTrue(stack.isEmpty()); + } + + @Test + @DisplayName("throws EmptyStackException when popped") + void throwsExceptionWhenPopped() { + Assertions.assertThrows(EmptyStackException.class, () -> stack.pop()); + } + + @Test + @DisplayName("throws EmptyStackException when peeked") + void throwsExceptionWhenPeeked() { + Assertions.assertThrows(EmptyStackException.class, () -> stack.peek()); + } + + @Nested + @DisplayName("after pushing an element") + class AfterPushing { + + String anElement = "an element"; + + @BeforeEach + void init() { + stack.push(anElement); + } + + @Test + @DisplayName("it is no longer empty") + void isEmpty() { + Assertions.assertFalse(stack.isEmpty()); + } + + @Test + @DisplayName("returns the element when popped and is empty") + void returnElementWhenPopped() { + Assertions.assertEquals(anElement, stack.pop()); + Assertions.assertTrue(stack.isEmpty()); + } + + @Test + @DisplayName("returns the element when peeked but remains not empty") + void returnElementWhenPeeked() { + Assertions.assertEquals(anElement, stack.peek()); + Assertions.assertFalse(stack.isEmpty()); + } + } + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleExampleUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleExampleUnitTest.java new file mode 100644 index 0000000000..297d0f1730 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +@RunWith(JUnitPlatform.class) +@ExtendWith(TraceUnitExtension.class) +public class RuleExampleUnitTest { + + @Test + public void whenTracingTests() { + System.out.println("This is my test"); + /*...*/ + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleMigrationSupportUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleMigrationSupportUnitTest.java new file mode 100644 index 0000000000..bbaa42ec7b --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/RuleMigrationSupportUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.junit5; + +import org.junit.Rule; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport; +import org.junit.rules.ExpectedException; + +@EnableRuleMigrationSupport +public class RuleMigrationSupportUnitTest { + + @Rule + public ExpectedException exceptionRule = ExpectedException.none(); + + @Test + public void whenExceptionThrown_thenExpectationSatisfied() { + exceptionRule.expect(NullPointerException.class); + String test = null; + test.length(); + } + + @Test + public void whenExceptionThrown_thenRuleIsApplied() { + exceptionRule.expect(NumberFormatException.class); + exceptionRule.expectMessage("For input string"); + Integer.parseInt("1a"); + } +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/TestAnnotationsUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/TestAnnotationsUnitTest.java new file mode 100644 index 0000000000..8daf952747 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/TestAnnotationsUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.*; + +import java.util.logging.Logger; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestAnnotationsUnitTest { + + private static final Logger log = Logger.getLogger(TestAnnotationsUnitTest.class.getName()); + + @BeforeAll + static void setup() { + log.info("@BeforeAll - executes once before all test methods in this class"); + } + + @BeforeEach + void init() { + log.info("@BeforeEach - executes before each test method in this class"); + } + + @Test + @Disabled + void disabledTest() { + assertTrue(false); + } + + @AfterEach + void tearDown() { + log.info("@AfterEach - executed after each test method."); + } + + @AfterAll + static void done() { + log.info("@AfterAll - executed after all test methods."); + } + +} diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/TraceUnitExtension.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/TraceUnitExtension.java new file mode 100644 index 0000000000..bd5ae47d63 --- /dev/null +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/TraceUnitExtension.java @@ -0,0 +1,19 @@ +package com.baeldung.junit5; + +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +public class TraceUnitExtension implements AfterEachCallback, BeforeEachCallback { + + @Override + public void beforeEach(ExtensionContext context) throws Exception { + System.out.println("Starting test ... " + context.getDisplayName()); + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + System.out.println("... test finished. " + context.getDisplayName()); + } + +} diff --git a/testing-modules/mockito-2/pom.xml b/testing-modules/mockito-2/pom.xml index f51919858f..cab4d7977b 100644 --- a/testing-modules/mockito-2/pom.xml +++ b/testing-modules/mockito-2/pom.xml @@ -1,5 +1,5 @@ + 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 mockito-2 @@ -15,9 +15,6 @@ - UTF-8 - - - 2.8.9 + 2.21.0 diff --git a/testing-modules/mockito-2/src/main/resources/logback.xml b/testing-modules/mockito-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/mockito-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/mockito/README.md b/testing-modules/mockito/README.md index 05cc7ca936..e1b9c27523 100644 --- a/testing-modules/mockito/README.md +++ b/testing-modules/mockito/README.md @@ -18,3 +18,4 @@ - [Hamcrest File Matchers](http://www.baeldung.com/hamcrest-file-matchers) - [Hamcrest Custom Matchers](http://www.baeldung.com/hamcrest-custom-matchers) - [Hamcrest Common Core Matchers](http://www.baeldung.com/hamcrest-core-matchers) +- [Testing Callbacks with Mockito](http://www.baeldung.com/mockito-callbacks) diff --git a/testing-modules/mockito/pom.xml b/testing-modules/mockito/pom.xml index c2e5b4bf31..acdd7eb2ac 100644 --- a/testing-modules/mockito/pom.xml +++ b/testing-modules/mockito/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung mockito @@ -9,11 +9,32 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../../parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + org.springframework + spring-core + ${spring-framework.version} + + + org.springframework + spring-context + ${spring-framework.version} + + + org.springframework.data + spring-data-jpa + ${spring-data.version} + + + org.eclipse.persistence + javax.persistence + 2.1.1 + @@ -23,8 +44,6 @@ ${commons-lang3.version} - - @@ -39,13 +58,24 @@ ${powermock.version} test - org.hamcrest java-hamcrest ${hamcrest.version} + + org.springframework.boot + spring-boot-starter + ${spring-boot.version} + test + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + @@ -56,10 +86,12 @@ true - + 2.0.4.RELEASE + 5.0.8.RELEASE + 2.0.9.RELEASE 19.0 3.5 @@ -67,7 +99,6 @@ 1.7.0 2.0.0.0 - \ No newline at end of file diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoSpyIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoSpyIntegrationTest.java index 206e0f4daf..118d50ea40 100644 --- a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoSpyIntegrationTest.java +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoSpyIntegrationTest.java @@ -1,15 +1,15 @@ package org.baeldung.mockito; +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.Spy; -import org.mockito.runners.MockitoJUnitRunner; - -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertEquals; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class MockitoSpyIntegrationTest { diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsUnitTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsUnitTest.java index 49360f8d6c..b020338fd9 100644 --- a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsUnitTest.java +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsUnitTest.java @@ -1,14 +1,22 @@ package org.baeldung.mockito; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + import org.junit.Test; import org.junit.runner.RunWith; -import static org.junit.Assert.assertEquals; - -import static org.mockito.Mockito.*; import org.mockito.ArgumentCaptor; -import static org.mockito.Matchers.any; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; -import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class MockitoVoidMethodsUnitTest { diff --git a/testing-modules/mocks/README.md b/testing-modules/mocks/README.md index fe8e197061..2b24ed8536 100644 --- a/testing-modules/mocks/README.md +++ b/testing-modules/mocks/README.md @@ -5,4 +5,4 @@ - [JMockit 101](http://www.baeldung.com/jmockit-101) - [Mockito vs EasyMock vs JMockit](http://www.baeldung.com/mockito-vs-easymock-vs-jmockit) - [EasyMock Argument Matchers](http://www.baeldung.com/easymock-argument-matchers) - +- [Mock Static Method using JMockit](https://www.baeldung.com/jmockit-static-method) diff --git a/testing-modules/mocks/jmockit/pom.xml b/testing-modules/mocks/jmockit/pom.xml index 0ce0818ca3..12bbe6b60d 100644 --- a/testing-modules/mocks/jmockit/pom.xml +++ b/testing-modules/mocks/jmockit/pom.xml @@ -1,6 +1,8 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + jmockit + jmockit com.baeldung @@ -9,13 +11,6 @@ ../ - jmockit - jmockit - - - 1.24 - - org.jmockit @@ -35,4 +30,8 @@ + + 1.24 + + \ No newline at end of file diff --git a/testing-modules/mocks/jmockit/src/main/java/com/baeldung/mocks/jmockit/AppManager.java b/testing-modules/mocks/jmockit/src/main/java/com/baeldung/mocks/jmockit/AppManager.java new file mode 100644 index 0000000000..615650ea6d --- /dev/null +++ b/testing-modules/mocks/jmockit/src/main/java/com/baeldung/mocks/jmockit/AppManager.java @@ -0,0 +1,26 @@ +package com.baeldung.mocks.jmockit; + +import java.util.Random; + +public class AppManager { + + public boolean managerResponse(String question) { + return AppManager.isResponsePositive(question); + } + + public static boolean isResponsePositive(String value) { + if (value == null) + return false; + int orgLength = value.length(); + int randomNumber = randomNumber(); + return orgLength == randomNumber ? true : false; + } + + private static int randomNumber() { + return new Random().nextInt(7); + } + + private static Integer stringToInteger(String num) { + return Integer.parseInt(num); + } +} diff --git a/testing-modules/mocks/jmockit/src/main/resources/logback.xml b/testing-modules/mocks/jmockit/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/mocks/jmockit/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/mocks/jmockit/src/test/java/com/baeldung/mocks/jmockit/AppManagerUnitTest.java b/testing-modules/mocks/jmockit/src/test/java/com/baeldung/mocks/jmockit/AppManagerUnitTest.java new file mode 100644 index 0000000000..2c5aa2a3ed --- /dev/null +++ b/testing-modules/mocks/jmockit/src/test/java/com/baeldung/mocks/jmockit/AppManagerUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.mocks.jmockit; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import mockit.Deencapsulation; +import mockit.Mock; +import mockit.MockUp; + +public class AppManagerUnitTest { + + private AppManager appManager; + + @BeforeEach + public void setUp() { + appManager = new AppManager(); + } + + @Test + public void givenAppManager_whenStaticMethodCalled_thenValidateExpectedResponse() { + new MockUp() { + @Mock + public boolean isResponsePositive(String value) { + return false; + } + }; + + Assertions.assertFalse(appManager.managerResponse("Why are you coming late?")); + } + + @Test + public void givenAppManager_whenPrivateStaticMethod_thenValidateExpectedResponse() { + final int response = Deencapsulation.invoke(AppManager.class, "stringToInteger", "110"); + Assertions.assertEquals(110, response); + } + + @Test + public void givenAppManager_whenPrivateStaticMethod_thenExpectException() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { + Deencapsulation.invoke(AppManager.class, "stringToInteger", "11r"); + }); + } +} diff --git a/testing-modules/mocks/mock-comparisons/pom.xml b/testing-modules/mocks/mock-comparisons/pom.xml index 9328639ad8..ae36280300 100644 --- a/testing-modules/mocks/mock-comparisons/pom.xml +++ b/testing-modules/mocks/mock-comparisons/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 mock-comparisons mock-comparisons @@ -46,10 +46,10 @@ - 2.9.0 + 2.21.0 3.5.1 - 1.34 - UTF-8 + 1.41 + - \ No newline at end of file + diff --git a/testing-modules/mocks/mock-comparisons/src/main/resources/logback.xml b/testing-modules/mocks/mock-comparisons/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/mocks/mock-comparisons/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/mocks/pom.xml b/testing-modules/mocks/pom.xml index b005164413..6473f07c13 100644 --- a/testing-modules/mocks/pom.xml +++ b/testing-modules/mocks/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 diff --git a/testing-modules/mockserver/pom.xml b/testing-modules/mockserver/pom.xml index 96c86a23d7..c2fa2870e2 100644 --- a/testing-modules/mockserver/pom.xml +++ b/testing-modules/mockserver/pom.xml @@ -1,7 +1,6 @@ - + 4.0.0 com.baeldung mockserver @@ -20,13 +19,11 @@ mockserver-netty ${mock-sever-netty-version} - org.mock-server mockserver-client-java ${mock-sever-netty-version} - org.apache.httpcomponents httpclient diff --git a/testing-modules/mockserver/src/main/resources/logback.xml b/testing-modules/mockserver/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/mockserver/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/parallel-tests-junit/math-test-functions/pom.xml b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml new file mode 100644 index 0000000000..18d2b562f3 --- /dev/null +++ b/testing-modules/parallel-tests-junit/math-test-functions/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + com.baeldung + parallel-tests-junit + 0.0.1-SNAPSHOT + + math-test-functions + math-test-functions + http://maven.apache.org + + UTF-8 + + + + junit + junit + 4.12 + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.0 + + all + 10 + 2 + 2 + 6 + 3.5 + 5 + true + + FunctionTestSuite.class + + + + + + diff --git a/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/ArithmeticFunctionTest.java b/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/ArithmeticFunctionTest.java new file mode 100644 index 0000000000..df0aa695fc --- /dev/null +++ b/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/ArithmeticFunctionTest.java @@ -0,0 +1,28 @@ +package com.baeldung; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class ArithmeticFunctionTest { + + @Test + public void test_addingIntegers_returnsSum() { + assertEquals(22, Math.addExact(10, 12)); + } + + @Test + public void test_multiplyingIntegers_returnsProduct() { + assertEquals(120, Math.multiplyExact(10, 12)); + } + + @Test + public void test_subtractingIntegers_returnsDifference() { + assertEquals(2, Math.subtractExact(12, 10)); + } + + @Test + public void test_minimumInteger() { + assertEquals(10, Math.min(10, 12)); + } +} diff --git a/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/ComparisonFunctionTest.java b/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/ComparisonFunctionTest.java new file mode 100644 index 0000000000..4f72c87279 --- /dev/null +++ b/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/ComparisonFunctionTest.java @@ -0,0 +1,19 @@ +package com.baeldung; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class ComparisonFunctionTest { + + @Test + public void test_findMax() { + assertEquals(20, Math.max(10, 20)); + } + + @Test + public void test_findMin() { + assertEquals(10, Math.min(10, 20)); + } + +} diff --git a/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/FunctionTestSuite.java b/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/FunctionTestSuite.java new file mode 100644 index 0000000000..4fe551b365 --- /dev/null +++ b/testing-modules/parallel-tests-junit/math-test-functions/src/test/java/com/baeldung/FunctionTestSuite.java @@ -0,0 +1,11 @@ +package com.baeldung; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ ComparisonFunctionTest.class, ArithmeticFunctionTest.class }) +public class FunctionTestSuite { + +} diff --git a/testing-modules/parallel-tests-junit/pom.xml b/testing-modules/parallel-tests-junit/pom.xml new file mode 100644 index 0000000000..3fd4e695e5 --- /dev/null +++ b/testing-modules/parallel-tests-junit/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + com.baeldung + parallel-tests-junit + 0.0.1-SNAPSHOT + pom + + math-test-functions + string-test-functions + + diff --git a/testing-modules/parallel-tests-junit/string-test-functions/pom.xml b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml new file mode 100644 index 0000000000..af61cfce8e --- /dev/null +++ b/testing-modules/parallel-tests-junit/string-test-functions/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + com.baeldung + parallel-tests-junit + 0.0.1-SNAPSHOT + + string-test-functions + string-test-functions + http://maven.apache.org + + UTF-8 + + + + + junit + junit + 4.12 + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.0 + + all + true + 2 + + + + + diff --git a/testing-modules/parallel-tests-junit/string-test-functions/src/test/java/com/baeldung/StringFunctionTest.java b/testing-modules/parallel-tests-junit/string-test-functions/src/test/java/com/baeldung/StringFunctionTest.java new file mode 100644 index 0000000000..7f2bc5e5e7 --- /dev/null +++ b/testing-modules/parallel-tests-junit/string-test-functions/src/test/java/com/baeldung/StringFunctionTest.java @@ -0,0 +1,18 @@ +package com.baeldung; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class StringFunctionTest { + + @Test + public void test_upperCase() { + assertEquals("TESTCASE", "testCase".toUpperCase()); + } + + @Test + public void test_indexOf() { + assertEquals(1, "testCase".indexOf("e")); + } +} diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml index 3452cdae22..ed7e5e3577 100644 --- a/testing-modules/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung rest-assured @@ -9,8 +9,8 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../../parent-java + 0.0.1-SNAPSHOT + ../../parent-java @@ -168,7 +168,6 @@ commons-collections ${commons-collections.version} - @@ -181,7 +180,6 @@ 1.4.7 9.4.0.v20161208 - 3.5 3.2.2 diff --git a/testing-modules/rest-testing/pom.xml b/testing-modules/rest-testing/pom.xml index 8ebe86b9bb..9bfd715682 100644 --- a/testing-modules/rest-testing/pom.xml +++ b/testing-modules/rest-testing/pom.xml @@ -1,17 +1,17 @@ + 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 rest-testing 0.1-SNAPSHOT - rest-testing com.baeldung parent-java - 0.0.1-SNAPSHOT - ../../parent-java + 0.0.1-SNAPSHOT + ../../parent-java @@ -106,6 +106,46 @@ true + + + + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + classes + 4 + + + + + integration-test + verify + + + + + + com.github.temyers + cucumber-jvm-parallel-plugin + 5.0.0 + + + generateRunners + generate-test-sources + + generateRunners + + + + com.baeldung.rest.cucumber + + src/test/resources/Feature/ + SCENARIO + + + + + @@ -116,7 +156,6 @@ 19.0 3.5 - 2.5 2.9.0 @@ -131,7 +170,6 @@ 2.6 - \ No newline at end of file diff --git a/testing-modules/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java index b461da8403..35a913ae25 100644 --- a/testing-modules/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java +++ b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java @@ -1,19 +1,5 @@ package com.baeldung.rest.cucumber; -import com.github.tomakehurst.wiremock.WireMockServer; -import cucumber.api.java.en.Then; -import cucumber.api.java.en.When; -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 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.configureFor; import static com.github.tomakehurst.wiremock.client.WireMock.containing; @@ -25,10 +11,27 @@ import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import java.io.IOException; +import java.io.InputStream; +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 com.github.tomakehurst.wiremock.WireMockServer; + +import cucumber.api.java.en.Then; +import cucumber.api.java.en.When; + public class StepDefinition { private static final String CREATE_PATH = "/create"; @@ -37,20 +40,20 @@ public class StepDefinition { private final InputStream jsonInputStream = this.getClass().getClassLoader().getResourceAsStream("cucumber.json"); private final String jsonString = new Scanner(jsonInputStream, "UTF-8").useDelimiter("\\Z").next(); - private final WireMockServer wireMockServer = new WireMockServer(); + private final WireMockServer wireMockServer = new WireMockServer(options().dynamicPort()); private final CloseableHttpClient httpClient = HttpClients.createDefault(); @When("^users upload data on a project$") public void usersUploadDataOnAProject() throws IOException { wireMockServer.start(); - configureFor("localhost", 8080); + configureFor("localhost", wireMockServer.port()); stubFor(post(urlEqualTo(CREATE_PATH)) .withHeader("content-type", equalTo(APPLICATION_JSON)) .withRequestBody(containing("testing-framework")) .willReturn(aResponse().withStatus(200))); - HttpPost request = new HttpPost("http://localhost:8080/create"); + HttpPost request = new HttpPost("http://localhost:" + wireMockServer.port() + "/create"); StringEntity entity = new StringEntity(jsonString); request.addHeader("content-type", APPLICATION_JSON); request.setEntity(entity); @@ -67,11 +70,11 @@ public class StepDefinition { public void usersGetInformationOnAProject(String projectName) throws IOException { wireMockServer.start(); - configureFor("localhost", 8080); + configureFor("localhost", wireMockServer.port()); stubFor(get(urlEqualTo("/projects/cucumber")).withHeader("accept", equalTo(APPLICATION_JSON)) .willReturn(aResponse().withBody(jsonString))); - HttpGet request = new HttpGet("http://localhost:8080/projects/" + projectName.toLowerCase()); + HttpGet request = new HttpGet("http://localhost:" + wireMockServer.port() + "/projects/" + projectName.toLowerCase()); request.addHeader("accept", APPLICATION_JSON); HttpResponse httpResponse = httpClient.execute(request); String responseString = convertResponseToString(httpResponse); diff --git a/testing-modules/rest-testing/src/test/resources/Feature/cucumber.feature b/testing-modules/rest-testing/src/test/resources/Feature/cucumber.feature new file mode 100644 index 0000000000..99dd8249fe --- /dev/null +++ b/testing-modules/rest-testing/src/test/resources/Feature/cucumber.feature @@ -0,0 +1,10 @@ +Feature: Testing a REST API + Users should be able to submit GET and POST requests to a web service, represented by WireMock + + Scenario: Data Upload to a web service + When users upload data on a project + Then the server should handle it and return a success status + + Scenario: Data retrieval from a web service + When users want to get information on the Cucumber project + Then the requested data is returned \ No newline at end of file diff --git a/testing-modules/runjunitfromjava/src/main/resources/logback.xml b/testing-modules/runjunitfromjava/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/runjunitfromjava/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit4/runfromjava/FirstUnitTest.java b/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit4/runfromjava/FirstUnitTest.java new file mode 100644 index 0000000000..588a1e5d66 --- /dev/null +++ b/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit4/runfromjava/FirstUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.junit4.runfromjava; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + + +public class FirstUnitTest { + + @Test + public void whenThis_thenThat() { + assertTrue(true); + } + + @Test + public void whenSomething_thenSomething() { + assertTrue(true); + } + + @Test + public void whenSomethingElse_thenSomethingElse() { + assertTrue(true); + } + +} diff --git a/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit4/runfromjava/SecondUnitTest.java b/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit4/runfromjava/SecondUnitTest.java new file mode 100644 index 0000000000..e2d75021cf --- /dev/null +++ b/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit4/runfromjava/SecondUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.junit4.runfromjava; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class SecondUnitTest { + + @Test + public void whenSomething_thenSomething() { + assertTrue(true); + } + + @Test + public void whensomethingElse_thenSomethingElse() { + assertTrue(true); + } +} diff --git a/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit5/runfromjava/FirstUnitTest.java b/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit5/runfromjava/FirstUnitTest.java new file mode 100644 index 0000000000..57c505781d --- /dev/null +++ b/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit5/runfromjava/FirstUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.junit5.runfromjava; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class FirstUnitTest { + + @Test + void whenThis_thenThat() { + assertTrue(true); + } + + @Test + void whenSomething_thenSomething() { + assertTrue(true); + } + + @Test + void whenSomethingElse_thenSomethingElse() { + assertTrue(true); + } + +} diff --git a/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit5/runfromjava/SecondUnitTest.java b/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit5/runfromjava/SecondUnitTest.java new file mode 100644 index 0000000000..fbfb68898b --- /dev/null +++ b/testing-modules/runjunitfromjava/src/test/java/com/baeldung/junit5/runfromjava/SecondUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.junit5.runfromjava; + +import org.junit.jupiter.api.RepeatedTest; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SecondUnitTest { + + @RepeatedTest(10) + void whenSomething_thenSomething() { + assertTrue(true); + } + + @RepeatedTest(5) + void whenSomethingElse_thenSomethingElse() { + assertTrue(true); + } +} diff --git a/testing-modules/selenium-junit-testng/pom.xml b/testing-modules/selenium-junit-testng/pom.xml index 194871b58e..e22f7421cf 100644 --- a/testing-modules/selenium-junit-testng/pom.xml +++ b/testing-modules/selenium-junit-testng/pom.xml @@ -1,5 +1,5 @@ + 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 selenium-junit-testng @@ -12,29 +12,6 @@ ../../ - - src - - - - live - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - **/*LiveTest.java - - - - - - - - org.seleniumhq.selenium @@ -60,10 +37,34 @@ org.hamcrest hamcrest-all - 1.3 + ${org.hamcrest.version} + + src + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*LiveTest.java + + + + + + + + 6.10 3.4.0 diff --git a/testing-modules/selenium-junit-testng/src/main/resources/logback.xml b/testing-modules/selenium-junit-testng/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/selenium-junit-testng/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/spring-testing/README.md b/testing-modules/spring-testing/README.md new file mode 100644 index 0000000000..e22c3e84e7 --- /dev/null +++ b/testing-modules/spring-testing/README.md @@ -0,0 +1,4 @@ +### Relevant Articles: + +- [Mockito.mock() vs @Mock vs @MockBean](http://www.baeldung.com/java-spring-mockito-mock-mockbean) +- [A Quick Guide to @TestPropertySource](https://www.baeldung.com/spring-test-property-source) diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml new file mode 100644 index 0000000000..a137bc8d33 --- /dev/null +++ b/testing-modules/spring-testing/pom.xml @@ -0,0 +1,75 @@ + + 4.0.0 + org.baeldung + spring-testing + 0.1-SNAPSHOT + spring-testing + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + + + + + + org.hamcrest + java-hamcrest + ${hamcrest.version} + + + + org.springframework.boot + spring-boot-starter + LATEST + test + + + org.springframework.boot + spring-boot-starter-test + LATEST + test + + + org.springframework + spring-core + LATEST + + + org.springframework + spring-context + LATEST + + + org.eclipse.persistence + javax.persistence + 2.1.1 + + + org.springframework.data + spring-data-jpa + LATEST + + + + + spring-testing + + + src/main/resources + true + + + + + + + + 2.0.0.0 + + + \ No newline at end of file diff --git a/testing-modules/spring-testing/src/main/java/com/baeldung/testpropertysource/ClassUsingProperty.java b/testing-modules/spring-testing/src/main/java/com/baeldung/testpropertysource/ClassUsingProperty.java new file mode 100644 index 0000000000..d545daf0df --- /dev/null +++ b/testing-modules/spring-testing/src/main/java/com/baeldung/testpropertysource/ClassUsingProperty.java @@ -0,0 +1,15 @@ +package com.baeldung.testpropertysource; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class ClassUsingProperty { + + @Value("${baeldung.testpropertysource.one}") + private String propertyOne; + + public String retrievePropertyOne() { + return propertyOne; + } +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/User.java b/testing-modules/spring-testing/src/main/java/org/baeldung/mockito/repository/User.java similarity index 95% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/User.java rename to testing-modules/spring-testing/src/main/java/org/baeldung/mockito/repository/User.java index f84a10cf76..28cd4f9fb0 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/User.java +++ b/testing-modules/spring-testing/src/main/java/org/baeldung/mockito/repository/User.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package org.baeldung.mockito.repository; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -46,4 +46,4 @@ public class User { public void setStatus(Integer status) { this.status = status; } -} +} \ No newline at end of file diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java b/testing-modules/spring-testing/src/main/java/org/baeldung/mockito/repository/UserRepository.java similarity index 53% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java rename to testing-modules/spring-testing/src/main/java/org/baeldung/mockito/repository/UserRepository.java index e250a291bc..3f1952a5e7 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java +++ b/testing-modules/spring-testing/src/main/java/org/baeldung/mockito/repository/UserRepository.java @@ -1,8 +1,9 @@ -package org.baeldung.persistence.multiple.dao.user; +package org.baeldung.mockito.repository; -import org.baeldung.persistence.multiple.model.user.User; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +@Repository("userRepository") public interface UserRepository extends JpaRepository { } diff --git a/testing-modules/spring-testing/src/main/resources/logback.xml b/testing-modules/spring-testing/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/spring-testing/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.java new file mode 100644 index 0000000000..f983abdd54 --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.testpropertysource; + +import static org.assertj.core.api.Assertions.assertThat; + +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.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ClassUsingProperty.class) +@TestPropertySource +public class DefaultTestPropertySourceIntegrationTest { + + @Autowired + ClassUsingProperty classUsingProperty; + + @Test + public void givenDefaultTestPropertySource_whenVariableOneRetrieved_thenValueInDefaultFileReturned() { + String output = classUsingProperty.retrievePropertyOne(); + + assertThat(output).isEqualTo("default-value"); + } +} diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/LocationTestPropertySourceIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/LocationTestPropertySourceIntegrationTest.java new file mode 100644 index 0000000000..93d4cc58da --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/LocationTestPropertySourceIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.testpropertysource; + +import static org.assertj.core.api.Assertions.assertThat; + +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.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ClassUsingProperty.class) +@TestPropertySource(locations = "/other-location.properties") +public class LocationTestPropertySourceIntegrationTest { + + @Autowired + ClassUsingProperty classUsingProperty; + + @Test + public void givenDefaultTestPropertySource_whenVariableOneRetrieved_thenValueInDefaultFileReturned() { + String output = classUsingProperty.retrievePropertyOne(); + + assertThat(output).isEqualTo("other-location-value"); + } +} diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/PropertiesTestPropertySourceIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/PropertiesTestPropertySourceIntegrationTest.java new file mode 100644 index 0000000000..d98e2b9f98 --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/PropertiesTestPropertySourceIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.testpropertysource; + +import static org.assertj.core.api.Assertions.assertThat; + +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.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ClassUsingProperty.class) +@TestPropertySource(locations = "/other-location.properties", properties = "baeldung.testpropertysource.one=other-properties-value") +public class PropertiesTestPropertySourceIntegrationTest { + + @Autowired + ClassUsingProperty classUsingProperty; + + @Test + public void givenDefaultTestPropertySource_whenVariableOneRetrieved_thenValueInDefaultFileReturned() { + String output = classUsingProperty.retrievePropertyOne(); + + assertThat(output).isEqualTo("other-properties-value"); + } +} diff --git a/spring-boot/src/test/java/org/baeldung/MockAnnotationTest.java b/testing-modules/spring-testing/src/test/java/org/baeldung/mockito/MockAnnotationUnitTest.java similarity index 67% rename from spring-boot/src/test/java/org/baeldung/MockAnnotationTest.java rename to testing-modules/spring-testing/src/test/java/org/baeldung/mockito/MockAnnotationUnitTest.java index a70b31177f..fcc646e8ea 100644 --- a/spring-boot/src/test/java/org/baeldung/MockAnnotationTest.java +++ b/testing-modules/spring-testing/src/test/java/org/baeldung/mockito/MockAnnotationUnitTest.java @@ -1,6 +1,6 @@ -package org.baeldung; +package org.baeldung.mockito; -import org.baeldung.repository.UserRepository; +import org.baeldung.mockito.repository.UserRepository; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -9,25 +9,29 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) -public class MockAnnotationTest { +public class MockAnnotationUnitTest { @Mock UserRepository mockRepository; @Test - public void testMockAnnotation() { + public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() { Mockito.when(mockRepository.count()).thenReturn(123L); + long userCount = mockRepository.count(); + Assert.assertEquals(123L, userCount); Mockito.verify(mockRepository).count(); } @Test - public void testMockitoMockMethod() { + public void givenCountMethodOfLocalMockVariableMocked_WhenCountInvoked_ThenMockedValueReturned() { UserRepository localMockRepository = Mockito.mock(UserRepository.class); Mockito.when(localMockRepository.count()).thenReturn(111L); + long userCount = localMockRepository.count(); + Assert.assertEquals(111L, userCount); - Mockito.verify(localMockRepository).count(); + Mockito.verify(localMockRepository).count(); } } diff --git a/spring-boot/src/test/java/org/baeldung/MockBeanAnnotationIntegrationTest.java b/testing-modules/spring-testing/src/test/java/org/baeldung/mockito/MockBeanAnnotationIntegrationTest.java similarity index 83% rename from spring-boot/src/test/java/org/baeldung/MockBeanAnnotationIntegrationTest.java rename to testing-modules/spring-testing/src/test/java/org/baeldung/mockito/MockBeanAnnotationIntegrationTest.java index 0c93004a49..3a7e58fb48 100644 --- a/spring-boot/src/test/java/org/baeldung/MockBeanAnnotationIntegrationTest.java +++ b/testing-modules/spring-testing/src/test/java/org/baeldung/mockito/MockBeanAnnotationIntegrationTest.java @@ -1,6 +1,6 @@ -package org.baeldung; +package org.baeldung.mockito; -import org.baeldung.repository.UserRepository; +import org.baeldung.mockito.repository.UserRepository; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -10,7 +10,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit4.SpringRunner; - @RunWith(SpringRunner.class) public class MockBeanAnnotationIntegrationTest { @@ -21,10 +20,12 @@ public class MockBeanAnnotationIntegrationTest { ApplicationContext context; @Test - public void testMockBean() { + public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() { Mockito.when(mockRepository.count()).thenReturn(123L); + UserRepository userRepoFromContext = context.getBean(UserRepository.class); long userCount = userRepoFromContext.count(); + Assert.assertEquals(123L, userCount); Mockito.verify(mockRepository).count(); } diff --git a/testing-modules/spring-testing/src/test/resources/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.properties b/testing-modules/spring-testing/src/test/resources/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.properties new file mode 100644 index 0000000000..a443a2b776 --- /dev/null +++ b/testing-modules/spring-testing/src/test/resources/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.properties @@ -0,0 +1 @@ +baeldung.testpropertysource.one=default-value \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/resources/other-location.properties b/testing-modules/spring-testing/src/test/resources/other-location.properties new file mode 100644 index 0000000000..6ef791ec75 --- /dev/null +++ b/testing-modules/spring-testing/src/test/resources/other-location.properties @@ -0,0 +1 @@ +baeldung.testpropertysource.one=other-location-value \ No newline at end of file diff --git a/testing-modules/test-containers/README.md b/testing-modules/test-containers/README.md index 160893581d..f4f424194f 100644 --- a/testing-modules/test-containers/README.md +++ b/testing-modules/test-containers/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [Docker Test Containers in Java Tests](TODO link to be added.) +- [Docker Test Containers in Java Tests](http://www.baeldung.com/docker-test-containers) diff --git a/testing-modules/test-containers/pom.xml b/testing-modules/test-containers/pom.xml index 3551092c57..1f4c483988 100644 --- a/testing-modules/test-containers/pom.xml +++ b/testing-modules/test-containers/pom.xml @@ -1,119 +1,115 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - - test-containers - 1.0-SNAPSHOT + + test-containers + 1.0-SNAPSHOT + test-containers + Intro to Java Test Containers - test-containers - Intro to Java Test Containers + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - ../../ - + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.junit.vintage + junit-vintage-engine + ${junit.vintage.version} + test + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + + + org.testcontainers + testcontainers + ${testcontainers.version} + + + org.testcontainers + postgresql + ${testcontainers.version} + + + org.testcontainers + selenium + ${testcontainers.version} + + + org.postgresql + postgresql + ${postgresql.version} + + + org.seleniumhq.selenium + selenium-remote-driver + ${selenium-remote-driver.version} + + + + + + src/test/resources + true + + + + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + + + java + + + + + com.baeldung.TestLauncher + + + + - - - - src/test/resources - true - - - - - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - - - - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - - - java - - - - - com.baeldung.TestLauncher - - - - - - - - org.junit.platform - junit-platform-runner - ${junit.platform.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit.vintage.version} - test - - - org.apache.logging.log4j - log4j-core - ${log4j2.version} - - - org.testcontainers - testcontainers - 1.7.2 - - - org.testcontainers - postgresql - 1.7.2 - - - org.testcontainers - selenium - 1.7.2 - - - org.postgresql - postgresql - 42.2.2 - - - org.seleniumhq.selenium - selenium-remote-driver - 3.12.0 - - - - - - UTF-8 - 1.8 - 5.1.0 - 1.0.1 - 4.12.1 - 2.8.2 - 1.4.196 - 2.11.0 - - 3.7.0 - 2.19.1 - 5.0.1.RELEASE - + + 5.1.0 + 1.0.1 + 4.12.1 + 2.8.2 + 1.4.196 + 2.21.0 + 5.0.1.RELEASE + 1.7.2 + 42.2.2 + 3.12.0 + 2.21.0 + diff --git a/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/DockerComposeContainerUnitTest.java b/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/DockerComposeContainerLiveTest.java similarity index 97% rename from testing-modules/test-containers/src/test/java/com/baeldung/testconainers/DockerComposeContainerUnitTest.java rename to testing-modules/test-containers/src/test/java/com/baeldung/testconainers/DockerComposeContainerLiveTest.java index f51721ecde..438c4dee23 100644 --- a/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/DockerComposeContainerUnitTest.java +++ b/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/DockerComposeContainerLiveTest.java @@ -12,7 +12,7 @@ import org.junit.ClassRule; import org.junit.Test; import org.testcontainers.containers.DockerComposeContainer; -public class DockerComposeContainerUnitTest { +public class DockerComposeContainerLiveTest { @ClassRule public static DockerComposeContainer compose = new DockerComposeContainer( diff --git a/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/GenericContainerUnitTest.java b/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/GenericContainerLiveTest.java similarity index 97% rename from testing-modules/test-containers/src/test/java/com/baeldung/testconainers/GenericContainerUnitTest.java rename to testing-modules/test-containers/src/test/java/com/baeldung/testconainers/GenericContainerLiveTest.java index 32dbba7dcf..90b9d3a6c3 100644 --- a/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/GenericContainerUnitTest.java +++ b/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/GenericContainerLiveTest.java @@ -13,7 +13,7 @@ import org.junit.platform.commons.annotation.Testable; import org.testcontainers.containers.GenericContainer; @Testable -public class GenericContainerUnitTest { +public class GenericContainerLiveTest { @ClassRule public static GenericContainer simpleWebServer = new GenericContainer("alpine:3.2") diff --git a/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/PostgreSqlContainerUnitTest.java b/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/PostgreSqlContainerLiveTest.java similarity index 96% rename from testing-modules/test-containers/src/test/java/com/baeldung/testconainers/PostgreSqlContainerUnitTest.java rename to testing-modules/test-containers/src/test/java/com/baeldung/testconainers/PostgreSqlContainerLiveTest.java index f458f1a999..ca53f7da13 100644 --- a/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/PostgreSqlContainerUnitTest.java +++ b/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/PostgreSqlContainerLiveTest.java @@ -13,7 +13,7 @@ import org.junit.platform.commons.annotation.Testable; import org.testcontainers.containers.PostgreSQLContainer; @Testable -public class PostgreSqlContainerUnitTest { +public class PostgreSqlContainerLiveTest { @Rule public PostgreSQLContainer postgresContainer = new PostgreSQLContainer(); diff --git a/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/WebDriverContainerUnitTest.java b/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/WebDriverContainerLiveTest.java similarity index 95% rename from testing-modules/test-containers/src/test/java/com/baeldung/testconainers/WebDriverContainerUnitTest.java rename to testing-modules/test-containers/src/test/java/com/baeldung/testconainers/WebDriverContainerLiveTest.java index c10deac0f7..0e52c4e9f7 100644 --- a/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/WebDriverContainerUnitTest.java +++ b/testing-modules/test-containers/src/test/java/com/baeldung/testconainers/WebDriverContainerLiveTest.java @@ -12,7 +12,7 @@ import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.BrowserWebDriverContainer; import org.testcontainers.containers.GenericContainer; -public class WebDriverContainerUnitTest { +public class WebDriverContainerLiveTest { @Rule public BrowserWebDriverContainer chrome = new BrowserWebDriverContainer() diff --git a/testing-modules/testing/README.md b/testing-modules/testing/README.md index c9c656dde9..849b578a55 100644 --- a/testing-modules/testing/README.md +++ b/testing-modules/testing/README.md @@ -19,3 +19,5 @@ - [Guide to JSpec](http://www.baeldung.com/jspec) - [Custom Assertions with AssertJ](http://www.baeldung.com/assertj-custom-assertion) - [Using Conditions with AssertJ](http://www.baeldung.com/assertj-conditions) +- [Guide to JavaFaker](https://www.baeldung.com/java-faker) +- [Running JUnit Tests Programmatically, from a Java Application](https://www.baeldung.com/junit-tests-run-programmatically-from-java) diff --git a/testing-modules/testing/pom.xml b/testing-modules/testing/pom.xml index 6cf7ee223f..2e783b2116 100644 --- a/testing-modules/testing/pom.xml +++ b/testing-modules/testing/pom.xml @@ -1,5 +1,5 @@ + 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 testing @@ -9,57 +9,51 @@ com.baeldung parent-java - 0.0.1-SNAPSHOT - ../../parent-java + 0.0.1-SNAPSHOT + ../../parent-java com.insightfullogic lambda-behave - 0.4 + ${lambda-behave.version} org.assertj assertj-guava - 3.0.0 + ${assertj-guava.version} - org.assertj assertj-core ${assertj-core.version} test - info.cukes cucumber-junit ${cucumber.version} test - info.cukes cucumber-java ${cucumber.version} test - info.cukes cucumber-java8 ${cucumber.version} test - org.pitest pitest-parent ${pitest.version} pom - com.google.truth truth @@ -86,7 +80,7 @@ org.jukito jukito - 1.5 + ${jukito.version} test @@ -94,7 +88,13 @@ javalite-common ${javalite.version} + + com.github.javafaker + javafaker + 0.15 + + @@ -174,5 +174,9 @@ 1.1.0 0.12 1.4.13 + 0.4 + 3.0.0 + 1.5 + diff --git a/testing-modules/testing/src/main/resources/logback.xml b/testing-modules/testing/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/testing-modules/testing/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/testing-modules/testing/src/test/java/com/baeldung/javafaker/JavaFakerUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/javafaker/JavaFakerUnitTest.java new file mode 100644 index 0000000000..7a3b9771fb --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/javafaker/JavaFakerUnitTest.java @@ -0,0 +1,121 @@ +package com.baeldung.javafaker; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Locale; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.Before; +import org.junit.Test; + +import com.github.javafaker.Faker; +import com.github.javafaker.service.FakeValuesService; +import com.github.javafaker.service.LocaleDoesNotExistException; +import com.github.javafaker.service.RandomService; + +public class JavaFakerUnitTest { + + private Faker faker; + + @Before + public void setUp() throws Exception { + faker = new Faker(); + } + + @Test + public void givenJavaFaker_whenAddressObjectCalled_checkValidAddressInfoGiven() throws Exception { + + Faker faker = new Faker(); + + String streetName = faker.address() + .streetName(); + String number = faker.address() + .buildingNumber(); + String city = faker.address() + .city(); + String country = faker.address() + .country(); + + System.out.println(String.format("%s\n%s\n%s\n%s", number, streetName, city, country)); + + } + + @Test + public void givenJavaFakersWithSameSeed_whenNameCalled_CheckSameName() throws Exception { + + Faker faker1 = new Faker(new Random(24)); + Faker faker2 = new Faker(new Random(24)); + + assertEquals(faker1.name() + .firstName(), + faker2.name() + .firstName()); + } + + @Test + public void givenJavaFakersWithDifferentLocals_checkZipCodesMatchRegex() throws Exception { + + Faker ukFaker = new Faker(new Locale("en-GB")); + Faker usFaker = new Faker(new Locale("en-US")); + + System.out.println(String.format("American zipcode: %s", usFaker.address() + .zipCode())); + System.out.println(String.format("British postcode: %s", ukFaker.address() + .zipCode())); + + Pattern ukPattern = Pattern.compile("([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))\\s?[0-9][A-Za-z]{2})"); + Matcher ukMatcher = ukPattern.matcher(ukFaker.address() + .zipCode()); + + assertTrue(ukMatcher.find()); + + Matcher usMatcher = Pattern.compile("^\\d{5}(?:[-\\s]\\d{4})?$") + .matcher(usFaker.address() + .zipCode()); + + assertTrue(usMatcher.find()); + + } + + @Test + public void givenJavaFakerService_testFakersCreated() throws Exception { + + RandomService randomService = new RandomService(); + + System.out.println(randomService.nextBoolean()); + System.out.println(randomService.nextDouble()); + + Faker faker = new Faker(new Random(randomService.nextLong())); + + System.out.println(faker.address() + .city()); + + } + + @Test + public void testFakeValuesService() throws Exception { + + FakeValuesService fakeValuesService = new FakeValuesService(new Locale("en-GB"), new RandomService()); + + String email = fakeValuesService.bothify("????##@gmail.com"); + Matcher emailMatcher = Pattern.compile("\\w{4}\\d{2}@gmail.com") + .matcher(email); + assertTrue(emailMatcher.find()); + + String alphaNumericString = fakeValuesService.regexify("[a-z1-9]{10}"); + Matcher alphaNumericMatcher = Pattern.compile("[a-z1-9]{10}") + .matcher(alphaNumericString); + assertTrue(alphaNumericMatcher.find()); + + } + + @Test(expected = LocaleDoesNotExistException.class) + public void givenWrongLocale_whenFakerIsInitialised_testLocaleDoesNotExistExceptionIsThrown() throws Exception { + + Faker wrongLocaleFaker = new Faker(new Locale("en-seaWorld")); + + } +} \ No newline at end of file diff --git a/testing-modules/testing/src/test/java/com/baeldung/runfromjava/FirstUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/runfromjava/FirstUnitTest.java new file mode 100644 index 0000000000..0e08c43021 --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/runfromjava/FirstUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.runfromjava; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class FirstUnitTest { + + @Test + public void whenThis_thenThat() { + assertTrue(true); + } + + @Test + public void whenSomething_thenSomething() { + assertTrue(true); + } + + @Test + public void whenSomethingElse_thenSomethingElse() { + assertTrue(true); + } + +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/runfromjava/MyTestSuite.java b/testing-modules/testing/src/test/java/com/baeldung/runfromjava/MyTestSuite.java new file mode 100644 index 0000000000..2413fb1ddf --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/runfromjava/MyTestSuite.java @@ -0,0 +1,10 @@ +package com.baeldung.runfromjava; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ FirstUnitTest.class, SecondUnitTest.class }) +public class MyTestSuite { + +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/runfromjava/RunJUnit4TestsFromJava.java b/testing-modules/testing/src/test/java/com/baeldung/runfromjava/RunJUnit4TestsFromJava.java new file mode 100644 index 0000000000..b44b66440a --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/runfromjava/RunJUnit4TestsFromJava.java @@ -0,0 +1,93 @@ +package com.baeldung.runfromjava; + +import junit.extensions.ActiveTestSuite; +import junit.extensions.RepeatedTest; +import junit.framework.JUnit4TestAdapter; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.junit.internal.TextListener; +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; + +public class RunJUnit4TestsFromJava { + + public static void runOne() { + JUnitCore junit = new JUnitCore(); + junit.addListener(new TextListener(System.out)); + junit.run(FirstUnitTest.class); + } + + public static void runAllClasses() { + JUnitCore junit = new JUnitCore(); + junit.addListener(new TextListener(System.out)); + + Result result = junit.run(FirstUnitTest.class, SecondUnitTest.class); + + for (Failure failure : result.getFailures()) { + System.out.println(failure.toString()); + } + + resultReport(result); + } + + public static void runSuiteOfClasses() { + JUnitCore junit = new JUnitCore(); + junit.addListener(new TextListener(System.out)); + Result result = junit.run(MyTestSuite.class); + + for (Failure failure : result.getFailures()) { + System.out.println(failure.toString()); + } + + resultReport(result); + } + + public static void runRepeated() { + Test test = new JUnit4TestAdapter(SecondUnitTest.class); + RepeatedTest repeatedTest = new RepeatedTest(test, 5); + + JUnitCore junit = new JUnitCore(); + junit.addListener(new TextListener(System.out)); + + junit.run(repeatedTest); + } + + public static void runRepeatedSuite() { + TestSuite mySuite = new ActiveTestSuite(); + + JUnitCore junit = new JUnitCore(); + junit.addListener(new TextListener(System.out)); + + mySuite.addTest(new RepeatedTest(new JUnit4TestAdapter(FirstUnitTest.class), 5)); + mySuite.addTest(new RepeatedTest(new JUnit4TestAdapter(SecondUnitTest.class), 3)); + + junit.run(mySuite); + } + + public static void resultReport(Result result) { + System.out.println("Finished. Result: Failures: " + + result.getFailureCount() + ". Ignored: " + + result.getIgnoreCount() + ". Tests run: " + + result.getRunCount() + ". Time: " + + result.getRunTime() + "ms."); + } + + public static void main(String[] args) { + System.out.println("\nRunning one test class:"); + runOne(); + + System.out.println("\nRunning all test classes:"); + runAllClasses(); + + System.out.println("\nRunning a suite of test classes:"); + runSuiteOfClasses(); + + System.out.println("\nRunning repeated tests:"); + runRepeated(); + + System.out.println("\nRunning repeated suite tests:"); + runRepeatedSuite(); + } + +} \ No newline at end of file diff --git a/testing-modules/testing/src/test/java/com/baeldung/runfromjava/SecondUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/runfromjava/SecondUnitTest.java new file mode 100644 index 0000000000..aa5883562e --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/runfromjava/SecondUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.runfromjava; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class SecondUnitTest { + + @Test + public void whenSomething_thenSomething() { + assertTrue(true); + } + + @Test + public void whensomethingElse_thenSomethingElse() { + assertTrue(true); + } +} diff --git a/testing-modules/testng/pom.xml b/testing-modules/testng/pom.xml index e50f3bb563..a9f680aafb 100644 --- a/testing-modules/testng/pom.xml +++ b/testing-modules/testng/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 testng 0.1.0-SNAPSHOT @@ -15,16 +15,13 @@ - - org.testng testng ${testng.version} test - @@ -41,26 +38,6 @@ true - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - - - @@ -68,5 +45,4 @@ 6.10 - \ No newline at end of file diff --git a/twilio/pom.xml b/twilio/pom.xml index 89b40ccdac..610cc04b60 100644 --- a/twilio/pom.xml +++ b/twilio/pom.xml @@ -1,17 +1,15 @@ - + 4.0.0 - - com.baeldung twilio 1.0-SNAPSHOT - - 1.8 - 1.8 - + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + diff --git a/twilio/src/main/resources/logback.xml b/twilio/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/twilio/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/undertow/pom.xml b/undertow/pom.xml index 35ea2b3348..d000956aee 100644 --- a/undertow/pom.xml +++ b/undertow/pom.xml @@ -1,27 +1,25 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 + com.baeldung.undertow undertow jar 1.0-SNAPSHOT undertow http://maven.apache.org + com.baeldung parent-modules 1.0.0-SNAPSHOT - - 1.8 - 1.8 - io.undertow undertow-servlet - 1.4.18.Final + ${undertow-servlet.version} @@ -31,6 +29,7 @@ org.apache.maven.plugins maven-shade-plugin + ${maven-shade-plugin.version} package @@ -43,6 +42,7 @@ org.apache.maven.plugins maven-jar-plugin + ${maven-jar-plugin.version} @@ -54,4 +54,10 @@ + + 1.4.18.Final + 2.4.3 + 3.0.2 + + \ No newline at end of file diff --git a/undertow/src/main/resources/logback.xml b/undertow/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/undertow/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/vaadin/README.md b/vaadin/README.md index 0dfeea8996..43d2cc8961 100644 --- a/vaadin/README.md +++ b/vaadin/README.md @@ -1,3 +1,4 @@ ## Relevant articles: - [Introduction to Vaadin](http://www.baeldung.com/vaadin) +- [Sample Application with Spring Boot and Vaadin](https://www.baeldung.com/spring-boot-vaadin) diff --git a/vaadin/pom.xml b/vaadin/pom.xml index 6fdf033c22..c34ffa3636 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -1,40 +1,21 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.test - vaadin-app + vaadin war 1.0-SNAPSHOT - vaadin-app + Vaadin - - 3 - + parent-boot-2 com.baeldung - parent-modules - 1.0.0-SNAPSHOT + 0.0.1-SNAPSHOT + ../parent-boot-2 - - 7.7.10 - 8.0.6 - 9.3.9.v20160517 - UTF-8 - 1.8 - 1.8 - local - mytheme - - - - - vaadin-addons - http://maven.vaadin.com/vaadin-addons - - - + @@ -46,12 +27,11 @@ - + javax.servlet javax.servlet-api - 3.0.1 provided @@ -70,6 +50,25 @@ com.vaadin vaadin-themes + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.vaadin + vaadin-spring-boot-starter + ${vaadin-spring-boot-starter.version} + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + @@ -77,7 +76,7 @@ org.apache.maven.plugins maven-war-plugin - 3.0.0 + ${maven-war-plugin.version} false @@ -103,7 +102,7 @@ org.apache.maven.plugins maven-clean-plugin - 3.0.0 + ${maven-clean-plugin.version} @@ -117,9 +116,7 @@ - - + org.eclipse.jetty jetty-maven-plugin @@ -128,9 +125,20 @@ 2 + + org.springframework.boot + spring-boot-maven-plugin + + + + vaadin-addons + http://maven.vaadin.com/vaadin-addons + + + @@ -174,4 +182,19 @@ + + 3.0.1 + 7.7.10 + 8.0.6 + 10.0.1 + 9.3.9.v20160517 + UTF-8 + 1.8 + 1.8 + local + mytheme + 3.0.0 + 3.0.0 + + diff --git a/vaadin/src/main/java/com/baeldung/Application.java b/vaadin/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..1d3084723a --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/Application.java @@ -0,0 +1,29 @@ +package com.baeldung; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class Application { + + private static final Logger log = LoggerFactory.getLogger(Application.class); + + public static void main(String[] args) { + SpringApplication.run(Application.class); + } + + @Bean + public CommandLineRunner loadData(EmployeeRepository repository) { + return (args) -> { + repository.save(new Employee("Bill", "Gates")); + repository.save(new Employee("Mark", "Zuckerberg")); + repository.save(new Employee("Sundar", "Pichai")); + repository.save(new Employee("Jeff", "Bezos")); + }; + } +} diff --git a/vaadin/src/main/java/com/baeldung/Employee.java b/vaadin/src/main/java/com/baeldung/Employee.java new file mode 100644 index 0000000000..726f0838b6 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/Employee.java @@ -0,0 +1,51 @@ +package com.baeldung; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Employee { + + @Id + @GeneratedValue + private Long id; + + private String firstName; + + private String lastName; + + protected Employee() { + } + + public Employee(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public Long getId() { + return id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public String toString() { + return String.format("Employee[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName); + } + +} diff --git a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/EmployeeEditor.java new file mode 100644 index 0000000000..ee312786d1 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/EmployeeEditor.java @@ -0,0 +1,90 @@ +package com.baeldung; + +import com.vaadin.flow.component.Key; +import com.vaadin.flow.component.KeyNotifier; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.Binder; +import com.vaadin.flow.spring.annotation.SpringComponent; +import com.vaadin.flow.spring.annotation.UIScope; +import org.springframework.beans.factory.annotation.Autowired; + +@SpringComponent +@UIScope +public class EmployeeEditor extends VerticalLayout implements KeyNotifier { + + private final EmployeeRepository repository; + + private Employee employee; + + TextField firstName = new TextField("First name"); + TextField lastName = new TextField("Last name"); + + Button save = new Button("Save", VaadinIcon.CHECK.create()); + Button cancel = new Button("Cancel"); + Button delete = new Button("Delete", VaadinIcon.TRASH.create()); + HorizontalLayout actions = new HorizontalLayout(save, cancel, delete); + + Binder binder = new Binder<>(Employee.class); + private ChangeHandler changeHandler; + + @Autowired + public EmployeeEditor(EmployeeRepository repository) { + this.repository = repository; + + add(firstName, lastName, actions); + + binder.bindInstanceFields(this); + + setSpacing(true); + + save.getElement().getThemeList().add("primary"); + delete.getElement().getThemeList().add("error"); + + addKeyPressListener(Key.ENTER, e -> save()); + + save.addClickListener(e -> save()); + delete.addClickListener(e -> delete()); + cancel.addClickListener(e -> editEmployee(employee)); + setVisible(false); + } + + void delete() { + repository.delete(employee); + changeHandler.onChange(); + } + + void save() { + repository.save(employee); + changeHandler.onChange(); + } + + public interface ChangeHandler { + void onChange(); + } + + public final void editEmployee(Employee c) { + if (c == null) { + setVisible(false); + return; + } + final boolean persisted = c.getId() != null; + if (persisted) { + employee = repository.findById(c.getId()).get(); + } else { + employee = c; + } + + cancel.setVisible(persisted); + binder.setBean(employee); + setVisible(true); + firstName.focus(); + } + + public void setChangeHandler(ChangeHandler h) { + changeHandler = h; + } +} diff --git a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java b/vaadin/src/main/java/com/baeldung/EmployeeRepository.java new file mode 100644 index 0000000000..044160da78 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/EmployeeRepository.java @@ -0,0 +1,10 @@ +package com.baeldung; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface EmployeeRepository extends JpaRepository { + + List findByLastNameStartsWithIgnoreCase(String lastName); +} diff --git a/vaadin/src/main/java/com/baeldung/MainView.java b/vaadin/src/main/java/com/baeldung/MainView.java new file mode 100644 index 0000000000..6d4c0aaa88 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/MainView.java @@ -0,0 +1,67 @@ +package com.baeldung; + +import org.springframework.util.StringUtils; + +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.Route; + +@Route +public class MainView extends VerticalLayout { + + private final EmployeeRepository employeeRepository; + + private final EmployeeEditor editor; + + final Grid grid; + + final TextField filter; + + private final Button addNewBtn; + + public MainView(EmployeeRepository repo, EmployeeEditor editor) { + this.employeeRepository = repo; + this.editor = editor; + this.grid = new Grid<>(Employee.class); + this.filter = new TextField(); + this.addNewBtn = new Button("New employee", VaadinIcon.PLUS.create()); + + HorizontalLayout actions = new HorizontalLayout(filter, addNewBtn); + add(actions, grid, editor); + + grid.setHeight("200px"); + grid.setColumns("id", "firstName", "lastName"); + grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0); + + filter.setPlaceholder("Filter by last name"); + + filter.setValueChangeMode(ValueChangeMode.EAGER); + filter.addValueChangeListener(e -> listEmployees(e.getValue())); + + grid.asSingleSelect().addValueChangeListener(e -> { + editor.editEmployee(e.getValue()); + }); + + addNewBtn.addClickListener(e -> editor.editEmployee(new Employee("", ""))); + + editor.setChangeHandler(() -> { + editor.setVisible(false); + listEmployees(filter.getValue()); + }); + + listEmployees(null); + } + + void listEmployees(String filterText) { + if (StringUtils.isEmpty(filterText)) { + grid.setItems(employeeRepository.findAll()); + } else { + grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText)); + } + } +} diff --git a/vaadin/src/main/resources/logback.xml b/vaadin/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/vaadin/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/vavr/pom.xml b/vavr/pom.xml index 3bf91adcd3..ae495e9830 100644 --- a/vavr/pom.xml +++ b/vavr/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 com.baeldung vavr @@ -18,23 +19,19 @@ vavr-test ${vavr.version} - org.springframework.boot spring-boot-starter-data-jpa - com.h2database h2 - org.springframework.boot spring-boot-starter-test test - org.awaitility awaitility @@ -46,7 +43,6 @@ 1.8 0.9.1 - 4.12 3.0.0 diff --git a/vavr/src/main/resources/logback.xml b/vavr/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/vavr/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/vertx-and-rxjava/pom.xml b/vertx-and-rxjava/pom.xml index b0668c34a6..cbc94dd8f1 100644 --- a/vertx-and-rxjava/pom.xml +++ b/vertx-and-rxjava/pom.xml @@ -1,7 +1,8 @@ - + + 4.0.0 + vertx-and-rxjava com.baeldung @@ -9,63 +10,42 @@ 1.0.0-SNAPSHOT - 4.0.0 - vertx-and-rxjava + + + io.vertx + vertx-rx-java2 + ${vertx.version} + + + io.vertx + vertx-core + ${vertx.version} + + + io.vertx + vertx-unit + ${vertx.version} + test + + org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + ${maven-compiler-plugin.version} - 1.8 - 1.8 + ${java.version} + ${java.version} - - - - io.vertx - vertx-rx-java2 - 3.5.0.Beta1 - - - io.vertx - vertx-core - 3.5.0.Beta1 - - - io.vertx - vertx-unit - 3.5.0.Beta1 - test - - - junit - junit - 4.12 - test - - - org.slf4j - slf4j-api - 1.7.25 - - - ch.qos.logback - logback-classic - 1.2.3 - - - junit - junit - 4.12 - - - + + 3.5.0.Beta1 + 1.2.3 + \ No newline at end of file diff --git a/vertx-and-rxjava/src/test/resources/logback-test.xml b/vertx-and-rxjava/src/test/resources/logback-test.xml index 71e05a4e24..8b6abffc76 100644 --- a/vertx-and-rxjava/src/test/resources/logback-test.xml +++ b/vertx-and-rxjava/src/test/resources/logback-test.xml @@ -1,7 +1,7 @@ - [%thread{32}] %-5level %msg - %logger%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/vertx/pom.xml b/vertx/pom.xml index b5ca43b1f4..7e494c5914 100644 --- a/vertx/pom.xml +++ b/vertx/pom.xml @@ -1,36 +1,35 @@ - + 4.0.0 - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + com.baeldung vertx 1.0-SNAPSHOT vertx http://maven.apache.org - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + io.vertx vertx-core - 3.0.0 + ${vertx.version} - io.vertx vertx-web - 3.0.0 + ${vertx.version} - io.vertx vertx-unit - 3.0.0 + ${vertx.version} test @@ -40,7 +39,7 @@ org.apache.maven.plugins maven-shade-plugin - 2.3 + ${maven-shade-plugin.version} package @@ -49,15 +48,14 @@ - + io.vertx.core.Starter com.baeldung.SimpleServerVerticle - + ${project.build.directory}/${project.artifactId}-${project.version}-app.jar @@ -67,10 +65,9 @@ - - + 3.0.0 6.10 - + 2.3 diff --git a/vertx/src/main/resources/logback.xml b/vertx/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/vertx/src/main/resources/logback.xml +++ b/vertx/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n diff --git a/video-tutorials/jackson-annotations/pom.xml b/video-tutorials/jackson-annotations/pom.xml index c315efa713..748721b83c 100644 --- a/video-tutorials/jackson-annotations/pom.xml +++ b/video-tutorials/jackson-annotations/pom.xml @@ -1,6 +1,7 @@ + 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 jackson-annotations 1.0.0-SNAPSHOT @@ -84,7 +85,7 @@ io.rest-assured rest-assured - 3.0.1 + ${rest-assured.version} test @@ -98,7 +99,7 @@ io.rest-assured json-schema-validator - 3.0.0 + ${rest-assured-json-schema-validator.version} test @@ -137,35 +138,25 @@ - - 4.3.11.Final - 5.1.38 - 2.8.5 - 5.1.3.Final 2.9.6 2.8.0 4.1 - 20.0 3.5 2.5 - 2.8.9 - 4.4.1 - 4.5 - 2.9.0 + 3.0.1 + 3.0.0 3.6.1 2.2.6 3.0.1 - - - + \ No newline at end of file diff --git a/video-tutorials/jackson-annotations/src/main/resources/logback.xml b/video-tutorials/jackson-annotations/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/video-tutorials/jackson-annotations/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/video-tutorials/pom.xml b/video-tutorials/pom.xml index cbaf5e3680..ca3b39904f 100644 --- a/video-tutorials/pom.xml +++ b/video-tutorials/pom.xml @@ -1,24 +1,23 @@ + 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 video-tutorials 1.0.0-SNAPSHOT - pom video-tutorials com.baeldung parent-java - 0.0.1-SNAPSHOT - ../parent-java + 0.0.1-SNAPSHOT + ../parent-java jackson-annotations - diff --git a/vraptor/pom.xml b/vraptor/pom.xml index c5978173ab..ae43d8e083 100644 --- a/vraptor/pom.xml +++ b/vraptor/pom.xml @@ -1,33 +1,30 @@ - + 4.0.0 com.baeldung vraptor 1.0.0 war - A demo project to start using VRaptor 4 + com.baeldung parent-modules 1.0.0-SNAPSHOT - - UTF-8 - 2.1.2.Final - br.com.caelum vraptor - 4.2.0.Final + ${vraptor.version} org.jboss.weld.servlet weld-servlet-core - 2.1.2.Final + ${weld.version} org.jboss.spec.javax.el @@ -39,7 +36,7 @@ org.jboss.weld weld-core-impl - 2.1.2.Final + ${weld.version} org.jboss.spec.javax.el @@ -51,63 +48,63 @@ javax.el el-api - 2.2 + ${el.version} provided org.hibernate hibernate-validator-cdi - 5.1.1.Final + ${hibernate-validator.version} javax.servlet jstl - 1.2 + ${jstl.version} javax.servlet javax.servlet-api - 3.1.0 + ${servlet.version} provided org.slf4j slf4j-log4j12 - 1.7.5 + ${slf4j-log4j12.version} br.com.caelum.vraptor vraptor-freemarker - 4.1.0-RC3 + ${vraptor-freemarker.version} br.com.caelum.vraptor vraptor-hibernate - 4.0.4 + ${vraptor-hibernate.version} mysql mysql-connector-java - 8.0.8-dmr + ${mysql-connector.version} org.mindrot jbcrypt - 0.4 + ${jbcrypt.version} org.freemarker freemarker - 2.3.27-incubating + ${freemarker.version} @@ -119,11 +116,28 @@ org.apache.tomcat.maven tomcat7-maven-plugin - 2.1 + ${tomcat7-maven-plugin.version} / - + + + 4.2.0.Final + 2.1.2.Final + 2.2 + 5.1.1.Final + 1.2 + 3.1.0 + 1.7.5 + 4.1.0-RC3 + 4.0.4 + 8.0.8-dmr + 0.4 + 2.3.27-incubating + 2.1 + + + \ No newline at end of file diff --git a/wicket/pom.xml b/wicket/pom.xml index d3cb319902..99be467167 100644 --- a/wicket/pom.xml +++ b/wicket/pom.xml @@ -1,8 +1,8 @@ - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 + com.baeldung.wicket.examples wicket war @@ -15,12 +15,6 @@ 1.0.0-SNAPSHOT - - 7.5.0 - 9.2.13.v20150730 - 2.6 - UTF-8 - @@ -37,6 +31,7 @@ test + @@ -86,4 +81,11 @@ + + + 7.5.0 + 9.2.13.v20150730 + 2.6 + + diff --git a/wicket/src/main/resources/logback.xml b/wicket/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/wicket/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/xml/pom.xml b/xml/pom.xml index c417ceb15d..5490f3a89f 100644 --- a/xml/pom.xml +++ b/xml/pom.xml @@ -1,7 +1,6 @@ + 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 xml 0.1-SNAPSHOT xml @@ -12,32 +11,6 @@ 1.0.0-SNAPSHOT - - - jibx.sf.net - JiBX repository - http://jibx.sf.net/maven2 - - never - - - false - - - - - - jibx.sf.net - JiBX repository - http://jibx.sf.net/maven2 - - never - - - false - - - @@ -82,12 +55,12 @@ jibx-run ${jibx-version} + commons-lang commons-lang ${commons-lang.version} - @@ -166,7 +139,6 @@ - @@ -194,23 +166,7 @@ template-binding.xml - true - - - - process-classes - - bind - - - - - - org.jibx - maven-jibx-plugin - 1.3.1 - - src/main/resources + src/main/resources *-binding.xml @@ -218,6 +174,14 @@ + process-classes + process-classes + + bind + + + + process-test-classes process-test-classes test-bind @@ -225,7 +189,6 @@ - org.apache.maven.plugins maven-compiler-plugin @@ -235,8 +198,7 @@ - + maven-assembly-plugin ${project.basedir} @@ -266,9 +228,36 @@ - - + + + + jibx.sf.net + JiBX repository + http://jibx.sf.net/maven2 + + never + + + false + + + + + + + jibx.sf.net + JiBX repository + http://jibx.sf.net/maven2 + + never + + + false + + + + 1.6.1 1.1.6 @@ -282,11 +271,8 @@ 2.4 1.8 - 1.3.1 - - diff --git a/xml/src/main/java/com/baeldung/xml/XMLDocumentWriter.java b/xml/src/main/java/com/baeldung/xml/XMLDocumentWriter.java new file mode 100644 index 0000000000..e33fc5fe1d --- /dev/null +++ b/xml/src/main/java/com/baeldung/xml/XMLDocumentWriter.java @@ -0,0 +1,41 @@ +package com.baeldung.xml; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; + +public class XMLDocumentWriter { + + public void write(Document document, String fileName, boolean excludeDeclaration, boolean prettyPrint) { + try(FileWriter writer = new FileWriter(new File(fileName))) { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + if(excludeDeclaration) { + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + } + if(prettyPrint) { + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + } + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(writer); + transformer.transform(source, result); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } catch (TransformerConfigurationException e) { + throw new IllegalStateException(e); + } catch (TransformerException e) { + throw new IllegalArgumentException(e); + } + } +} diff --git a/xml/src/main/resources/logback.xml b/xml/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/xml/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/xml/src/test/java/com/baeldung/xml/XMLDocumentWriterUnitTest.java b/xml/src/test/java/com/baeldung/xml/XMLDocumentWriterUnitTest.java new file mode 100644 index 0000000000..68f787a054 --- /dev/null +++ b/xml/src/test/java/com/baeldung/xml/XMLDocumentWriterUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.xml; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.io.File; + +public class XMLDocumentWriterUnitTest { + + @Test + public void givenXMLDocumentWhenWriteIsCalledThenXMLIsWrittenToFile() throws Exception { + Document document = createSampleDocument(); + new XMLDocumentWriter().write(document, "company_simple.xml", false, false); + } + + @Test + public void givenXMLDocumentWhenWriteIsCalledWithPrettyPrintThenFormattedXMLIsWrittenToFile() throws Exception { + Document document = createSampleDocument(); + new XMLDocumentWriter().write(document, "company_prettyprinted.xml", false, true); + } + + private Document createSampleDocument() throws ParserConfigurationException { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = documentBuilder.newDocument(); + Element companyElement = document.createElement("Company"); + document.appendChild(companyElement); + Element departmentElement = document.createElement("Department"); + departmentElement.setAttribute("name", "Sales"); + companyElement.appendChild(departmentElement); + Element employee1 = document.createElement("Employee"); + employee1.setAttribute("name", "John Smith"); + departmentElement.appendChild(employee1); + Element employee2 = document.createElement("Employee"); + employee2.setAttribute("name", "Tim Dellor"); + departmentElement.appendChild(employee2); + return document; + } + + @After + public void cleanUp() throws Exception { + FileUtils.deleteQuietly(new File("company_simple.xml")); + FileUtils.deleteQuietly(new File("company_prettyprinted.xml")); + } +} diff --git a/xml/src/test/resources/example_dom4j_new.xml b/xml/src/test/resources/example_dom4j_new.xml deleted file mode 100644 index 020760fdd3..0000000000 --- a/xml/src/test/resources/example_dom4j_new.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - XML with Dom4J - XML handling with Dom4J - 14/06/2016 - Dom4J tech writer - - diff --git a/xml/src/test/resources/example_dom4j_updated.xml b/xml/src/test/resources/example_dom4j_updated.xml deleted file mode 100755 index 962ca0c889..0000000000 --- a/xml/src/test/resources/example_dom4j_updated.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - Guava updated - Introduction to Guava - 04/04/2016 - GuavaAuthor - - - XML updated - Introduction to XPath - 04/05/2016 - XMLAuthor - - - Android updated - Introduction to Android - 04/03/2016 - AndroidAuthor - - - Spring updated - Introduction to Spring - 04/02/2016 - SpringAuthor - -
    Spring Core
    -
    Spring MVC
    -
    Spring Batch
    -
    -
    -
    \ No newline at end of file diff --git a/xml/src/test/resources/example_jaxb_new.xml b/xml/src/test/resources/example_jaxb_new.xml deleted file mode 100644 index 646d938869..0000000000 --- a/xml/src/test/resources/example_jaxb_new.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - Jaxb author - 04/02/2015 - XML Binding with Jaxb - XML with Jaxb - - diff --git a/xmlunit-2/pom.xml b/xmlunit-2/pom.xml index 0a32b90af5..806ebb6c0e 100644 --- a/xmlunit-2/pom.xml +++ b/xmlunit-2/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung xmlunit-2 @@ -17,7 +17,6 @@ xmlunit-matchers ${xmlunit.version}
    - org.xmlunit xmlunit-core @@ -27,7 +26,6 @@
    - 2.3.0 diff --git a/xmlunit-2/src/main/resources/logback.xml b/xmlunit-2/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/xmlunit-2/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/xstream/pom.xml b/xstream/pom.xml index b8462ac34d..64c8198082 100644 --- a/xstream/pom.xml +++ b/xstream/pom.xml @@ -1,6 +1,7 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + org.baeldung xstream 0.0.1-SNAPSHOT @@ -19,7 +20,6 @@ xstream ${xstream.version} - org.codehaus.jettison jettison diff --git a/xstream/src/main/resources/logback.xml b/xstream/src/main/resources/logback.xml index ec0dc2469a..56af2d397e 100644 --- a/xstream/src/main/resources/logback.xml +++ b/xstream/src/main/resources/logback.xml @@ -2,7 +2,7 @@ - web - %date [%thread] %-5level %logger{36} - %message%n + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n