products = service.getProducts();
+
+ context.put("products", products);
+
+ Template template = null;
+
+ try {
+ template = getTemplate("templates/index.vm");
+ response.setHeader("Template Returned", "Success");
+ } catch (Exception e) {
+ logger.error("Error while reading the template ", e);
+ }
+
+ return template;
+
+ }
+}
diff --git a/apache-velocity/src/main/resources/logback.xml b/apache-velocity/src/main/resources/logback.xml
new file mode 100644
index 0000000000..70a420a57a
--- /dev/null
+++ b/apache-velocity/src/main/resources/logback.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apache-velocity/src/main/webapp/WEB-INF/velocity.properties b/apache-velocity/src/main/webapp/WEB-INF/velocity.properties
new file mode 100644
index 0000000000..00e0b7e410
--- /dev/null
+++ b/apache-velocity/src/main/webapp/WEB-INF/velocity.properties
@@ -0,0 +1,4 @@
+resource.loader=webapp
+webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
+webapp.resource.loader.path = .
+webapp.resource.loader.cache = true
\ No newline at end of file
diff --git a/apache-velocity/src/main/webapp/WEB-INF/web.xml b/apache-velocity/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..95b41b36dd
--- /dev/null
+++ b/apache-velocity/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,49 @@
+
+
+
+ apache-velocity
+
+ ProductServlet
+ com.baeldung.apache.velocity.servlet.ProductServlet
+
+
+
+ LayoutServlet
+ com.baeldung.apache.velocity.servlet.LayoutServlet
+
+
+ velocityLayout
+ org.apache.velocity.tools.view.VelocityLayoutServlet
+
+
+ org.apache.velocity.properties
+ /WEB-INF/velocity.properties
+
+
+
+ ProductServlet
+ /
+
+
+
+ LayoutServlet
+ /layout
+
+
+ velocityLayout
+ *.vm
+
+
+
+
+ 30
+
+
+
+
+
+ index.html
+
+
diff --git a/apache-velocity/src/main/webapp/fragments/footer.vm b/apache-velocity/src/main/webapp/fragments/footer.vm
new file mode 100644
index 0000000000..41bb36ce5e
--- /dev/null
+++ b/apache-velocity/src/main/webapp/fragments/footer.vm
@@ -0,0 +1,4 @@
+
+ @Copyright baeldung.com
+
\ No newline at end of file
diff --git a/apache-velocity/src/main/webapp/fragments/header.vm b/apache-velocity/src/main/webapp/fragments/header.vm
new file mode 100644
index 0000000000..96700d3baf
--- /dev/null
+++ b/apache-velocity/src/main/webapp/fragments/header.vm
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/apache-velocity/src/main/webapp/layout/Default.vm b/apache-velocity/src/main/webapp/layout/Default.vm
new file mode 100644
index 0000000000..39a8b277a5
--- /dev/null
+++ b/apache-velocity/src/main/webapp/layout/Default.vm
@@ -0,0 +1,22 @@
+
+
+ Velocity
+
+
+
+ #parse("/fragments/header.vm")
+
+
+
+
+
+
+ $screen_content
+
+
+
+
+ #parse("/fragments/footer.vm")
+
+
+
\ No newline at end of file
diff --git a/apache-velocity/src/main/webapp/templates/index.vm b/apache-velocity/src/main/webapp/templates/index.vm
new file mode 100644
index 0000000000..0ca07caf42
--- /dev/null
+++ b/apache-velocity/src/main/webapp/templates/index.vm
@@ -0,0 +1,63 @@
+
+
+ Online Electronic Store
+
+
+
+
+
+ Today's Offers
+
+
+ $products.size() Products on Sale!
+
+ We are proud to offer these fine products
+ at these amazing prices.
+
+
+ #set( $count = 1 )
+
+
+ Serial # Product Name Price
+
+ #foreach( $product in $products )
+
+ $count)
+ $product.getName()
+ $product.getPrice()
+
+ #set( $count = $count + 1 )
+ #end
+
+
+
+
+
+
diff --git a/apache-velocity/src/main/webapp/templates/layoutdemo.vm b/apache-velocity/src/main/webapp/templates/layoutdemo.vm
new file mode 100644
index 0000000000..0626b655c9
--- /dev/null
+++ b/apache-velocity/src/main/webapp/templates/layoutdemo.vm
@@ -0,0 +1,27 @@
+#set( $layout = "layout.vm" )
+
+ Today's Offers
+
+
+ $products.size() Products on Sale!
+
+ We are proud to offer these fine products
+ at these amazing prices.
+
+
+ #set( $count = 1 )
+
+
+ Serial # Product Name Price
+
+ #foreach( $product in $products )
+
+ $count)
+ $product.getName()
+ $product.getPrice()
+
+ #set( $count = $count + 1 )
+ #end
+
+
+
\ No newline at end of file
diff --git a/apache-velocity/src/test/java/com/baeldung/apache/velocity/servlet/LayoutServletLiveTest.java b/apache-velocity/src/test/java/com/baeldung/apache/velocity/servlet/LayoutServletLiveTest.java
new file mode 100644
index 0000000000..f1f166b119
--- /dev/null
+++ b/apache-velocity/src/test/java/com/baeldung/apache/velocity/servlet/LayoutServletLiveTest.java
@@ -0,0 +1,26 @@
+package com.baeldung.apache.velocity.servlet;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class LayoutServletLiveTest {
+
+ @Test
+ public void whenRequestUsingHttpClient_thenCorrectResponse() throws Exception {
+
+ HttpClient client = new DefaultHttpClient();
+ HttpGet method= new HttpGet("http://localhost:8080/layout");
+
+ HttpResponse httpResponse = client.execute(method);
+
+ assertEquals("Success", httpResponse.getHeaders("Template Returned")[0].getValue());
+
+ }
+
+}
diff --git a/apache-velocity/src/test/java/com/baeldung/apache/velocity/servlet/ProductServletLiveTest.java b/apache-velocity/src/test/java/com/baeldung/apache/velocity/servlet/ProductServletLiveTest.java
new file mode 100644
index 0000000000..397e575d4d
--- /dev/null
+++ b/apache-velocity/src/test/java/com/baeldung/apache/velocity/servlet/ProductServletLiveTest.java
@@ -0,0 +1,24 @@
+package com.baeldung.apache.velocity.servlet;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ProductServletLiveTest {
+
+ @Test
+ public void whenRequestUsingHttpClient_thenCorrectResponse() throws Exception {
+
+ HttpClient client = new DefaultHttpClient();
+ HttpGet method= new HttpGet("http://localhost:8080/");
+
+ HttpResponse httpResponse = client.execute(method);
+
+ assertEquals("Success", httpResponse.getHeaders("Template Returned")[0].getValue());
+
+ }
+}
diff --git a/aws/pom.xml b/aws/pom.xml
index f3ae672a2f..681b76cfd4 100644
--- a/aws/pom.xml
+++ b/aws/pom.xml
@@ -7,17 +7,36 @@
jar
aws
+
+ 2.5
+ 1.3.0
+ 1.1.0
+ 2.8.0
+
+
com.amazonaws
aws-lambda-java-core
- 1.1.0
+ ${aws-lambda-java-core.version}
+
+
+
+ com.amazonaws
+ aws-lambda-java-events
+ ${aws-lambda-java-events.version}
commons-io
commons-io
- 2.5
+ ${commons-io.version}
+
+
+
+ com.google.code.gson
+ gson
+ ${gson.version}
@@ -26,7 +45,7 @@
org.apache.maven.plugins
maven-shade-plugin
- 2.3
+ 3.0.0
false
diff --git a/aws/src/main/java/com/baeldung/lambda/dynamodb/SavePersonHandler.java b/aws/src/main/java/com/baeldung/lambda/dynamodb/SavePersonHandler.java
new file mode 100644
index 0000000000..625da62efd
--- /dev/null
+++ b/aws/src/main/java/com/baeldung/lambda/dynamodb/SavePersonHandler.java
@@ -0,0 +1,49 @@
+package com.baeldung.lambda.dynamodb;
+
+import com.amazonaws.regions.Region;
+import com.amazonaws.regions.Regions;
+import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
+import com.amazonaws.services.dynamodbv2.document.DynamoDB;
+import com.amazonaws.services.dynamodbv2.document.Item;
+import com.amazonaws.services.dynamodbv2.document.PutItemOutcome;
+import com.amazonaws.services.dynamodbv2.document.spec.PutItemSpec;
+import com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException;
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.baeldung.lambda.dynamodb.bean.PersonRequest;
+import com.baeldung.lambda.dynamodb.bean.PersonResponse;
+
+public class SavePersonHandler implements RequestHandler {
+
+ private DynamoDB dynamoDb;
+
+ private String DYNAMODB_TABLE_NAME = "Person";
+ private Regions REGION = Regions.US_WEST_2;
+
+ public PersonResponse handleRequest(PersonRequest personRequest, Context context) {
+ this.initDynamoDbClient();
+
+ persistData(personRequest);
+
+ PersonResponse personResponse = new PersonResponse();
+ personResponse.setMessage("Saved Successfully!!!");
+ return personResponse;
+ }
+
+ private PutItemOutcome persistData(PersonRequest personRequest) throws ConditionalCheckFailedException {
+ return this.dynamoDb.getTable(DYNAMODB_TABLE_NAME)
+ .putItem(
+ new PutItemSpec().withItem(new Item()
+ .withNumber("id", personRequest.getId())
+ .withString("firstName", personRequest.getFirstName())
+ .withString("lastName", personRequest.getLastName())
+ .withNumber("age", personRequest.getAge())
+ .withString("address", personRequest.getAddress())));
+ }
+
+ private void initDynamoDbClient() {
+ AmazonDynamoDBClient client = new AmazonDynamoDBClient();
+ client.setRegion(Region.getRegion(REGION));
+ this.dynamoDb = new DynamoDB(client);
+ }
+}
diff --git a/aws/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonRequest.java b/aws/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonRequest.java
new file mode 100644
index 0000000000..0c0706e676
--- /dev/null
+++ b/aws/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonRequest.java
@@ -0,0 +1,67 @@
+package com.baeldung.lambda.dynamodb.bean;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class PersonRequest {
+ private int id;
+ private String firstName;
+ private String lastName;
+ private int age;
+ private String address;
+
+ public static void main(String[] args) {
+ PersonRequest personRequest = new PersonRequest();
+ personRequest.setId(1);
+ personRequest.setFirstName("John");
+ personRequest.setLastName("Doe");
+ personRequest.setAge(30);
+ personRequest.setAddress("United States");
+ System.out.println(personRequest);
+ }
+
+ public String toString() {
+ final Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ return gson.toJson(this);
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int 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 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/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonResponse.java b/aws/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonResponse.java
new file mode 100644
index 0000000000..a61294ddea
--- /dev/null
+++ b/aws/src/main/java/com/baeldung/lambda/dynamodb/bean/PersonResponse.java
@@ -0,0 +1,20 @@
+package com.baeldung.lambda.dynamodb.bean;
+
+import com.google.gson.Gson;
+
+public class PersonResponse {
+ private String message;
+
+ public String toString() {
+ final Gson gson = new Gson();
+ return gson.toJson(this);
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/core-java-9/README.md b/core-java-9/README.md
index 1b44239e40..53ad79e59c 100644
--- a/core-java-9/README.md
+++ b/core-java-9/README.md
@@ -6,3 +6,5 @@
### Relevant Articles:
- [Java 9 Stream API Improvements](http://www.baeldung.com/java-9-stream-api)
+- [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods)
+- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors)
diff --git a/core-java-9/pom.xml b/core-java-9/pom.xml
index 9d1ff29ef7..23473ff161 100644
--- a/core-java-9/pom.xml
+++ b/core-java-9/pom.xml
@@ -21,6 +21,11 @@
slf4j-api
${org.slf4j.version}
+
+ ch.qos.logback
+ logback-classic
+ ${ch.qos.logback.version}
+
org.hamcrest
@@ -76,9 +81,9 @@
1.7.21
-
+ 1.2.1
- 3.6-jigsaw-SNAPSHOT
+ 3.6.0
2.19.1
diff --git a/core-java-9/src/test/java/com/baeldung/java9/process/ProcessAPIEnhancementsTest.java b/core-java-9/src/test/java/com/baeldung/java9/process/ProcessAPIEnhancementsTest.java
new file mode 100644
index 0000000000..1129a10d17
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/process/ProcessAPIEnhancementsTest.java
@@ -0,0 +1,133 @@
+package com.baeldung.java9.process;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created by sanaulla on 2/23/2017.
+ */
+
+public class ProcessAPIEnhancementsTest {
+
+ Logger log = LoggerFactory.getLogger(ProcessAPIEnhancementsTest.class);
+
+ @Test
+ public void givenCurrentProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
+ ProcessHandle processHandle = ProcessHandle.current();
+ ProcessHandle.Info processInfo = processHandle.info();
+ assertNotNull(processHandle.getPid());
+ assertEquals(false, processInfo.arguments()
+ .isPresent());
+ assertEquals(true, processInfo.command()
+ .isPresent());
+ assertTrue(processInfo.command()
+ .get()
+ .contains("java"));
+
+ assertEquals(true, processInfo.startInstant()
+ .isPresent());
+ assertEquals(true, processInfo.totalCpuDuration()
+ .isPresent());
+ assertEquals(true, processInfo.user()
+ .isPresent());
+ }
+
+ @Test
+ public void givenSpawnProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
+
+ String javaCmd = ProcessUtils.getJavaCmd()
+ .getAbsolutePath();
+ ProcessBuilder processBuilder = new ProcessBuilder(javaCmd, "-version");
+ Process process = processBuilder.inheritIO()
+ .start();
+ ProcessHandle processHandle = process.toHandle();
+ ProcessHandle.Info processInfo = processHandle.info();
+ assertNotNull(processHandle.getPid());
+ assertEquals(false, processInfo.arguments()
+ .isPresent());
+ assertEquals(true, processInfo.command()
+ .isPresent());
+ assertTrue(processInfo.command()
+ .get()
+ .contains("java"));
+ assertEquals(true, processInfo.startInstant()
+ .isPresent());
+ assertEquals(true, processInfo.totalCpuDuration()
+ .isPresent());
+ assertEquals(true, processInfo.user()
+ .isPresent());
+ }
+
+ @Test
+ public void givenLiveProcesses_whenInvokeGetInfo_thenSuccess() {
+ Stream liveProcesses = ProcessHandle.allProcesses();
+ liveProcesses.filter(ProcessHandle::isAlive)
+ .forEach(ph -> {
+ assertNotNull(ph.getPid());
+ assertEquals(true, ph.info()
+ .command()
+ .isPresent());
+ assertEquals(true, ph.info()
+ .startInstant()
+ .isPresent());
+ assertEquals(true, ph.info()
+ .totalCpuDuration()
+ .isPresent());
+ assertEquals(true, ph.info()
+ .user()
+ .isPresent());
+ });
+ }
+
+ @Test
+ public void givenProcess_whenGetChildProcess_thenSuccess() throws IOException {
+ int childProcessCount = 5;
+ for (int i = 0; i < childProcessCount; i++) {
+ String javaCmd = ProcessUtils.getJavaCmd()
+ .getAbsolutePath();
+ ProcessBuilder processBuilder
+ = new ProcessBuilder(javaCmd, "-version");
+ processBuilder.inheritIO().start();
+ }
+
+ Stream children = ProcessHandle.current()
+ .children();
+ children.filter(ProcessHandle::isAlive)
+ .forEach(ph -> log.info("PID: {}, Cmd: {}", ph.getPid(), ph.info()
+ .command()));
+ Stream descendants = ProcessHandle.current()
+ .descendants();
+ descendants.filter(ProcessHandle::isAlive)
+ .forEach(ph -> log.info("PID: {}, Cmd: {}", ph.getPid(), ph.info()
+ .command()));
+ }
+
+ @Test
+ public void givenProcess_whenAddExitCallback_thenSuccess() throws Exception {
+ String javaCmd = ProcessUtils.getJavaCmd()
+ .getAbsolutePath();
+ ProcessBuilder processBuilder
+ = new ProcessBuilder(javaCmd, "-version");
+ Process process = processBuilder.inheritIO()
+ .start();
+ ProcessHandle processHandle = process.toHandle();
+
+ log.info("PID: {} has started", processHandle.getPid());
+ CompletableFuture onProcessExit = processHandle.onExit();
+ onProcessExit.get();
+ assertEquals(false, processHandle.isAlive());
+ onProcessExit.thenAccept(ph -> {
+ log.info("PID: {} has stopped", ph.getPid());
+ });
+ }
+
+}
diff --git a/core-java/0.004102810554955205 b/core-java/0.004102810554955205
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java/0.04832801936270381 b/core-java/0.04832801936270381
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java/0.5633433244738808 b/core-java/0.5633433244738808
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java/0.5967303215007616 b/core-java/0.5967303215007616
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java/0.6256429734439612 b/core-java/0.6256429734439612
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java/0.9252611327674576 b/core-java/0.9252611327674576
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java/0.9799201796740292 b/core-java/0.9799201796740292
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/core-java/README.md b/core-java/README.md
index cd16935864..a34908d8ae 100644
--- a/core-java/README.md
+++ b/core-java/README.md
@@ -57,3 +57,25 @@
- [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)
+- [How to Design a Genetic Algorithm in Java](http://www.baeldung.com/java-genetic-algorithm)
+- [A Guide to ConcurrentMap](http://www.baeldung.com/java-concurrent-map)
+- [Guide to PriorityBlockingQueue in Java](http://www.baeldung.com/java-priority-blocking-queue)
+- [Guide to Java 8 groupingBy Collector](http://www.baeldung.com/java-groupingby-collector)
+- [Avoiding the ConcurrentModificationException in Java](http://www.baeldung.com/java-concurrentmodificationexception)
+- [Guide to WeakHashMap in Java](http://www.baeldung.com/java-weakhashmap)
+- [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)
+- [Custom Thread Pools In Java 8 Parallel Streams](http://www.baeldung.com/java-8-parallel-streams-custom-threadpool)
+- [String Operations with Java Streams](http://www.baeldung.com/java-stream-operations-on-strings)
+- [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)
+- [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions)
+- [Guide to the Guava BiMap](http://www.baeldung.com/guava-bimap)
+- [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream)
+- [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany)
+- [Chained Exceptions in Java](http://www.baeldung.com/java-chained-exceptions)
+- [The Java HashMap Under the Hood](http://www.baeldung.com/java-hashmap)
+- [A Guide to LinkedHashMap in Java](http://www.baeldung.com/java-linked-hashmap)
+- [A Guide to TreeMap in Java](http://www.baeldung.com/java-treemap)
diff --git a/core-java/pom.xml b/core-java/pom.xml
index 85afee2968..b2c59989f1 100644
--- a/core-java/pom.xml
+++ b/core-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
core-java
@@ -9,7 +9,7 @@
core-java
-
+
net.sourceforge.collections
@@ -63,7 +63,6 @@
grep4j
${grep4j.version}
-
@@ -154,6 +153,12 @@
${mockito.version}
test
+
+ com.jayway.awaitility
+ awaitility
+ ${avaitility.version}
+ test
+
commons-codec
@@ -263,7 +268,8 @@
true
-
+
org.baeldung.executable.ExecutableMavenJar
@@ -371,6 +377,7 @@
1.10.19
6.10
3.6.1
+ 1.7.0
3.6.0
diff --git a/core-java/src/main/java/com/baeldung/algorithms/RunAlgorithm.java b/core-java/src/main/java/com/baeldung/algorithms/RunAlgorithm.java
index 113ac1cc53..3f7c8bf4b3 100644
--- a/core-java/src/main/java/com/baeldung/algorithms/RunAlgorithm.java
+++ b/core-java/src/main/java/com/baeldung/algorithms/RunAlgorithm.java
@@ -3,28 +3,35 @@ package com.baeldung.algorithms;
import java.util.Scanner;
import com.baeldung.algorithms.annealing.SimulatedAnnealing;
+import com.baeldung.algorithms.ga.binary.SimpleGeneticAlgorithm;
import com.baeldung.algorithms.slope_one.SlopeOne;
public class RunAlgorithm {
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- System.out.println("Run algorithm:");
- System.out.println("1 - Simulated Annealing");
- System.out.println("2 - Slope One");
- int decision = in.nextInt();
- switch (decision) {
- case 1:
- System.out.println("Optimized distance for travel: " + SimulatedAnnealing.simulateAnnealing(10, 10000, 0.9995));
- break;
- case 2:
- SlopeOne.slopeOne(3);
- break;
- default:
- System.out.println("Unknown option");
- break;
- }
- in.close();
- }
+ public static void main(String[] args) {
+ Scanner in = new Scanner(System.in);
+ System.out.println("Run algorithm:");
+ System.out.println("1 - Simulated Annealing");
+ System.out.println("2 - Slope One");
+ System.out.println("3 - Simple Genetic Algorithm");
+ int decision = in.nextInt();
+ switch (decision) {
+ case 1:
+ System.out.println(
+ "Optimized distance for travel: " + SimulatedAnnealing.simulateAnnealing(10, 10000, 0.9995));
+ break;
+ case 2:
+ SlopeOne.slopeOne(3);
+ break;
+ case 3:
+ SimpleGeneticAlgorithm ga = new SimpleGeneticAlgorithm();
+ ga.runAlgorithm(50, "1011000100000100010000100000100111001000000100000100000000001111");
+ break;
+ default:
+ System.out.println("Unknown option");
+ break;
+ }
+ in.close();
+ }
}
diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java b/core-java/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java
new file mode 100644
index 0000000000..2a740777f3
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/algorithms/ga/binary/Individual.java
@@ -0,0 +1,44 @@
+package com.baeldung.algorithms.ga.binary;
+
+import lombok.Data;
+
+@Data
+public class Individual {
+
+ protected int defaultGeneLength = 64;
+ private byte[] genes = new byte[defaultGeneLength];
+ private int fitness = 0;
+
+ public Individual() {
+ for (int i = 0; i < genes.length; i++) {
+ byte gene = (byte) Math.round(Math.random());
+ genes[i] = gene;
+ }
+ }
+
+ protected byte getSingleGene(int index) {
+ return genes[index];
+ }
+
+ protected void setSingleGene(int index, byte value) {
+ genes[index] = value;
+ fitness = 0;
+ }
+
+ public int getFitness() {
+ if (fitness == 0) {
+ fitness = SimpleGeneticAlgorithm.getFitness(this);
+ }
+ return fitness;
+ }
+
+ @Override
+ public String toString() {
+ String geneString = "";
+ for (int i = 0; i < genes.length; i++) {
+ geneString += getSingleGene(i);
+ }
+ return geneString;
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/binary/Population.java b/core-java/src/main/java/com/baeldung/algorithms/ga/binary/Population.java
new file mode 100644
index 0000000000..47677d7d88
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/algorithms/ga/binary/Population.java
@@ -0,0 +1,40 @@
+package com.baeldung.algorithms.ga.binary;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import lombok.Data;
+
+@Data
+public class Population {
+
+ private List individuals;
+
+ public Population(int size, boolean createNew) {
+ individuals = new ArrayList<>();
+ if (createNew) {
+ createNewPopulation(size);
+ }
+ }
+
+ protected Individual getIndividual(int index) {
+ return individuals.get(index);
+ }
+
+ protected Individual getFittest() {
+ Individual fittest = individuals.get(0);
+ for (int i = 0; i < individuals.size(); i++) {
+ if (fittest.getFitness() <= getIndividual(i).getFitness()) {
+ fittest = getIndividual(i);
+ }
+ }
+ return fittest;
+ }
+
+ private void createNewPopulation(int size) {
+ for (int i = 0; i < size; i++) {
+ Individual newIndividual = new Individual();
+ individuals.add(i, newIndividual);
+ }
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java b/core-java/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java
new file mode 100644
index 0000000000..e62eab0d57
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/algorithms/ga/binary/SimpleGeneticAlgorithm.java
@@ -0,0 +1,117 @@
+package com.baeldung.algorithms.ga.binary;
+
+import lombok.Data;
+
+@Data
+public class SimpleGeneticAlgorithm {
+
+ private static final double uniformRate = 0.5;
+ private static final double mutationRate = 0.025;
+ private static final int tournamentSize = 5;
+ private static final boolean elitism = true;
+ private static byte[] solution = new byte[64];
+
+ public boolean runAlgorithm(int populationSize, String solution) {
+ if (solution.length() != SimpleGeneticAlgorithm.solution.length) {
+ throw new RuntimeException("The solution needs to have " + SimpleGeneticAlgorithm.solution.length + " bytes");
+ }
+ setSolution(solution);
+ Population myPop = new Population(populationSize, true);
+
+ int generationCount = 1;
+ while (myPop.getFittest().getFitness() < getMaxFitness()) {
+ System.out.println("Generation: " + generationCount + " Correct genes found: " + myPop.getFittest().getFitness());
+ myPop = evolvePopulation(myPop);
+ generationCount++;
+ }
+ System.out.println("Solution found!");
+ System.out.println("Generation: " + generationCount);
+ System.out.println("Genes: ");
+ System.out.println(myPop.getFittest());
+ return true;
+ }
+
+ public Population evolvePopulation(Population pop) {
+ int elitismOffset;
+ Population newPopulation = new Population(pop.getIndividuals().size(), false);
+
+ if (elitism) {
+ newPopulation.getIndividuals().add(0, pop.getFittest());
+ elitismOffset = 1;
+ } else {
+ elitismOffset = 0;
+ }
+
+ for (int i = elitismOffset; i < pop.getIndividuals().size(); i++) {
+ Individual indiv1 = tournamentSelection(pop);
+ Individual indiv2 = tournamentSelection(pop);
+ Individual newIndiv = crossover(indiv1, indiv2);
+ newPopulation.getIndividuals().add(i, newIndiv);
+ }
+
+ for (int i = elitismOffset; i < newPopulation.getIndividuals().size(); i++) {
+ mutate(newPopulation.getIndividual(i));
+ }
+
+ return newPopulation;
+ }
+
+ private Individual crossover(Individual indiv1, Individual indiv2) {
+ Individual newSol = new Individual();
+ for (int i = 0; i < newSol.getDefaultGeneLength(); i++) {
+ if (Math.random() <= uniformRate) {
+ newSol.setSingleGene(i, indiv1.getSingleGene(i));
+ } else {
+ newSol.setSingleGene(i, indiv2.getSingleGene(i));
+ }
+ }
+ return newSol;
+ }
+
+ private void mutate(Individual indiv) {
+ for (int i = 0; i < indiv.getDefaultGeneLength(); i++) {
+ if (Math.random() <= mutationRate) {
+ byte gene = (byte) Math.round(Math.random());
+ indiv.setSingleGene(i, gene);
+ }
+ }
+ }
+
+ private Individual tournamentSelection(Population pop) {
+ Population tournament = new Population(tournamentSize, false);
+ for (int i = 0; i < tournamentSize; i++) {
+ int randomId = (int) (Math.random() * pop.getIndividuals().size());
+ tournament.getIndividuals().add(i, pop.getIndividual(randomId));
+ }
+ Individual fittest = tournament.getFittest();
+ return fittest;
+ }
+
+ protected static int getFitness(Individual individual) {
+ int fitness = 0;
+ for (int i = 0; i < individual.getDefaultGeneLength() && i < solution.length; i++) {
+ if (individual.getSingleGene(i) == solution[i]) {
+ fitness++;
+ }
+ }
+ return fitness;
+ }
+
+ protected int getMaxFitness() {
+ int maxFitness = solution.length;
+ return maxFitness;
+ }
+
+ protected void setSolution(String newSolution) {
+ solution = new byte[newSolution.length()];
+ for (int i = 0; i < newSolution.length(); i++) {
+ String character = newSolution.substring(i, i + 1);
+ if (character.contains("0") || character.contains("1")) {
+ solution[i] = Byte.parseByte(character);
+ } else {
+ solution[i] = 0;
+ }
+ }
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/future/SquareCalculator.java b/core-java/src/main/java/com/baeldung/concurrent/future/SquareCalculator.java
index e53a2413d1..bcd559dd3b 100644
--- a/core-java/src/main/java/com/baeldung/concurrent/future/SquareCalculator.java
+++ b/core-java/src/main/java/com/baeldung/concurrent/future/SquareCalculator.java
@@ -15,6 +15,6 @@ public class SquareCalculator {
return executor.submit(() -> {
Thread.sleep(1000);
return input * input;
- });
+ });
}
}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/locks/ReentrantLockWithCondition.java b/core-java/src/main/java/com/baeldung/concurrent/locks/ReentrantLockWithCondition.java
new file mode 100644
index 0000000000..4f061d2efd
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/concurrent/locks/ReentrantLockWithCondition.java
@@ -0,0 +1,83 @@
+package com.baeldung.concurrent.locks;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Stack;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+import static java.lang.Thread.sleep;
+
+public class ReentrantLockWithCondition {
+
+ static Logger logger = LoggerFactory.getLogger(ReentrantLockWithCondition.class);
+
+ Stack stack = new Stack<>();
+ int CAPACITY = 5;
+
+ ReentrantLock lock = new ReentrantLock();
+ Condition stackEmptyCondition = lock.newCondition();
+ Condition stackFullCondition = lock.newCondition();
+
+ public void pushToStack(String item) throws InterruptedException {
+ try {
+ lock.lock();
+ if (stack.size() == CAPACITY) {
+ logger.info(Thread.currentThread().getName() + " wait on stack full");
+ stackFullCondition.await();
+ }
+ logger.info("Pushing the item " + item);
+ stack.push(item);
+ stackEmptyCondition.signalAll();
+ } finally {
+ lock.unlock();
+ }
+
+ }
+
+ public String popFromStack() throws InterruptedException {
+ try {
+ lock.lock();
+ if (stack.size() == 0) {
+ logger.info(Thread.currentThread().getName() + " wait on stack empty");
+ stackEmptyCondition.await();
+ }
+ return stack.pop();
+ } finally {
+ stackFullCondition.signalAll();
+ lock.unlock();
+ }
+ }
+
+ public static void main(String[] args) {
+ final int threadCount = 2;
+ ReentrantLockWithCondition object = new ReentrantLockWithCondition();
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+ service.execute(() -> {
+ for (int i = 0; i < 10; i++) {
+ try {
+ object.pushToStack("Item " + i);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ });
+
+ service.execute(() -> {
+ for (int i = 0; i < 10; i++) {
+ try {
+ logger.info("Item popped " + object.popFromStack());
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ });
+
+ service.shutdown();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/locks/SharedObjectWithLock.java b/core-java/src/main/java/com/baeldung/concurrent/locks/SharedObjectWithLock.java
new file mode 100644
index 0000000000..b6a4615638
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/concurrent/locks/SharedObjectWithLock.java
@@ -0,0 +1,92 @@
+package com.baeldung.concurrent.locks;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+import static java.lang.Thread.sleep;
+
+public class SharedObjectWithLock {
+
+ Logger logger = LoggerFactory.getLogger(SharedObjectWithLock.class);
+
+ ReentrantLock lock = new ReentrantLock(true);
+
+ int counter = 0;
+
+ public void perform() {
+
+ lock.lock();
+ logger.info("Thread - " + Thread.currentThread().getName() + " acquired the lock");
+ try {
+ logger.info("Thread - " + Thread.currentThread().getName() + " processing");
+ counter++;
+ } catch (Exception exception) {
+ logger.error(" Interrupted Exception ", exception);
+ } finally {
+ lock.unlock();
+ logger.info("Thread - " + Thread.currentThread().getName() + " released the lock");
+ }
+ }
+
+ public void performTryLock() {
+
+ logger.info("Thread - " + Thread.currentThread().getName() + " attempting to acquire the lock");
+ try {
+ boolean isLockAcquired = lock.tryLock(2, TimeUnit.SECONDS);
+ if (isLockAcquired) {
+ try {
+ logger.info("Thread - " + Thread.currentThread().getName() + " acquired the lock");
+
+ logger.info("Thread - " + Thread.currentThread().getName() + " processing");
+ sleep(1000);
+ } finally {
+ lock.unlock();
+ logger.info("Thread - " + Thread.currentThread().getName() + " released the lock");
+
+ }
+ }
+ } catch (InterruptedException exception) {
+ logger.error(" Interrupted Exception ", exception);
+ }
+ logger.info("Thread - " + Thread.currentThread().getName() + " could not acquire the lock");
+ }
+
+ public ReentrantLock getLock() {
+ return lock;
+ }
+
+ boolean isLocked() {
+ return lock.isLocked();
+ }
+
+ boolean hasQueuedThreads() {
+ return lock.hasQueuedThreads();
+ }
+
+ int getCounter() {
+ return counter;
+ }
+
+ public static void main(String[] args) {
+
+ final int threadCount = 2;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+ final SharedObjectWithLock object = new SharedObjectWithLock();
+
+ service.execute(() -> {
+ object.perform();
+ });
+ service.execute(() -> {
+ object.performTryLock();
+ });
+
+ service.shutdown();
+
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/locks/StampedLockDemo.java b/core-java/src/main/java/com/baeldung/concurrent/locks/StampedLockDemo.java
new file mode 100644
index 0000000000..0b0dbc72cb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/concurrent/locks/StampedLockDemo.java
@@ -0,0 +1,104 @@
+package com.baeldung.concurrent.locks;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.locks.StampedLock;
+
+import static java.lang.Thread.sleep;
+
+public class StampedLockDemo {
+ Map map = new HashMap<>();
+ Logger logger = LoggerFactory.getLogger(StampedLockDemo.class);
+
+ private final StampedLock lock = new StampedLock();
+
+ public void put(String key, String value) throws InterruptedException {
+ long stamp = lock.writeLock();
+
+ try {
+ logger.info(Thread.currentThread().getName() + " acquired the write lock with stamp " + stamp);
+ map.put(key, value);
+ } finally {
+ lock.unlockWrite(stamp);
+ logger.info(Thread.currentThread().getName() + " unlocked the write lock with stamp " + stamp);
+ }
+ }
+
+ public String get(String key) throws InterruptedException {
+ long stamp = lock.readLock();
+ logger.info(Thread.currentThread().getName() + " acquired the read lock with stamp " + stamp);
+ try {
+ sleep(5000);
+ return map.get(key);
+
+ } finally {
+ lock.unlockRead(stamp);
+ logger.info(Thread.currentThread().getName() + " unlocked the read lock with stamp " + stamp);
+
+ }
+
+ }
+
+ public String readWithOptimisticLock(String key) throws InterruptedException {
+ long stamp = lock.tryOptimisticRead();
+ String value = map.get(key);
+
+ if (!lock.validate(stamp)) {
+ stamp = lock.readLock();
+ try {
+ sleep(5000);
+ return map.get(key);
+
+ } finally {
+ lock.unlock(stamp);
+ logger.info(Thread.currentThread().getName() + " unlocked the read lock with stamp " + stamp);
+
+ }
+ }
+ return value;
+ }
+
+ public static void main(String[] args) {
+ final int threadCount = 4;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+ StampedLockDemo object = new StampedLockDemo();
+
+ Runnable writeTask = () -> {
+
+ try {
+ object.put("key1", "value1");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ };
+ Runnable readTask = () -> {
+
+ try {
+ object.get("key1");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ };
+ Runnable readOptimisticTask = () -> {
+
+ try {
+ object.readWithOptimisticLock("key1");
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ };
+ service.submit(writeTask);
+ service.submit(writeTask);
+ service.submit(readTask);
+ service.submit(readOptimisticTask);
+
+ service.shutdown();
+
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/locks/SynchronizedHashMapWithRWLock.java b/core-java/src/main/java/com/baeldung/concurrent/locks/SynchronizedHashMapWithRWLock.java
new file mode 100644
index 0000000000..83b8b34fe9
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/concurrent/locks/SynchronizedHashMapWithRWLock.java
@@ -0,0 +1,120 @@
+package com.baeldung.concurrent.locks;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import static java.lang.Thread.sleep;
+
+public class SynchronizedHashMapWithRWLock {
+
+ static Map syncHashMap = new HashMap<>();
+ Logger logger = LoggerFactory.getLogger(SynchronizedHashMapWithRWLock.class);
+
+ private final ReadWriteLock lock = new ReentrantReadWriteLock();
+ private final Lock readLock = lock.readLock();
+ private final Lock writeLock = lock.writeLock();
+
+ public void put(String key, String value) throws InterruptedException {
+
+ try {
+ writeLock.lock();
+ logger.info(Thread.currentThread().getName() + " writing");
+ syncHashMap.put(key, value);
+ sleep(1000);
+ } finally {
+ writeLock.unlock();
+ }
+
+ }
+
+ public String get(String key) {
+ try {
+ readLock.lock();
+ logger.info(Thread.currentThread().getName() + " reading");
+ return syncHashMap.get(key);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public String remove(String key) {
+ try {
+ writeLock.lock();
+ return syncHashMap.remove(key);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ public boolean containsKey(String key) {
+ try {
+ readLock.lock();
+ return syncHashMap.containsKey(key);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ boolean isReadLockAvailable() {
+ return readLock.tryLock();
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+
+ final int threadCount = 3;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+ SynchronizedHashMapWithRWLock object = new SynchronizedHashMapWithRWLock();
+
+ service.execute(new Thread(new Writer(object), "Writer"));
+ service.execute(new Thread(new Reader(object), "Reader1"));
+ service.execute(new Thread(new Reader(object), "Reader2"));
+
+ service.shutdown();
+ }
+
+ private static class Reader implements Runnable {
+
+ SynchronizedHashMapWithRWLock object;
+
+ public Reader(SynchronizedHashMapWithRWLock object) {
+ this.object = object;
+ }
+
+ @Override
+ public void run() {
+ for (int i = 0; i < 10; i++) {
+ object.get("key" + i);
+ }
+ }
+ }
+
+ private static class Writer implements Runnable {
+
+ SynchronizedHashMapWithRWLock object;
+
+ public Writer(SynchronizedHashMapWithRWLock object) {
+ this.object = object;
+ }
+
+ @Override
+ public void run() {
+ for (int i = 0; i < 10; i++) {
+ try {
+ object.put("key" + i, "value" + i);
+ sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/java_8_features/Person.java b/core-java/src/main/java/com/baeldung/java_8_features/Person.java
new file mode 100644
index 0000000000..83b5530ee8
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java_8_features/Person.java
@@ -0,0 +1,27 @@
+package com.baeldung.java_8_features;
+
+public class Person {
+ private String name;
+ private Integer age;
+
+ public Person(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/java_8_features/groupingby/BlogPost.java b/core-java/src/main/java/com/baeldung/java_8_features/groupingby/BlogPost.java
new file mode 100644
index 0000000000..afc05e356a
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java_8_features/groupingby/BlogPost.java
@@ -0,0 +1,36 @@
+package com.baeldung.java_8_features.groupingby;
+
+public class BlogPost {
+ private String title;
+ private String author;
+ private BlogPostType type;
+ private int likes;
+
+ public BlogPost(String title, String author, BlogPostType type, int likes) {
+ this.title = title;
+ this.author = author;
+ this.type = type;
+ this.likes = likes;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public BlogPostType getType() {
+ return type;
+ }
+
+ public int getLikes() {
+ return likes;
+ }
+
+ @Override
+ public String toString() {
+ return "BlogPost{" + "title='" + title + '\'' + ", type=" + type + ", likes=" + likes + '}';
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/java_8_features/groupingby/BlogPostType.java b/core-java/src/main/java/com/baeldung/java_8_features/groupingby/BlogPostType.java
new file mode 100644
index 0000000000..2029784e91
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java_8_features/groupingby/BlogPostType.java
@@ -0,0 +1,5 @@
+package com.baeldung.java_8_features.groupingby;
+
+public enum BlogPostType {
+ NEWS, REVIEW, GUIDE
+}
diff --git a/core-java/src/main/java/com/baeldung/strategy/ChristmasDiscounter.java b/core-java/src/main/java/com/baeldung/strategy/ChristmasDiscounter.java
new file mode 100644
index 0000000000..a0c36bb63e
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/strategy/ChristmasDiscounter.java
@@ -0,0 +1,11 @@
+package com.baeldung.strategy;
+
+import java.math.BigDecimal;
+
+public class ChristmasDiscounter implements Discounter {
+
+ @Override
+ public BigDecimal apply(BigDecimal amount) {
+ return amount.multiply(BigDecimal.valueOf(0.9));
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/strategy/Discounter.java b/core-java/src/main/java/com/baeldung/strategy/Discounter.java
new file mode 100644
index 0000000000..00bf4855d1
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/strategy/Discounter.java
@@ -0,0 +1,23 @@
+package com.baeldung.strategy;
+
+import java.math.BigDecimal;
+import java.util.function.UnaryOperator;
+
+public interface Discounter extends UnaryOperator {
+
+ default Discounter combine(Discounter after) {
+ return value -> after.apply(this.apply(value));
+ }
+
+ static Discounter christmas() {
+ return (amount) -> amount.multiply(BigDecimal.valueOf(0.9));
+ }
+
+ static Discounter newYear() {
+ return (amount) -> amount.multiply(BigDecimal.valueOf(0.8));
+ }
+
+ static Discounter easter() {
+ return (amount) -> amount.multiply(BigDecimal.valueOf(0.5));
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/strategy/EasterDiscounter.java b/core-java/src/main/java/com/baeldung/strategy/EasterDiscounter.java
new file mode 100644
index 0000000000..990d10073b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/strategy/EasterDiscounter.java
@@ -0,0 +1,11 @@
+package com.baeldung.strategy;
+
+import java.math.BigDecimal;
+
+public class EasterDiscounter implements Discounter {
+
+ @Override
+ public BigDecimal apply(BigDecimal amount) {
+ return amount.multiply(BigDecimal.valueOf(0.5));
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/stream/InfiniteStreams.java b/core-java/src/main/java/com/baeldung/stream/InfiniteStreams.java
new file mode 100644
index 0000000000..097b516f8c
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/stream/InfiniteStreams.java
@@ -0,0 +1,27 @@
+package com.baeldung.stream;
+
+
+import java.util.stream.Stream;
+
+public class InfiniteStreams {
+ public static void main(String[] args) {
+ doWhileOldWay();
+
+ doWhileStreamWay();
+
+ }
+
+ private static void doWhileOldWay() {
+
+ int i = 0;
+ while (i < 10) {
+ System.out.println(i);
+ i++;
+ }
+ }
+
+ private static void doWhileStreamWay() {
+ Stream integers = Stream.iterate(0, i -> i + 1);
+ integers.limit(10).forEach(System.out::println);
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/string/JoinerSplitter.java b/core-java/src/main/java/com/baeldung/string/JoinerSplitter.java
new file mode 100644
index 0000000000..085be66801
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/string/JoinerSplitter.java
@@ -0,0 +1,36 @@
+package com.baeldung.string;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class JoinerSplitter {
+
+ public static String join ( String[] arrayOfString ) {
+ return Arrays.asList(arrayOfString)
+ .stream()
+ .map(x -> x)
+ .collect(Collectors.joining(","));
+ }
+
+ public static String joinWithPrefixPostFix ( String[] arrayOfString ) {
+ return Arrays.asList(arrayOfString)
+ .stream()
+ .map(x -> x)
+ .collect(Collectors.joining(",","[","]"));
+ }
+
+ public static List split ( String str ) {
+ return Stream.of(str.split(","))
+ .map (elem -> new String(elem))
+ .collect(Collectors.toList());
+ }
+
+ public static List splitToListOfChar ( String str ) {
+ return str.chars()
+ .mapToObj(item -> (char) item)
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/CharArrayToStringUnitTest.java b/core-java/src/test/java/com/baeldung/CharArrayToStringUnitTest.java
index 2f7830bbf4..3488f8b390 100644
--- a/core-java/src/test/java/com/baeldung/CharArrayToStringUnitTest.java
+++ b/core-java/src/test/java/com/baeldung/CharArrayToStringUnitTest.java
@@ -8,55 +8,55 @@ public class CharArrayToStringUnitTest {
@Test
public void givenCharArray_whenCallingStringConstructor_shouldConvertToString() {
- char[] charArray = {'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r'};
+ char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' };
String result = new String(charArray);
String expectedValue = "character";
-
+
assertEquals(expectedValue, result);
}
-
+
@Test
- public void givenCharArray_whenCallingStringConstructorWithOffsetAndLength_shouldConvertToString(){
- char[] charArray = {'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r'};
+ public void givenCharArray_whenCallingStringConstructorWithOffsetAndLength_shouldConvertToString() {
+ char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' };
String result = new String(charArray, 4, 3);
String expectedValue = "act";
-
+
assertEquals(expectedValue, result);
}
-
+
@Test
- public void givenCharArray_whenCallingStringCopyValueOf_shouldConvertToString(){
- char[] charArray = {'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r'};
+ public void givenCharArray_whenCallingStringCopyValueOf_shouldConvertToString() {
+ char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' };
String result = String.copyValueOf(charArray);
String expectedValue = "character";
-
+
assertEquals(expectedValue, result);
}
-
+
@Test
- public void givenCharArray_whenCallingStringCopyValueOfWithOffsetAndLength_shouldConvertToString(){
- char[] charArray = {'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r'};
+ public void givenCharArray_whenCallingStringCopyValueOfWithOffsetAndLength_shouldConvertToString() {
+ char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' };
String result = String.copyValueOf(charArray, 0, 4);
String expectedValue = "char";
-
+
assertEquals(expectedValue, result);
}
-
+
@Test
- public void givenCharArray_whenCallingStringValueOf_shouldConvertToString(){
- char[] charArray = {'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r'};
+ public void givenCharArray_whenCallingStringValueOf_shouldConvertToString() {
+ char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' };
String result = String.valueOf(charArray);
String expectedValue = "character";
-
+
assertEquals(expectedValue, result);
}
-
+
@Test
- public void givenCharArray_whenCallingStringValueOfWithOffsetAndLength_shouldConvertToString(){
- char[] charArray = {'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r'};
+ public void givenCharArray_whenCallingStringValueOfWithOffsetAndLength_shouldConvertToString() {
+ char[] charArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r' };
String result = String.valueOf(charArray, 3, 4);
String expectedValue = "ract";
-
+
assertEquals(expectedValue, result);
}
}
diff --git a/core-java/src/test/java/com/baeldung/StringToCharArrayUnitTest.java b/core-java/src/test/java/com/baeldung/StringToCharArrayUnitTest.java
index 2e7dc24a17..cd996e58e2 100644
--- a/core-java/src/test/java/com/baeldung/StringToCharArrayUnitTest.java
+++ b/core-java/src/test/java/com/baeldung/StringToCharArrayUnitTest.java
@@ -6,15 +6,15 @@ import org.junit.Test;
public class StringToCharArrayUnitTest {
-@Test
-public void givenString_whenCallingStringToCharArray_shouldConvertToCharArray() {
- String givenString = "characters";
+ @Test
+ public void givenString_whenCallingStringToCharArray_shouldConvertToCharArray() {
+ String givenString = "characters";
- char[] result = givenString.toCharArray();
+ char[] result = givenString.toCharArray();
- char[] expectedCharArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r', 's' };
+ char[] expectedCharArray = { 'c', 'h', 'a', 'r', 'a', 'c', 't', 'e', 'r', 's' };
- assertArrayEquals(expectedCharArray, result);
-}
+ assertArrayEquals(expectedCharArray, result);
+ }
}
diff --git a/core-java/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmUnitTest.java b/core-java/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmUnitTest.java
new file mode 100644
index 0000000000..2e92177c8c
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/algorithms/BinaryGeneticAlgorithmUnitTest.java
@@ -0,0 +1,16 @@
+package com.baeldung.algorithms;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.baeldung.algorithms.ga.binary.SimpleGeneticAlgorithm;
+
+public class BinaryGeneticAlgorithmUnitTest {
+
+ @Test
+ public void testGA() {
+ SimpleGeneticAlgorithm ga = new SimpleGeneticAlgorithm();
+ Assert.assertTrue(ga.runAlgorithm(50, "1011000100000100010000100000100111001000000100000100000000001111"));
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/concurrent/locks/SharedObjectWithLockManualTest.java b/core-java/src/test/java/com/baeldung/concurrent/locks/SharedObjectWithLockManualTest.java
new file mode 100644
index 0000000000..9b82ced642
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/concurrent/locks/SharedObjectWithLockManualTest.java
@@ -0,0 +1,75 @@
+package com.baeldung.concurrent.locks;
+
+import org.junit.Test;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class SharedObjectWithLockManualTest {
+
+ @Test
+ public void whenLockAcquired_ThenLockedIsTrue() {
+ final SharedObjectWithLock object = new SharedObjectWithLock();
+
+ final int threadCount = 2;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+
+ executeThreads(object, threadCount, service);
+
+ assertEquals(true, object.isLocked());
+
+ service.shutdown();
+ }
+
+ @Test
+ public void whenLocked_ThenQueuedThread() {
+ final int threadCount = 4;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+ final SharedObjectWithLock object = new SharedObjectWithLock();
+
+ executeThreads(object, threadCount, service);
+
+ assertEquals(object.hasQueuedThreads(), true);
+
+ service.shutdown();
+
+ }
+
+ public void whenTryLock_ThenQueuedThread() {
+ final SharedObjectWithLock object = new SharedObjectWithLock();
+
+ final int threadCount = 2;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+
+ executeThreads(object, threadCount, service);
+
+ assertEquals(true, object.isLocked());
+
+ service.shutdown();
+ }
+
+ @Test
+ public void whenGetCount_ThenCorrectCount() throws InterruptedException {
+ final int threadCount = 4;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+ final SharedObjectWithLock object = new SharedObjectWithLock();
+
+ executeThreads(object, threadCount, service);
+ Thread.sleep(1000);
+ assertEquals(object.getCounter(), 4);
+
+ service.shutdown();
+
+ }
+
+ private void executeThreads(SharedObjectWithLock object, int threadCount, ExecutorService service) {
+ for (int i = 0; i < threadCount; i++) {
+ service.execute(() -> {
+ object.perform();
+ });
+ }
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/concurrent/locks/SynchronizedHashMapWithRWLockManualTest.java b/core-java/src/test/java/com/baeldung/concurrent/locks/SynchronizedHashMapWithRWLockManualTest.java
new file mode 100644
index 0000000000..fd6cf08442
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/concurrent/locks/SynchronizedHashMapWithRWLockManualTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.concurrent.locks;
+
+import jdk.nashorn.internal.ir.annotations.Ignore;
+import org.junit.Test;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class SynchronizedHashMapWithRWLockManualTest {
+
+ @Test
+ public void whenWriting_ThenNoReading() {
+ SynchronizedHashMapWithRWLock object = new SynchronizedHashMapWithRWLock();
+ final int threadCount = 3;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+
+ executeWriterThreads(object, threadCount, service);
+
+ assertEquals(object.isReadLockAvailable(), false);
+
+ service.shutdown();
+ }
+
+ @Test
+ public void whenReading_ThenMultipleReadingAllowed() {
+ SynchronizedHashMapWithRWLock object = new SynchronizedHashMapWithRWLock();
+ final int threadCount = 5;
+ final ExecutorService service = Executors.newFixedThreadPool(threadCount);
+
+ executeReaderThreads(object, threadCount, service);
+
+ assertEquals(object.isReadLockAvailable(), true);
+
+ service.shutdown();
+ }
+
+ private void executeWriterThreads(SynchronizedHashMapWithRWLock object, int threadCount, ExecutorService service) {
+ for (int i = 0; i < threadCount; i++) {
+ service.execute(() -> {
+ try {
+ object.put("key" + threadCount, "value" + threadCount);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ });
+ }
+ }
+
+ private void executeReaderThreads(SynchronizedHashMapWithRWLock object, int threadCount, ExecutorService service) {
+ for (int i = 0; i < threadCount; i++)
+ service.execute(() -> {
+ object.get("key" + threadCount);
+ });
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/concurrent/priorityblockingqueue/PriorityBlockingQueueUnitTest.java b/core-java/src/test/java/com/baeldung/concurrent/priorityblockingqueue/PriorityBlockingQueueUnitTest.java
index 063e07d859..0272726465 100644
--- a/core-java/src/test/java/com/baeldung/concurrent/priorityblockingqueue/PriorityBlockingQueueUnitTest.java
+++ b/core-java/src/test/java/com/baeldung/concurrent/priorityblockingqueue/PriorityBlockingQueueUnitTest.java
@@ -1,12 +1,10 @@
package com.baeldung.concurrent.priorityblockingqueue;
-import org.assertj.core.api.Assertions;
import org.junit.Test;
import java.util.ArrayList;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;
-import java.util.stream.IntStream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.util.Lists.newArrayList;
@@ -24,11 +22,7 @@ public class PriorityBlockingQueueUnitTest {
queue.add(3);
queue.add(4);
- polledElements.add(queue.poll());
- polledElements.add(queue.poll());
- polledElements.add(queue.poll());
- polledElements.add(queue.poll());
- polledElements.add(queue.poll());
+ queue.drainTo(polledElements);
assertThat(polledElements).containsExactly(1, 2, 3, 4, 5);
}
@@ -38,13 +32,14 @@ public class PriorityBlockingQueueUnitTest {
PriorityBlockingQueue queue = new PriorityBlockingQueue<>();
final Thread thread = new Thread(() -> {
- System.out.println("Polling...");
- while (true) {
- try {
- Integer poll = queue.take();
- System.out.println("Polled: " + poll);
- } catch (InterruptedException e) {}
- }
+ System.out.println("Polling...");
+ while (true) {
+ try {
+ Integer poll = queue.take();
+ System.out.println("Polled: " + poll);
+ } catch (InterruptedException e) {
+ }
+ }
});
thread.start();
diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusManualTest.java
similarity index 97%
rename from core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusTest.java
rename to core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusManualTest.java
index 73a4cdc0cd..ec865f71c4 100644
--- a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusTest.java
+++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapAggregateStatusManualTest.java
@@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-public class ConcurrentMapAggregateStatusTest {
+public class ConcurrentMapAggregateStatusManualTest {
private ExecutorService executorService;
private Map concurrentMap;
diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueManualTest.java
similarity index 99%
rename from core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueTest.java
rename to core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueManualTest.java
index 62a3d10add..33e3326427 100644
--- a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueTest.java
+++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapNullKeyValueManualTest.java
@@ -10,7 +10,7 @@ import java.util.concurrent.ConcurrentMap;
import static org.junit.Assert.assertNull;
-public class ConcurrentMapNullKeyValueTest {
+public class ConcurrentMapNullKeyValueManualTest {
ConcurrentMap concurrentMap;
diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceManualTest.java
similarity index 98%
rename from core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceTest.java
rename to core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceManualTest.java
index a0efa89351..5c1612ca60 100644
--- a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceTest.java
+++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentMapPerformanceManualTest.java
@@ -11,7 +11,7 @@ import java.util.concurrent.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-public class ConcurrentMapPerformanceTest {
+public class ConcurrentMapPerformanceManualTest {
@Test
public void givenMaps_whenGetPut500KTimes_thenConcurrentMapFaster() throws Exception {
diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapTests.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapManualTests.java
similarity index 95%
rename from core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapTests.java
rename to core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapManualTests.java
index 93087626a4..d102680aa4 100644
--- a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapTests.java
+++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurrentNavigableMapManualTests.java
@@ -10,7 +10,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import static org.testng.Assert.*;
-public class ConcurrentNavigableMapTests {
+public class ConcurrentNavigableMapManualTests {
@Test
public void givenSkipListMap_whenAccessInMultiThreads_thenOrderingStable() throws InterruptedException {
@@ -18,9 +18,7 @@ public class ConcurrentNavigableMapTests {
updateMapConcurrently(skipListMap, 4);
- Iterator skipListIter = skipListMap
- .keySet()
- .iterator();
+ Iterator skipListIter = skipListMap.keySet().iterator();
int previous = skipListIter.next();
while (skipListIter.hasNext()) {
int current = skipListIter.next();
diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyManualTest.java
similarity index 97%
rename from core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyTest.java
rename to core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyManualTest.java
index 63a96dd5ee..43cbb2d293 100644
--- a/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyTest.java
+++ b/core-java/src/test/java/com/baeldung/java/concurrentmap/ConcurretMapMemoryConsistencyManualTest.java
@@ -10,7 +10,7 @@ import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;
-public class ConcurretMapMemoryConsistencyTest {
+public class ConcurretMapMemoryConsistencyManualTest {
@Test
public void givenConcurrentMap_whenSumParallel_thenCorrect() throws Exception {
diff --git a/core-java/src/test/java/com/baeldung/java/concurrentmodification/ConcurrentModificationUnitTest.java b/core-java/src/test/java/com/baeldung/java/concurrentmodification/ConcurrentModificationUnitTest.java
new file mode 100644
index 0000000000..f7a7bd5fe0
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/java/concurrentmodification/ConcurrentModificationUnitTest.java
@@ -0,0 +1,80 @@
+package com.baeldung.java.concurrentmodification;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.util.Lists.newArrayList;
+
+public class ConcurrentModificationUnitTest {
+ @Test(expected = ConcurrentModificationException.class)
+ public void givenIterating_whenRemoving_thenThrowException() throws InterruptedException {
+
+ List integers = newArrayList(1, 2, 3);
+
+ for (Integer integer : integers) {
+ integers.remove(1);
+ }
+ }
+
+ @Test
+ public void givenIterating_whenUsingIteratorRemove_thenNoError() throws InterruptedException {
+
+ List integers = newArrayList(1, 2, 3);
+
+ for (Iterator iterator = integers.iterator(); iterator.hasNext();) {
+ Integer integer = iterator.next();
+ if(integer == 2) {
+ iterator.remove();
+ }
+ }
+
+ assertThat(integers).containsExactly(1, 3);
+ }
+
+ @Test
+ public void givenIterating_whenUsingRemovalList_thenNoError() throws InterruptedException {
+
+ List integers = newArrayList(1, 2, 3);
+ List toRemove = newArrayList();
+
+ for (Integer integer : integers) {
+ if(integer == 2) {
+ toRemove.add(integer);
+ }
+ }
+ integers.removeAll(toRemove);
+
+ assertThat(integers).containsExactly(1, 3);
+ }
+
+ @Test
+ public void whenUsingRemoveIf_thenRemoveElements() throws InterruptedException {
+
+ Collection integers = newArrayList(1, 2, 3);
+
+ integers.removeIf(i -> i == 2);
+
+ assertThat(integers).containsExactly(1, 3);
+ }
+
+ @Test
+ public void whenUsingStream_thenRemoveElements() {
+ Collection integers = newArrayList(1, 2, 3);
+
+ List collected = integers
+ .stream()
+ .filter(i -> i != 2)
+ .map(Object::toString)
+ .collect(toList());
+
+ assertThat(collected).containsExactly("1", "3");
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/java/map/README.md b/core-java/src/test/java/com/baeldung/java/map/README.md
deleted file mode 100644
index 0bba153763..0000000000
--- a/core-java/src/test/java/com/baeldung/java/map/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-### Relevant Articles:
-- [The Java HashMap Under the Hood](http://www.baeldung.com/java-hashmap)
diff --git a/core-java/src/test/java/com/baeldung/java8/Java8GroupingByCollectorUnitTest.java b/core-java/src/test/java/com/baeldung/java8/Java8GroupingByCollectorUnitTest.java
new file mode 100644
index 0000000000..4452b4db9a
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/java8/Java8GroupingByCollectorUnitTest.java
@@ -0,0 +1,231 @@
+package com.baeldung.java8;
+
+import com.baeldung.java_8_features.groupingby.BlogPost;
+import com.baeldung.java_8_features.groupingby.BlogPostType;
+import org.junit.Test;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentMap;
+
+import static java.util.Comparator.comparingInt;
+import static java.util.stream.Collectors.*;
+import static org.junit.Assert.*;
+
+public class Java8GroupingByCollectorUnitTest {
+
+ private static final List posts = Arrays.asList(
+ new BlogPost("News item 1", "Author 1", BlogPostType.NEWS, 15),
+ new BlogPost("Tech review 1", "Author 2", BlogPostType.REVIEW, 5),
+ new BlogPost("Programming guide", "Author 1", BlogPostType.GUIDE, 20),
+ new BlogPost("News item 2", "Author 2", BlogPostType.NEWS, 35),
+ new BlogPost("Tech review 2", "Author 1", BlogPostType.REVIEW, 15));
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByType_thenGetAMapBetweenTypeAndPosts() {
+ Map> postsPerType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType));
+
+ assertEquals(2, postsPerType
+ .get(BlogPostType.NEWS)
+ .size());
+ assertEquals(1, postsPerType
+ .get(BlogPostType.GUIDE)
+ .size());
+ assertEquals(2, postsPerType
+ .get(BlogPostType.REVIEW)
+ .size());
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeAndTheirTitlesAreJoinedInAString_thenGetAMapBetweenTypeAndCsvTitles() {
+ Map postsPerType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType, mapping(BlogPost::getTitle, joining(", ", "Post titles: [", "]"))));
+
+ assertEquals("Post titles: [News item 1, News item 2]", postsPerType.get(BlogPostType.NEWS));
+ assertEquals("Post titles: [Programming guide]", postsPerType.get(BlogPostType.GUIDE));
+ assertEquals("Post titles: [Tech review 1, Tech review 2]", postsPerType.get(BlogPostType.REVIEW));
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeAndSumTheLikes_thenGetAMapBetweenTypeAndPostLikes() {
+ Map likesPerType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType, summingInt(BlogPost::getLikes)));
+
+ assertEquals(50, likesPerType
+ .get(BlogPostType.NEWS)
+ .intValue());
+ assertEquals(20, likesPerType
+ .get(BlogPostType.REVIEW)
+ .intValue());
+ assertEquals(20, likesPerType
+ .get(BlogPostType.GUIDE)
+ .intValue());
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeInAnEnumMap_thenGetAnEnumMapBetweenTypeAndPosts() {
+ EnumMap> postsPerType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType, () -> new EnumMap<>(BlogPostType.class), toList()));
+
+ assertEquals(2, postsPerType
+ .get(BlogPostType.NEWS)
+ .size());
+ assertEquals(1, postsPerType
+ .get(BlogPostType.GUIDE)
+ .size());
+ assertEquals(2, postsPerType
+ .get(BlogPostType.REVIEW)
+ .size());
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeInSets_thenGetAMapBetweenTypesAndSetsOfPosts() {
+ Map> postsPerType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType, toSet()));
+
+ assertEquals(2, postsPerType
+ .get(BlogPostType.NEWS)
+ .size());
+ assertEquals(1, postsPerType
+ .get(BlogPostType.GUIDE)
+ .size());
+ assertEquals(2, postsPerType
+ .get(BlogPostType.REVIEW)
+ .size());
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeConcurrently_thenGetAMapBetweenTypeAndPosts() {
+ ConcurrentMap> postsPerType = posts
+ .parallelStream()
+ .collect(groupingByConcurrent(BlogPost::getType));
+
+ assertEquals(2, postsPerType
+ .get(BlogPostType.NEWS)
+ .size());
+ assertEquals(1, postsPerType
+ .get(BlogPostType.GUIDE)
+ .size());
+ assertEquals(2, postsPerType
+ .get(BlogPostType.REVIEW)
+ .size());
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeAndAveragingLikes_thenGetAMapBetweenTypeAndAverageNumberOfLikes() {
+ Map averageLikesPerType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType, averagingInt(BlogPost::getLikes)));
+
+ assertEquals(25, averageLikesPerType
+ .get(BlogPostType.NEWS)
+ .intValue());
+ assertEquals(20, averageLikesPerType
+ .get(BlogPostType.GUIDE)
+ .intValue());
+ assertEquals(10, averageLikesPerType
+ .get(BlogPostType.REVIEW)
+ .intValue());
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeAndCounted_thenGetAMapBetweenTypeAndNumberOfPosts() {
+ Map numberOfPostsPerType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType, counting()));
+
+ assertEquals(2, numberOfPostsPerType
+ .get(BlogPostType.NEWS)
+ .intValue());
+ assertEquals(1, numberOfPostsPerType
+ .get(BlogPostType.GUIDE)
+ .intValue());
+ assertEquals(2, numberOfPostsPerType
+ .get(BlogPostType.REVIEW)
+ .intValue());
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeAndMaxingLikes_thenGetAMapBetweenTypeAndMaximumNumberOfLikes() {
+ Map> maxLikesPerPostType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType, maxBy(comparingInt(BlogPost::getLikes))));
+
+ assertTrue(maxLikesPerPostType
+ .get(BlogPostType.NEWS)
+ .isPresent());
+ assertEquals(35, maxLikesPerPostType
+ .get(BlogPostType.NEWS)
+ .get()
+ .getLikes());
+
+ assertTrue(maxLikesPerPostType
+ .get(BlogPostType.GUIDE)
+ .isPresent());
+ assertEquals(20, maxLikesPerPostType
+ .get(BlogPostType.GUIDE)
+ .get()
+ .getLikes());
+
+ assertTrue(maxLikesPerPostType
+ .get(BlogPostType.REVIEW)
+ .isPresent());
+ assertEquals(15, maxLikesPerPostType
+ .get(BlogPostType.REVIEW)
+ .get()
+ .getLikes());
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByAuthorAndThenByType_thenGetAMapBetweenAuthorAndMapsBetweenTypeAndBlogPosts() {
+ Map>> map = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getAuthor, groupingBy(BlogPost::getType)));
+
+ assertEquals(1, map
+ .get("Author 1")
+ .get(BlogPostType.NEWS)
+ .size());
+ assertEquals(1, map
+ .get("Author 1")
+ .get(BlogPostType.GUIDE)
+ .size());
+ assertEquals(1, map
+ .get("Author 1")
+ .get(BlogPostType.REVIEW)
+ .size());
+
+ assertEquals(1, map
+ .get("Author 2")
+ .get(BlogPostType.NEWS)
+ .size());
+ assertEquals(1, map
+ .get("Author 2")
+ .get(BlogPostType.REVIEW)
+ .size());
+ assertNull(map
+ .get("Author 2")
+ .get(BlogPostType.GUIDE));
+ }
+
+ @Test
+ public void givenAListOfPosts_whenGroupedByTypeAndSummarizingLikes_thenGetAMapBetweenTypeAndSummary() {
+ Map likeStatisticsPerType = posts
+ .stream()
+ .collect(groupingBy(BlogPost::getType, summarizingInt(BlogPost::getLikes)));
+
+ IntSummaryStatistics newsLikeStatistics = likeStatisticsPerType.get(BlogPostType.NEWS);
+
+ assertEquals(2, newsLikeStatistics.getCount());
+ assertEquals(50, newsLikeStatistics.getSum());
+ assertEquals(25.0, newsLikeStatistics.getAverage(), 0.001);
+ assertEquals(35, newsLikeStatistics.getMax());
+ assertEquals(15, newsLikeStatistics.getMin());
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/java8/Java8MaxMinTest.java b/core-java/src/test/java/com/baeldung/java8/Java8MaxMinTest.java
new file mode 100644
index 0000000000..b0e514124d
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/java8/Java8MaxMinTest.java
@@ -0,0 +1,47 @@
+package com.baeldung.java8;
+
+import com.baeldung.java_8_features.Person;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import static org.junit.Assert.assertEquals;
+
+public class Java8MaxMinTest {
+
+ @Test
+ public void whenListIsOfIntegerThenMaxCanBeDoneUsingIntegerComparator() {
+ //given
+ final List listOfIntegers = Arrays.asList(1, 2, 3, 4, 56, 7, 89, 10);
+ final Integer expectedResult = 89;
+
+ //then
+ final Integer max = listOfIntegers
+ .stream()
+ .mapToInt(v -> v)
+ .max().orElseThrow(NoSuchElementException::new);
+
+ assertEquals("Should be 89", expectedResult, max);
+ }
+
+ @Test
+ public void whenListIsOfPersonObjectThenMinCanBeDoneUsingCustomComparatorThroughLambda() {
+ //given
+ final Person alex = new Person("Alex", 23);
+ final Person john = new Person("John", 40);
+ final Person peter = new Person("Peter", 32);
+ final List people = Arrays.asList(alex, john, peter);
+
+ //then
+ final Person minByAge = people
+ .stream()
+ .min(Comparator.comparing(Person::getAge))
+ .orElseThrow(NoSuchElementException::new);
+
+ assertEquals("Should be Alex", alex, minByAge);
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityTest.java b/core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityTest.java
new file mode 100644
index 0000000000..dec7dbe6aa
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityTest.java
@@ -0,0 +1,21 @@
+package com.baeldung.junit4vstestng;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class DivisibilityTest {
+
+ private static int number;
+
+ @BeforeClass
+ public static void setup() {
+ number = 40;
+ }
+
+ @Test
+ public void givenNumber_whenDivisibleByTwo_thenCorrect() {
+ assertEquals(number % 2, 0);
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedTests.java b/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedTests.java
new file mode 100644
index 0000000000..e9a9c6a07a
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedTests.java
@@ -0,0 +1,34 @@
+package com.baeldung.junit4vstestng;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(value = Parameterized.class)
+public class ParametrizedTests {
+
+ private int value;
+ private boolean isEven;
+
+ public ParametrizedTests(int value, boolean isEven) {
+ this.value = value;
+ this.isEven = isEven;
+ }
+
+ @Parameters
+ public static Collection data() {
+ Object[][] data = new Object[][]{{1, false}, {2, true}, {4, true}};
+ return Arrays.asList(data);
+ }
+
+ @Test
+ public void givenParametrizedNumber_ifEvenCheckOK_thenCorrect() {
+ Assert.assertEquals(isEven, value % 2 == 0);
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/RegistrationTest.java b/core-java/src/test/java/com/baeldung/junit4vstestng/RegistrationTest.java
new file mode 100644
index 0000000000..4aa1fa1a17
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/RegistrationTest.java
@@ -0,0 +1,15 @@
+package com.baeldung.junit4vstestng;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class RegistrationTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationTest.class);
+
+ @Test
+ public void whenCalledFromSuite_thanOK() {
+ LOGGER.info("Registration successful");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/SignInTest.java b/core-java/src/test/java/com/baeldung/junit4vstestng/SignInTest.java
new file mode 100644
index 0000000000..bb908ff37e
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/SignInTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.junit4vstestng;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SignInTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SignInTest.class);
+
+ @Test
+ public void whenCalledFromSuite_thanOK() {
+ LOGGER.info("SignIn successful");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/StringCaseTest.java b/core-java/src/test/java/com/baeldung/junit4vstestng/StringCaseTest.java
new file mode 100644
index 0000000000..520017e4c1
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/StringCaseTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.junit4vstestng;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class StringCaseTest {
+
+ private static String data;
+
+ @BeforeClass
+ public static void setup() {
+ data = "HELLO BAELDUNG";
+ }
+
+ @Test
+ public void givenString_whenAllCaps_thenCorrect() {
+ assertEquals(data.toUpperCase(), data);
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/SuiteTest.java b/core-java/src/test/java/com/baeldung/junit4vstestng/SuiteTest.java
new file mode 100644
index 0000000000..effd7fa10a
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/SuiteTest.java
@@ -0,0 +1,10 @@
+package com.baeldung.junit4vstestng;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({ RegistrationTest.class, SignInTest.class })
+public class SuiteTest {
+
+}
diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/SummationServiceTest.java b/core-java/src/test/java/com/baeldung/junit4vstestng/SummationServiceTest.java
new file mode 100644
index 0000000000..7d1bf3b7af
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/SummationServiceTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.junit4vstestng;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SummationServiceTest {
+ private static List numbers;
+
+ @BeforeClass
+ public static void initialize() {
+ numbers = new ArrayList<>();
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ numbers = null;
+ }
+
+ @Before
+ public void runBeforeEachTest() {
+ numbers.add(1);
+ numbers.add(2);
+ numbers.add(3);
+ }
+
+ @After
+ 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);
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void givenNumber_whenThrowsException_thenCorrect() {
+ int i = 1 / 0;
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/strategy/StrategyDesignPatternUnitTest.java b/core-java/src/test/java/com/baeldung/strategy/StrategyDesignPatternUnitTest.java
new file mode 100644
index 0000000000..7ca1d000be
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/strategy/StrategyDesignPatternUnitTest.java
@@ -0,0 +1,73 @@
+package com.baeldung.strategy;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+
+import static com.baeldung.strategy.Discounter.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class StrategyDesignPatternUnitTest {
+ @Test
+ public void shouldDivideByTwo_WhenApplyingStaffDiscounter() {
+ Discounter staffDiscounter = new EasterDiscounter();
+
+ final BigDecimal discountedValue = staffDiscounter
+ .apply(BigDecimal.valueOf(100));
+
+ assertThat(discountedValue)
+ .isEqualByComparingTo(BigDecimal.valueOf(50));
+ }
+
+ @Test
+ public void shouldDivideByTwo_WhenApplyingStaffDiscounterWithAnonyousTypes() {
+ Discounter staffDiscounter = new Discounter() {
+ @Override
+ public BigDecimal apply( BigDecimal amount) {
+ return amount.multiply(BigDecimal.valueOf(0.5));
+ }
+ };
+
+ final BigDecimal discountedValue = staffDiscounter
+ .apply(BigDecimal.valueOf(100));
+
+ assertThat(discountedValue)
+ .isEqualByComparingTo(BigDecimal.valueOf(50));
+ }
+
+ @Test
+ public void shouldDivideByTwo_WhenApplyingStaffDiscounterWithLamda() {
+ Discounter staffDiscounter = amount -> amount.multiply(BigDecimal.valueOf(0.5));
+
+ final BigDecimal discountedValue = staffDiscounter
+ .apply(BigDecimal.valueOf(100));
+
+ assertThat(discountedValue)
+ .isEqualByComparingTo(BigDecimal.valueOf(50));
+ }
+
+ @Test
+ public void shouldApplyAllDiscounts() {
+ List discounters = Arrays.asList(christmas(), newYear(), easter());
+
+ BigDecimal amount = BigDecimal.valueOf(100);
+
+ final Discounter combinedDiscounter = discounters
+ .stream()
+ .reduce(v -> v, Discounter::combine);
+
+ combinedDiscounter.apply(amount);
+ }
+
+ @Test
+ public void shouldChainDiscounters() {
+ final Function combinedDiscounters = Discounter
+ .christmas()
+ .andThen(newYear());
+
+ combinedDiscounters.apply(BigDecimal.valueOf(100));
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/stream/InfiniteStreamTest.java b/core-java/src/test/java/com/baeldung/stream/InfiniteStreamTest.java
new file mode 100644
index 0000000000..a1537a1735
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/stream/InfiniteStreamTest.java
@@ -0,0 +1,48 @@
+package com.baeldung.stream;
+
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertEquals;
+
+public class InfiniteStreamTest {
+
+ @Test
+ public void givenInfiniteStream_whenUseIntermediateLimitMethod_thenShouldTerminateInFiniteTime() {
+ //given
+ Stream infiniteStream = Stream.iterate(0, i -> i + 2);
+
+ //when
+ List collect = infiniteStream
+ .limit(10)
+ .collect(Collectors.toList());
+
+ //then
+ assertEquals(collect, Arrays.asList(0, 2, 4, 6, 8, 10, 12, 14, 16, 18));
+ }
+
+ @Test
+ public void givenInfiniteStreamOfRandomInts_whenUseLimit_shouldTerminateInFiniteTime() {
+ //given
+ Supplier randomUUIDSupplier = UUID::randomUUID;
+ Stream infiniteStreamOfRandomUUID = Stream.generate(randomUUIDSupplier);
+
+ //when
+ List randomInts = infiniteStreamOfRandomUUID
+ .skip(10)
+ .limit(10)
+ .collect(Collectors.toList());
+
+ //then
+ assertEquals(randomInts.size(), 10);
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/string/JoinerSplitterTest.java b/core-java/src/test/java/com/baeldung/string/JoinerSplitterTest.java
new file mode 100644
index 0000000000..a89f89b8d5
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/string/JoinerSplitterTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.string;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.baeldung.string.JoinerSplitter;
+
+public class JoinerSplitterTest {
+
+ @Test
+ public void provided_array_convert_to_stream_and_convert_to_string() {
+
+ String[] programming_languages = {"java", "python", "nodejs", "ruby"};
+
+ String expectation = "java,python,nodejs,ruby";
+
+ String result = JoinerSplitter.join(programming_languages);
+ assertEquals(result, expectation);
+ }
+
+ @Test
+ public void givenArray_transformedToStream_convertToPrefixPostfixString() {
+
+ String[] programming_languages = {"java", "python",
+ "nodejs", "ruby"};
+ String expectation = "[java,python,nodejs,ruby]";
+
+ String result = JoinerSplitter.joinWithPrefixPostFix(programming_languages);
+ assertEquals(result, expectation);
+ }
+
+ @Test
+ public void givenString_transformedToStream_convertToList() {
+
+ String programming_languages = "java,python,nodejs,ruby";
+
+ List expectation = new ArrayList();
+ expectation.add("java");
+ expectation.add("python");
+ expectation.add("nodejs");
+ expectation.add("ruby");
+
+ List result = JoinerSplitter.split(programming_languages);
+
+ assertEquals(result, expectation);
+ }
+
+ @Test
+ public void givenString_transformedToStream_convertToListOfChar() {
+
+ String programming_languages = "java,python,nodejs,ruby";
+
+ List expectation = new ArrayList();
+ char[] charArray = programming_languages.toCharArray();
+ for (char c : charArray) {
+ expectation.add(c);
+ }
+
+ List result = JoinerSplitter.splitToListOfChar(programming_languages);
+ assertEquals(result, expectation);
+
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/weakhashmap/WeakHashMapTest.java b/core-java/src/test/java/com/baeldung/weakhashmap/WeakHashMapTest.java
new file mode 100644
index 0000000000..1c5a261eea
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/weakhashmap/WeakHashMapTest.java
@@ -0,0 +1,72 @@
+package com.baeldung.weakhashmap;
+
+
+import org.junit.Test;
+
+import java.util.WeakHashMap;
+import java.util.concurrent.TimeUnit;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static org.junit.Assert.assertTrue;
+
+public class WeakHashMapTest {
+
+ @Test
+ public void givenWeakHashMap_whenCacheValueThatHasNoReferenceToIt_GCShouldReclaimThatObject() {
+ //given
+ WeakHashMap map = new WeakHashMap<>();
+ BigImage bigImage = new BigImage("image_id");
+ UniqueImageName imageName = new UniqueImageName("name_of_big_image");
+
+ map.put(imageName, bigImage);
+ assertTrue(map.containsKey(imageName));
+
+ //when big image key is not reference anywhere
+ imageName = null;
+ System.gc();
+
+ //then GC will finally reclaim that object
+ await().atMost(10, TimeUnit.SECONDS).until(map::isEmpty);
+ }
+
+ @Test
+ public void givenWeakHashMap_whenCacheValueThatHasNoReferenceToIt_GCShouldReclaimThatObjectButLeaveReferencedObject() {
+ //given
+ WeakHashMap map = new WeakHashMap<>();
+ BigImage bigImageFirst = new BigImage("foo");
+ UniqueImageName imageNameFirst = new UniqueImageName("name_of_big_image");
+
+ BigImage bigImageSecond = new BigImage("foo_2");
+ UniqueImageName imageNameSecond = new UniqueImageName("name_of_big_image_2");
+
+ map.put(imageNameFirst, bigImageFirst);
+ map.put(imageNameSecond, bigImageSecond);
+ assertTrue(map.containsKey(imageNameFirst));
+ assertTrue(map.containsKey(imageNameSecond));
+
+ //when
+ imageNameFirst = null;
+ System.gc();
+
+ //then
+ await().atMost(10, TimeUnit.SECONDS).until(() -> map.size() == 1);
+ await().atMost(10, TimeUnit.SECONDS).until(() -> map.containsKey(imageNameSecond));
+ }
+
+
+ class BigImage {
+ public final String imageId;
+
+ BigImage(String imageId) {
+ this.imageId = imageId;
+ }
+ }
+
+ class UniqueImageName {
+ public final String imageName;
+
+ UniqueImageName(String imageName) {
+ this.imageName = imageName;
+ }
+ }
+}
diff --git a/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java b/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java
index 4febe7c9fc..08f98025c3 100644
--- a/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java
+++ b/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java
@@ -1,12 +1,12 @@
package org.baeldung.java;
-import java.nio.charset.Charset;
-import java.util.Random;
-
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.math3.random.RandomDataGenerator;
import org.junit.Test;
+import java.nio.charset.Charset;
+import java.util.Random;
+
public class JavaRandomUnitTest {
// tests - random long
@@ -164,7 +164,7 @@ public class JavaRandomUnitTest {
final int targetStringLength = 10;
final StringBuilder buffer = new StringBuilder(targetStringLength);
for (int i = 0; i < targetStringLength; i++) {
- final int randomLimitedInt = leftLimit + (int) (new Random().nextFloat() * (rightLimit - leftLimit));
+ final int randomLimitedInt = leftLimit + (int) (new Random().nextFloat() * (rightLimit - leftLimit + 1));
buffer.append((char) randomLimitedInt);
}
final String generatedString = buffer.toString();
diff --git a/core-java/src/test/java/org/baeldung/java/streams/ThreadPoolInParallelStreamTest.java b/core-java/src/test/java/org/baeldung/java/streams/ThreadPoolInParallelStreamTest.java
index 5fd3fa4cb0..c2eb1cff5d 100644
--- a/core-java/src/test/java/org/baeldung/java/streams/ThreadPoolInParallelStreamTest.java
+++ b/core-java/src/test/java/org/baeldung/java/streams/ThreadPoolInParallelStreamTest.java
@@ -1,5 +1,5 @@
package org.baeldung.java.streams;
-
+
import org.junit.Test;
import java.util.ArrayList;
@@ -14,28 +14,25 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ThreadPoolInParallelStreamTest {
-
+
@Test
- public void giveRangeOfLongs_whenSummedInParallel_shouldBeEqualToExpectedTotal()
- throws InterruptedException, ExecutionException {
+ public void giveRangeOfLongs_whenSummedInParallel_shouldBeEqualToExpectedTotal() throws InterruptedException, ExecutionException {
long firstNum = 1;
long lastNum = 1_000_000;
- List aList = LongStream.rangeClosed(firstNum, lastNum).boxed()
- .collect(Collectors.toList());
+ List aList = LongStream.rangeClosed(firstNum, lastNum).boxed().collect(Collectors.toList());
ForkJoinPool customThreadPool = new ForkJoinPool(4);
- long actualTotal = customThreadPool.submit(() -> aList.parallelStream()
- .reduce(0L, Long::sum)).get();
-
- assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal);
+ long actualTotal = customThreadPool.submit(() -> aList.parallelStream().reduce(0L, Long::sum)).get();
+
+ assertEquals((lastNum + firstNum) * lastNum / 2, actualTotal);
}
-
+
@Test
- public void givenList_whenCallingParallelStream_shouldBeParallelStream(){
+ public void givenList_whenCallingParallelStream_shouldBeParallelStream() {
List aList = new ArrayList<>();
Stream parallelStream = aList.parallelStream();
-
+
assertTrue(parallelStream.isParallel());
}
}
diff --git a/couchbase-sdk/README.md b/couchbase-sdk/README.md
index 9cdcdea012..f124a0192c 100644
--- a/couchbase-sdk/README.md
+++ b/couchbase-sdk/README.md
@@ -4,6 +4,7 @@
- [Introduction to Couchbase SDK for Java](http://www.baeldung.com/java-couchbase-sdk)
- [Using Couchbase in a Spring Application](http://www.baeldung.com/couchbase-sdk-spring)
- [Asynchronous Batch Opereations in Couchbase](http://www.baeldung.com/async-batch-operations-in-couchbase)
+- [Querying Couchbase with MapReduce Views](http://www.baeldung.com/couchbase-query-mapreduce-view)
### Overview
This Maven project contains the Java code for the Couchbase entities and Spring services
diff --git a/couchbase-sdk/pom.xml b/couchbase-sdk/pom.xml
index 301fd81c51..1200fab454 100644
--- a/couchbase-sdk/pom.xml
+++ b/couchbase-sdk/pom.xml
@@ -102,10 +102,10 @@
1.8
UTF-8
- 2.3.6
- 4.3.4.RELEASE
- 1.1.7
- 1.7.21
+ 2.4.0
+ 4.3.5.RELEASE
+ 1.1.8
+ 1.7.22
4.12
3.5
3.6.0
diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java
new file mode 100644
index 0000000000..9ac1bbb3f7
--- /dev/null
+++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java
@@ -0,0 +1,6 @@
+package com.baeldung.couchbase.mapreduce;
+
+public interface CouchbaseKeyGenerator {
+
+ String generateKey(T t);
+}
diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java
new file mode 100644
index 0000000000..78baaa155c
--- /dev/null
+++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java
@@ -0,0 +1,10 @@
+package com.baeldung.couchbase.mapreduce;
+
+@SuppressWarnings("serial")
+public class DuplicateKeyException extends Exception {
+
+ public DuplicateKeyException(String s) {
+ super(s);
+ }
+
+}
diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java
new file mode 100644
index 0000000000..9baf4a4f43
--- /dev/null
+++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java
@@ -0,0 +1,11 @@
+package com.baeldung.couchbase.mapreduce;
+
+import java.util.UUID;
+
+public class RandomUUIDGenerator implements CouchbaseKeyGenerator {
+
+ @Override
+ public String generateKey(T t) {
+ return UUID.randomUUID().toString();
+ }
+}
diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java
new file mode 100644
index 0000000000..846aba716a
--- /dev/null
+++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java
@@ -0,0 +1,50 @@
+package com.baeldung.couchbase.mapreduce;
+
+public class StudentGrade {
+
+ private String name;
+ private String course;
+ private Integer grade;
+ private Integer hours;
+
+ public StudentGrade() { }
+
+ public StudentGrade(String name, String course, Integer grade, Integer hours) {
+ this.name = name;
+ this.course = course;
+ this.grade = grade;
+ this.hours = hours;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getCourse() {
+ return course;
+ }
+
+ public void setCourse(String course) {
+ this.course = course;
+ }
+
+ public Integer getGrade() {
+ return grade;
+ }
+
+ public void setGrade(Integer grade) {
+ this.grade = grade;
+ }
+
+ public Integer getHours() {
+ return hours;
+ }
+
+ public void setHours(Integer hours) {
+ this.hours = hours;
+ }
+}
diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java
new file mode 100644
index 0000000000..680e37ba57
--- /dev/null
+++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java
@@ -0,0 +1,9 @@
+package com.baeldung.couchbase.mapreduce;
+
+public class StudentGradeKeyGenerator implements CouchbaseKeyGenerator {
+
+ @Override
+ public String generateKey(StudentGrade g) {
+ return g.getName() + ":" + g.getCourse();
+ }
+}
diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java
new file mode 100644
index 0000000000..37bb03645a
--- /dev/null
+++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java
@@ -0,0 +1,70 @@
+package com.baeldung.couchbase.mapreduce;
+
+import com.couchbase.client.deps.com.fasterxml.jackson.databind.ObjectMapper;
+import com.couchbase.client.java.document.json.JsonArray;
+import com.couchbase.client.java.view.ViewQuery;
+
+public class StudentGradeQueryBuilder {
+
+ final ObjectMapper om = new ObjectMapper();
+
+ public ViewQuery findAll() {
+ return ViewQuery.from("studentGrades", "findByCourse");
+ }
+
+ public ViewQuery findByCourse(String course) {
+ return ViewQuery.from("studentGrades", "findByCourse")
+ .key(course);
+ }
+
+ public ViewQuery findByCourses(String... courses) {
+ return ViewQuery.from("studentGrades", "findByCourse")
+ .keys(JsonArray.from(courses));
+ }
+
+ public ViewQuery findByGradeInRange(int lower, int upper, boolean inclusiveEnd) {
+ return ViewQuery.from("studentGrades", "findByGrade")
+ .startKey(lower)
+ .endKey(upper)
+ .inclusiveEnd(inclusiveEnd);
+ }
+
+ public ViewQuery findByGradeLessThan(int upper) {
+ return ViewQuery.from("studentGrades", "findByGrade")
+ .endKey(upper)
+ .inclusiveEnd(false);
+ }
+
+ public ViewQuery findByGradeGreaterThan(int lower) {
+ return ViewQuery.from("studentGrades", "findByGrade")
+ .startKey(lower);
+ }
+
+ public ViewQuery findByCourseAndGradeInRange(String course, int minGrade, int maxGrade, boolean inclusiveEnd) {
+ return ViewQuery.from("studentGrades", "findByCourseAndGrade")
+ .startKey(JsonArray.from(course, minGrade))
+ .endKey(JsonArray.from(course, maxGrade))
+ .inclusiveEnd(inclusiveEnd);
+ }
+
+ public ViewQuery findTopGradesByCourse(String course, int limit) {
+ return ViewQuery.from("studentGrades", "findByCourseAndGrade")
+ .startKey(JsonArray.from(course, 100))
+ .endKey(JsonArray.from(course, 0))
+ .inclusiveEnd(true)
+ .descending()
+ .limit(limit);
+ }
+
+ public ViewQuery countStudentsByCourse() {
+ return ViewQuery.from("studentGrades", "countStudentsByCourse")
+ .reduce()
+ .groupLevel(1);
+ }
+
+ public ViewQuery sumCreditsByStudent() {
+ return ViewQuery.from("studentGrades", "sumCreditsByStudent")
+ .reduce()
+ .groupLevel(1);
+ }
+}
diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java
new file mode 100644
index 0000000000..2d2c63f699
--- /dev/null
+++ b/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java
@@ -0,0 +1,169 @@
+package com.baeldung.couchbase.mapreduce;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.couchbase.client.deps.com.fasterxml.jackson.databind.ObjectMapper;
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.CouchbaseCluster;
+import com.couchbase.client.java.document.JsonDocument;
+import com.couchbase.client.java.document.json.JsonArray;
+import com.couchbase.client.java.document.json.JsonObject;
+import com.couchbase.client.java.view.ViewQuery;
+import com.couchbase.client.java.view.ViewResult;
+import com.couchbase.client.java.view.ViewRow;
+
+public class StudentGradeService {
+
+ final CouchbaseKeyGenerator keyGenerator;
+ final CouchbaseCluster cluster;
+ final Bucket bucket;
+ final ObjectMapper om = new ObjectMapper();
+ final StudentGradeQueryBuilder queryBuilder;
+
+ public StudentGradeService(CouchbaseKeyGenerator keyGenerator) {
+ this.keyGenerator = keyGenerator;
+ this.queryBuilder = new StudentGradeQueryBuilder();
+ cluster = CouchbaseCluster.create("127.0.0.1");
+ bucket = cluster.openBucket("baeldung-tutorial");
+ }
+
+ public String insert(StudentGrade studentGrade) throws DuplicateKeyException {
+ String id = keyGenerator.generateKey(studentGrade);
+ if(bucket.exists(id)) {
+ throw new DuplicateKeyException("document already exists with key " + id);
+ }
+ JsonObject content = JsonObject.empty()
+ .put("type", "StudentGrade")
+ .put("name", studentGrade.getName())
+ .put("course", studentGrade.getCourse())
+ .put("grade", studentGrade.getGrade())
+ .put("hours", studentGrade.getHours());
+ JsonDocument doc = JsonDocument.create(id, content);
+ bucket.insert(doc);
+ return id;
+ }
+
+ public List findAll() {
+ ViewQuery query = queryBuilder.findAll();
+ ViewResult result = bucket.query(query);
+ return extractDocuments(result);
+ }
+
+ private List extractDocuments(ViewResult result) {
+ List docs = new ArrayList<>();
+ for(ViewRow row : result.allRows()) {
+ JsonDocument doc = row.document();
+ docs.add(doc);
+ }
+ return docs;
+ }
+
+ public List findByCourse(String course) {
+ ViewQuery query = queryBuilder.findByCourse(course);
+ ViewResult result = bucket.query(query);
+ return extractDocuments(result);
+ }
+
+ public List findByCourses(String... courses) {
+ ViewQuery query = queryBuilder.findByCourses(courses);
+ ViewResult result = bucket.query(query);
+ return extractDocuments(result);
+ }
+
+ public List findByGradeInRange(int lower, int upper, boolean inclusiveEnd) {
+ ViewQuery query = queryBuilder.findByGradeInRange(lower, upper, inclusiveEnd);
+ ViewResult result = bucket.query(query);
+ return extractDocuments(result);
+ }
+
+ public List findByGradeLessThan(int upper) {
+ ViewQuery query = queryBuilder.findByGradeLessThan(upper);
+ ViewResult result = bucket.query(query);
+ return extractDocuments(result);
+ }
+
+ public List findByGradeGreaterThan(int lower) {
+ ViewQuery query = queryBuilder.findByGradeGreaterThan(lower);
+ ViewResult result = bucket.query(query);
+ return extractDocuments(result);
+ }
+
+ public List findByCourseAndGradeInRange(String course, int minGrade, int maxGrade, boolean inclusiveEnd) {
+ ViewQuery query = queryBuilder.findByCourseAndGradeInRange(course, minGrade, maxGrade, inclusiveEnd);
+ ViewResult result = bucket.query(query);
+ return extractDocuments(result);
+ }
+
+ public List findTopGradesByCourse(String course, int limit) {
+ ViewQuery query = queryBuilder.findTopGradesByCourse(course, limit);
+ ViewResult result = bucket.query(query);
+ return extractDocuments(result);
+ }
+
+ public Map countStudentsByCourse() {
+ ViewQuery query = ViewQuery.from("studentGrades", "countStudentsByCourse")
+ .reduce()
+ .groupLevel(1);
+ ViewResult result = bucket.query(query);
+
+ Map numStudentsByCourse = new HashMap<>();
+ for(ViewRow row : result.allRows()) {
+ JsonArray keyArray = (JsonArray) row.key();
+ String course = keyArray.getString(0);
+ long count = Long.valueOf(row.value().toString());
+ numStudentsByCourse.put(course, count);
+ }
+
+ return numStudentsByCourse;
+ }
+
+ public Map sumCreditHoursByStudent() {
+ ViewQuery query = ViewQuery.from("studentGrades", "sumHoursByStudent")
+ .reduce()
+ .groupLevel(1);
+ ViewResult result = bucket.query(query);
+
+ Map creditHoursByStudent = new HashMap<>();
+ for(ViewRow row : result.allRows()) {
+ String course = (String) row.key();
+ long sum = Long.valueOf(row.value().toString());
+ creditHoursByStudent.put(course, sum);
+ }
+
+ return creditHoursByStudent;
+ }
+
+ public Map sumGradePointsByStudent() {
+ ViewQuery query = ViewQuery.from("studentGrades", "sumGradePointsByStudent")
+ .reduce()
+ .groupLevel(1);
+ ViewResult result = bucket.query(query);
+
+ Map gradePointsByStudent = new HashMap<>();
+ for(ViewRow row : result.allRows()) {
+ String course = (String) row.key();
+ long sum = Long.valueOf(row.value().toString());
+ gradePointsByStudent.put(course, sum);
+ }
+
+ return gradePointsByStudent;
+ }
+
+ public Map calculateGpaByStudent() {
+ Map creditHoursByStudent = sumCreditHoursByStudent();
+ Map gradePointsByStudent = sumGradePointsByStudent();
+
+ Map result = new HashMap<>();
+ for(Entry creditHoursEntry : creditHoursByStudent.entrySet()) {
+ String name = creditHoursEntry.getKey();
+ long totalHours = creditHoursEntry.getValue();
+ long totalGradePoints = gradePointsByStudent.get(name);
+ result.put(name, ((float) totalGradePoints / totalHours));
+ }
+ return result;
+ }
+}
diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java b/couchbase-sdk/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java
new file mode 100644
index 0000000000..00d462e32a
--- /dev/null
+++ b/couchbase-sdk/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java
@@ -0,0 +1,150 @@
+package com.baeldung.couchbase.mapreduce;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.couchbase.client.java.document.JsonDocument;
+import com.couchbase.client.java.view.ViewResult;
+import com.couchbase.client.java.view.ViewRow;
+
+public class StudentGradeServiceIntegrationTest {
+ private static final Logger logger = LoggerFactory.getLogger(StudentGradeServiceIntegrationTest.class);
+
+ static StudentGradeService studentGradeService;
+ static Set gradeIds = new HashSet<>();
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ studentGradeService = new StudentGradeService(new StudentGradeKeyGenerator());
+ insertStudentGrade(new StudentGrade("John Doe", "History", 80, 3));
+ insertStudentGrade(new StudentGrade("Jane Doe", "History", 89, 3));
+ insertStudentGrade(new StudentGrade("Bob Smith", "History", 90, 3));
+ insertStudentGrade(new StudentGrade("Mary Jones", "History", 92, 3));
+ insertStudentGrade(new StudentGrade("Jane Doe", "Math", 59, 3));
+ insertStudentGrade(new StudentGrade("Bob Smith", "Math", 91, 3));
+ insertStudentGrade(new StudentGrade("Mary Jones", "Math", 86, 3));
+ insertStudentGrade(new StudentGrade("John Doe", "Science", 85, 4));
+ insertStudentGrade(new StudentGrade("Bob Smith", "Science", 97, 4));
+ insertStudentGrade(new StudentGrade("Mary Jones", "Science", 84, 4));
+ }
+
+ private static void insertStudentGrade(StudentGrade studentGrade) {
+ try {
+ String id = studentGradeService.insert(studentGrade);
+ gradeIds.add(id);
+ } catch (DuplicateKeyException e) {
+ }
+ }
+
+ @Test
+ public final void whenFindAll_thenSuccess() {
+ List docs = studentGradeService.findAll();
+ printDocuments(docs);
+ }
+
+ @Test
+ public final void whenFindByCourse_thenSuccess() {
+ List docs = studentGradeService.findByCourse("History");
+ printDocuments(docs);
+ }
+
+ @Test
+ public final void whenFindByCourses_thenSuccess() {
+ List docs = studentGradeService.findByCourses("History", "Science");
+ printDocuments(docs);
+ }
+
+ @Test
+ public final void whenFindByGradeInRange_thenSuccess() {
+ List docs = studentGradeService.findByGradeInRange(80, 89, true);
+ printDocuments(docs);
+ }
+
+ @Test
+ public final void whenFindByGradeLessThan_thenSuccess() {
+ List docs = studentGradeService.findByGradeLessThan(60);
+ printDocuments(docs);
+ }
+
+ @Test
+ public final void whenFindByGradeGreaterThan_thenSuccess() {
+ List docs = studentGradeService.findByGradeGreaterThan(90);
+ printDocuments(docs);
+ }
+
+ @Test
+ public final void whenFindByCourseAndGradeInRange_thenSuccess() {
+ List docs = studentGradeService.findByCourseAndGradeInRange("Math", 80, 89, true);
+ printDocuments(docs);
+ }
+
+ @Test
+ public final void whenFindTopGradesByCourse_thenSuccess() {
+ List docs = studentGradeService.findTopGradesByCourse("Science", 2);
+ printDocuments(docs);
+ }
+
+ @Test
+ public final void whenCountStudentsByCourse_thenSuccess() {
+ Map map = studentGradeService.countStudentsByCourse();
+ printMap(map);
+ }
+
+ @Test
+ public final void whenSumCreditHoursByStudent_thenSuccess() {
+ Map map = studentGradeService.sumCreditHoursByStudent();
+ printMap(map);
+ }
+
+ @Test
+ public final void whenSumGradePointsByStudent_thenSuccess() {
+ Map map = studentGradeService.sumGradePointsByStudent();
+ printMap(map);
+ }
+
+ @Test
+ public final void whenCalculateGpaByStudent_thenSuccess() {
+ Map map = studentGradeService.calculateGpaByStudent();
+ printGpaMap(map);
+ }
+
+ private void printMap(Map map) {
+ for(Map.Entry entry : map.entrySet()) {
+ logger.info(entry.getKey() + "=" + entry.getValue());
+ }
+ }
+
+ private void printGpaMap(Map map) {
+ for(Map.Entry entry : map.entrySet()) {
+ logger.info(entry.getKey() + "=" + entry.getValue());
+ }
+ }
+
+ private void printDocuments(List docs) {
+ for(JsonDocument doc : docs) {
+ String key = doc.id();
+ logger.info(key + " = " + doc.content().toString());
+ }
+ }
+
+ private void printViewResultDocuments(ViewResult result) {
+ for(ViewRow row : result.allRows()) {
+ JsonDocument doc = row.document();
+ String key = doc.id();
+ logger.info(key + "=" + doc.content().toString());
+ }
+ }
+
+ private void printViewResultRows(ViewResult result) {
+ for(ViewRow row : result.allRows()) {
+ logger.info(row.toString());
+ }
+ }
+}
diff --git a/couchbase-sdk/src/test/resources/logback.xml b/couchbase-sdk/src/test/resources/logback.xml
new file mode 100644
index 0000000000..efcc6fb4c7
--- /dev/null
+++ b/couchbase-sdk/src/test/resources/logback.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ web - %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/disruptor/README.md b/disruptor/README.md
index e69de29bb2..779b1e89c4 100644
--- a/disruptor/README.md
+++ b/disruptor/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Concurrency with LMAX Disruptor – An Introduction](http://www.baeldung.com/lmax-disruptor-concurrency)
diff --git a/ejb/README.md b/ejb/README.md
new file mode 100644
index 0000000000..08392bc80d
--- /dev/null
+++ b/ejb/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Guide to EJB Set-up](http://www.baeldung.com/ejb-intro)
diff --git a/guava/README.md b/guava/README.md
index 40e7f19f41..ee224bae5f 100644
--- a/guava/README.md
+++ b/guava/README.md
@@ -16,3 +16,11 @@
- [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)
+- [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)
diff --git a/guava/pom.xml b/guava/pom.xml
index f65a9a2081..0edbb90efd 100644
--- a/guava/pom.xml
+++ b/guava/pom.xml
@@ -57,6 +57,32 @@
test
+
+
+
+ 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
+ ${org.slf4j.version}
+
+
+
org.assertj
assertj-core
@@ -112,6 +138,9 @@
3.6.0
2.19.1
+
+ 1.7.21
+ 1.1.7
\ No newline at end of file
diff --git a/guava/src/test/java/org/baeldung/guava/CustomEvent.java b/guava/src/main/java/org/baeldung/guava/CustomEvent.java
similarity index 99%
rename from guava/src/test/java/org/baeldung/guava/CustomEvent.java
rename to guava/src/main/java/org/baeldung/guava/CustomEvent.java
index 78348065b2..2d5c3382d4 100644
--- a/guava/src/test/java/org/baeldung/guava/CustomEvent.java
+++ b/guava/src/main/java/org/baeldung/guava/CustomEvent.java
@@ -1,6 +1,5 @@
package org.baeldung.guava;
-
public class CustomEvent {
private String action;
diff --git a/guava/src/main/java/org/baeldung/guava/EventListener.java b/guava/src/main/java/org/baeldung/guava/EventListener.java
new file mode 100644
index 0000000000..438fcade63
--- /dev/null
+++ b/guava/src/main/java/org/baeldung/guava/EventListener.java
@@ -0,0 +1,38 @@
+package org.baeldung.guava;
+
+import com.google.common.eventbus.DeadEvent;
+import com.google.common.eventbus.Subscribe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EventListener {
+
+ private static int eventsHandled;
+ private static final Logger LOG = LoggerFactory.getLogger(EventListener.class);
+
+ @Subscribe
+ public void stringEvent(String event) {
+ LOG.info("do event [" + event + "]");
+ eventsHandled++;
+ }
+
+ @Subscribe
+ public void someCustomEvent(CustomEvent customEvent) {
+ LOG.info("do event [" + customEvent.getAction() + "]");
+ eventsHandled++;
+ }
+
+ @Subscribe
+ public void handleDeadEvent(DeadEvent deadEvent) {
+ LOG.info("unhandled event [" + deadEvent.getEvent() + "]");
+ eventsHandled++;
+ }
+
+ public int getEventsHandled() {
+ return eventsHandled;
+ }
+
+ public void resetEventsHandled() {
+ eventsHandled = 0;
+ }
+}
diff --git a/guava/src/test/java/org/baeldung/guava/EventBusWrapper.java b/guava/src/test/java/org/baeldung/guava/EventBusWrapper.java
deleted file mode 100644
index eddaca0baf..0000000000
--- a/guava/src/test/java/org/baeldung/guava/EventBusWrapper.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.baeldung.guava;
-
-import com.google.common.eventbus.EventBus;
-
-class EventBusWrapper {
-
- private static EventBus eventBus = new EventBus();
-
- static void register(Object object){
- eventBus.register(object);
- }
-
- static void unregister(Object object){
- eventBus.unregister(object);
- }
-
- static void post(Object object){
- eventBus.post(object);
- }
-
-
-}
diff --git a/guava/src/test/java/org/baeldung/guava/EventListener.java b/guava/src/test/java/org/baeldung/guava/EventListener.java
deleted file mode 100644
index 17a3ac093e..0000000000
--- a/guava/src/test/java/org/baeldung/guava/EventListener.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.baeldung.guava;
-import com.google.common.eventbus.Subscribe;
-
-public class EventListener {
-
- private static int eventsHandled;
-
- /**
- * Handles events of type String *
- */
- @Subscribe
- public void stringEvent(String event){
- System.out.println("do event ["+event+"]");
- eventsHandled++;
- }
-
- /**
- * Handles events of type CustomEvent
- */
- @Subscribe
- public void someEvent(CustomEvent customEvent){
- System.out.println("do event ["+ customEvent.getAction()+"]");
- eventsHandled++;
- }
-
- public int getEventsHandled() {
- return eventsHandled;
- }
-
- public void resetEventsHandled(){
- eventsHandled = 0;
- }
-}
diff --git a/guava/src/test/java/org/baeldung/guava/GuavaCacheLoaderTest.java b/guava/src/test/java/org/baeldung/guava/GuavaCacheLoaderTest.java
new file mode 100644
index 0000000000..2aa2e6140b
--- /dev/null
+++ b/guava/src/test/java/org/baeldung/guava/GuavaCacheLoaderTest.java
@@ -0,0 +1,71 @@
+package org.baeldung.guava;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import static com.google.common.collect.Iterables.cycle;
+import static com.google.common.collect.Maps.newHashMap;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class GuavaCacheLoaderTest {
+ int callCount = 0;
+
+ @Test
+ public void givenAMap_whenAddingValues_thenCanTreatThemAsCache() {
+ Map cache = newHashMap();
+ cache.put("foo", "cachedValueForFoo");
+ cache.put("bar", "cachedValueForBar");
+
+ assertThat(cache.get("foo")).isEqualTo("cachedValueForFoo");
+ assertThat(cache.get("bar")).isEqualTo("cachedValueForBar");
+ }
+
+ @Test
+ public void givenCacheLoader_whenGettingItemTwice_shouldOnlyCallOnce() throws ExecutionException {
+
+ final LoadingCache loadingCache = CacheBuilder.newBuilder()
+ .build(new CacheLoader() {
+ @Override
+ public String load(final String s) throws Exception {
+ return slowMethod(s);
+ }
+ });
+
+ String value = loadingCache.get("key");
+ value = loadingCache.get("key");
+
+ assertThat(callCount).isEqualTo(1);
+ assertThat(value).isEqualTo("key");
+ }
+
+ @Test
+ public void givenCacheLoader_whenRefreshingItem_shouldCallAgain() throws ExecutionException {
+
+ final LoadingCache loadingCache = CacheBuilder.newBuilder()
+ .build(new CacheLoader() {
+ @Override
+ public String load(final String s) throws Exception {
+ return slowMethod(s);
+ }
+ });
+
+ String value = loadingCache.get("key");
+ loadingCache.refresh("key");
+
+ assertThat(callCount).isEqualTo(2);
+ assertThat(value).isEqualTo("key");
+ }
+
+ private String slowMethod(final String s) {
+ callCount++;
+ return s;
+ }
+}
diff --git a/guava/src/test/java/org/baeldung/guava/GuavaEventBusTest.java b/guava/src/test/java/org/baeldung/guava/GuavaEventBusTest.java
index bd966187ab..1390eb05aa 100644
--- a/guava/src/test/java/org/baeldung/guava/GuavaEventBusTest.java
+++ b/guava/src/test/java/org/baeldung/guava/GuavaEventBusTest.java
@@ -1,5 +1,6 @@
package org.baeldung.guava;
+import com.google.common.eventbus.EventBus;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -9,34 +10,46 @@ import static org.junit.Assert.*;
public class GuavaEventBusTest {
private EventListener listener;
+ private EventBus eventBus;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
+ eventBus = new EventBus();
listener = new EventListener();
- EventBusWrapper.register(listener);
+
+ eventBus.register(listener);
}
@After
- public void tearDown() throws Exception {
- EventBusWrapper.unregister(listener);
+ public void tearDown() {
+ eventBus.unregister(listener);
}
@Test
- public void givenStringEvent_whenEventHandled_thenSuccess() throws Exception {
+ public void givenStringEvent_whenEventHandled_thenSuccess() {
listener.resetEventsHandled();
- EventBusWrapper.post("String Event");
+ eventBus.post("String Event");
assertEquals(1, listener.getEventsHandled());
-
}
@Test
- public void givenCustomEvent_whenEventHandled_thenSuccess() throws Exception {
+ public void givenCustomEvent_whenEventHandled_thenSuccess() {
listener.resetEventsHandled();
CustomEvent customEvent = new CustomEvent("Custom Event");
- EventBusWrapper.post(customEvent);
+ eventBus.post(customEvent);
assertEquals(1, listener.getEventsHandled());
}
+
+ @Test
+ public void givenUnSubscribedEvent_whenEventHandledByDeadEvent_thenSuccess() throws InterruptedException {
+ listener.resetEventsHandled();
+
+ eventBus.post(12345);
+
+ assertEquals(1, listener.getEventsHandled());
+ }
+
}
diff --git a/guava/src/test/java/org/baeldung/guava/GuavaPreConditionsTest.java b/guava/src/test/java/org/baeldung/guava/GuavaPreConditionsTest.java
index 55e3c7db00..2d98418d48 100644
--- a/guava/src/test/java/org/baeldung/guava/GuavaPreConditionsTest.java
+++ b/guava/src/test/java/org/baeldung/guava/GuavaPreConditionsTest.java
@@ -3,7 +3,7 @@ package org.baeldung.guava;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.util.Arrays;
import org.junit.Test;
-import static com.google.common.base.Preconditions.*;
+import com.google.common.base.*;
public class GuavaPreConditionsTest {
@@ -11,10 +11,7 @@ public class GuavaPreConditionsTest {
public void whenCheckArgumentEvaluatesFalse_throwsException() {
int age = -18;
- assertThatThrownBy(() -> checkArgument(age > 0))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage(null)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkArgument(age > 0)).isInstanceOf(IllegalArgumentException.class).hasMessage(null).hasNoCause();
}
@Test
@@ -22,10 +19,7 @@ public class GuavaPreConditionsTest {
final int age = -18;
final String message = "Age can't be zero or less than zero";
- assertThatThrownBy(() -> checkArgument(age > 0, message))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage(message)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkArgument(age > 0, message)).isInstanceOf(IllegalArgumentException.class).hasMessage(message).hasNoCause();
}
@Test
@@ -33,19 +27,14 @@ public class GuavaPreConditionsTest {
final int age = -18;
final String message = "Age can't be zero or less than zero, you supplied %s.";
- assertThatThrownBy(() -> checkArgument(age > 0, message, age))
- .isInstanceOf(IllegalArgumentException.class)
- .hasMessage(message, age)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkArgument(age > 0, message, age)).isInstanceOf(IllegalArgumentException.class).hasMessage(message, age).hasNoCause();
}
@Test
public void givenArrayOfIntegers_whenCheckElementIndexEvaluatesFalse_throwsException() {
final int[] numbers = { 1, 2, 3, 4, 5 };
- assertThatThrownBy(() -> checkElementIndex(6, numbers.length - 1))
- .isInstanceOf(IndexOutOfBoundsException.class)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkElementIndex(6, numbers.length - 1)).isInstanceOf(IndexOutOfBoundsException.class).hasNoCause();
}
@Test
@@ -53,20 +42,7 @@ public class GuavaPreConditionsTest {
final int[] numbers = { 1, 2, 3, 4, 5 };
final String message = "Please check the bound of an array and retry";
- assertThatThrownBy(() -> checkElementIndex(6, numbers.length - 1, message))
- .isInstanceOf(IndexOutOfBoundsException.class)
- .hasMessageStartingWith(message)
- .hasNoCause();
- }
-
- @Test
- public void givenNullString_whenCheckNotNullCalled_throwsException() {
- final String nullObject = null;
-
- assertThatThrownBy(() -> checkNotNull(nullObject))
- .isInstanceOf(NullPointerException.class)
- .hasMessage(null)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkElementIndex(6, numbers.length - 1, message)).isInstanceOf(IndexOutOfBoundsException.class).hasMessageStartingWith(message).hasNoCause();
}
@Test
@@ -74,10 +50,7 @@ public class GuavaPreConditionsTest {
final String nullObject = null;
final String message = "Please check the Object supplied, its null!";
- assertThatThrownBy(() -> checkNotNull(nullObject, message))
- .isInstanceOf(NullPointerException.class)
- .hasMessage(message)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkNotNull(nullObject, message)).isInstanceOf(NullPointerException.class).hasMessage(message).hasNoCause();
}
@Test
@@ -85,19 +58,14 @@ public class GuavaPreConditionsTest {
final String nullObject = null;
final String message = "Please check the Object supplied, its %s!";
- assertThatThrownBy(() -> checkNotNull(nullObject, message, nullObject))
- .isInstanceOf(NullPointerException.class)
- .hasMessage(message, nullObject)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkNotNull(nullObject, message, new Object[] { null })).isInstanceOf(NullPointerException.class).hasMessage(message, nullObject).hasNoCause();
}
@Test
public void givenArrayOfIntegers_whenCheckPositionIndexEvaluatesFalse_throwsException() {
final int[] numbers = { 1, 2, 3, 4, 5 };
- assertThatThrownBy(() -> checkPositionIndex(6, numbers.length - 1))
- .isInstanceOf(IndexOutOfBoundsException.class)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkPositionIndex(6, numbers.length - 1)).isInstanceOf(IndexOutOfBoundsException.class).hasNoCause();
}
@Test
@@ -105,30 +73,14 @@ public class GuavaPreConditionsTest {
final int[] numbers = { 1, 2, 3, 4, 5 };
final String message = "Please check the bound of an array and retry";
- assertThatThrownBy(() -> checkPositionIndex(6, numbers.length - 1, message))
- .isInstanceOf(IndexOutOfBoundsException.class)
- .hasMessageStartingWith(message)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkPositionIndex(6, numbers.length - 1, message)).isInstanceOf(IndexOutOfBoundsException.class).hasMessageStartingWith(message).hasNoCause();
}
@Test
public void givenArrayOfIntegers_whenCheckPositionIndexesEvaluatesFalse_throwsException() {
final int[] numbers = { 1, 2, 3, 4, 5 };
- assertThatThrownBy(() -> checkPositionIndexes(6, 0, numbers.length - 1))
- .isInstanceOf(IndexOutOfBoundsException.class)
- .hasNoCause();
- }
-
- @Test
- public void givenValidStates_whenCheckStateEvaluatesFalse_throwsException() {
- final int[] validStates = { -1, 0, 1 };
- final int givenState = 10;
-
- assertThatThrownBy(() -> checkState(Arrays.binarySearch(validStates, givenState) > 0))
- .isInstanceOf(IllegalStateException.class)
- .hasMessage(null)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkPositionIndexes(6, 0, numbers.length - 1)).isInstanceOf(IndexOutOfBoundsException.class).hasNoCause();
}
@Test
@@ -137,10 +89,7 @@ public class GuavaPreConditionsTest {
final int givenState = 10;
final String message = "You have entered an invalid state";
- assertThatThrownBy(() -> checkState(Arrays.binarySearch(validStates, givenState) > 0, message))
- .isInstanceOf(IllegalStateException.class)
- .hasMessageStartingWith(message)
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkState(Arrays.binarySearch(validStates, givenState) > 0, message)).isInstanceOf(IllegalStateException.class).hasMessageStartingWith(message).hasNoCause();
}
@Test
@@ -149,9 +98,7 @@ public class GuavaPreConditionsTest {
final int givenState = 10;
final String message = "State can't be %s, It can be one of %s.";
- assertThatThrownBy(() -> checkState(Arrays.binarySearch(validStates, givenState) > 0, message, givenState, Arrays.toString(validStates)))
- .isInstanceOf(IllegalStateException.class)
- .hasMessage(message, givenState, Arrays.toString(validStates))
- .hasNoCause();
+ assertThatThrownBy(() -> Preconditions.checkState(Arrays.binarySearch(validStates, givenState) > 0, message, givenState, Arrays.toString(validStates))).isInstanceOf(IllegalStateException.class)
+ .hasMessage(message, givenState, Arrays.toString(validStates)).hasNoCause();
}
-}
+}
\ No newline at end of file
diff --git a/httpclient/README.md b/httpclient/README.md
index a848edfea6..2a98c2feac 100644
--- a/httpclient/README.md
+++ b/httpclient/README.md
@@ -19,3 +19,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Multipart Upload with HttpClient 4](http://www.baeldung.com/httpclient-multipart-upload)
- [HttpAsyncClient Tutorial](http://www.baeldung.com/httpasyncclient-tutorial)
- [HttpClient 4 Tutorial](http://www.baeldung.com/httpclient-guide)
+- [Advanced HttpClient Configuration](http://www.baeldung.com/httpclient-advanced-config)
diff --git a/httpclient/pom.xml b/httpclient/pom.xml
index be0daae995..eec705b224 100644
--- a/httpclient/pom.xml
+++ b/httpclient/pom.xml
@@ -1,4 +1,5 @@
-
+
4.0.0
com.baeldung
httpclient
@@ -113,6 +114,13 @@
${mockito.version}
test
+
+ com.github.tomakehurst
+ wiremock
+ ${wiremock.version}
+ test
+
+
@@ -145,7 +153,7 @@
**/*LiveTest.java
-
+
@@ -202,6 +210,7 @@
1.3
4.12
1.10.19
+ 2.5.1
4.4.5
4.5.2
diff --git a/httpclient/src/test/java/org/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfiguration.java b/httpclient/src/test/java/org/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfiguration.java
new file mode 100644
index 0000000000..9b5cb3f293
--- /dev/null
+++ b/httpclient/src/test/java/org/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfiguration.java
@@ -0,0 +1,154 @@
+package org.baeldung.httpclient.advancedconfig;
+
+
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static org.junit.Assert.assertEquals;
+
+public class HttpClientAdvancedConfiguration {
+
+ @Rule
+ public WireMockRule serviceMock = new WireMockRule(8089);
+
+ @Rule
+ public WireMockRule proxyMock = new WireMockRule(8090);
+
+ @Test
+ public void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException {
+ //given
+ String userAgent = "BaeldungAgent/1.0";
+ serviceMock.stubFor(get(urlEqualTo("/detail"))
+ .withHeader("User-Agent", equalTo(userAgent))
+ .willReturn(aResponse()
+ .withStatus(200)));
+
+ HttpClient httpClient = HttpClients.createDefault();
+ HttpGet httpGet = new HttpGet("http://localhost:8089/detail");
+ httpGet.setHeader(HttpHeaders.USER_AGENT, userAgent);
+
+ //when
+ HttpResponse response = httpClient.execute(httpGet);
+
+ //then
+ assertEquals(response.getStatusLine().getStatusCode(), 200);
+ }
+
+ @Test
+ public void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException {
+ //given
+ String xmlBody = "1 ";
+ serviceMock.stubFor(post(urlEqualTo("/person"))
+ .withHeader("Content-Type", equalTo("application/xml"))
+ .withRequestBody(equalTo(xmlBody))
+ .willReturn(aResponse()
+ .withStatus(200)));
+
+ HttpClient httpClient = HttpClients.createDefault();
+ HttpPost httpPost = new HttpPost("http://localhost:8089/person");
+ httpPost.setHeader("Content-Type", "application/xml");
+ StringEntity xmlEntity = new StringEntity(xmlBody);
+ httpPost.setEntity(xmlEntity);
+
+ //when
+ HttpResponse response = httpClient.execute(httpPost);
+
+ //then
+ assertEquals(response.getStatusLine().getStatusCode(), 200);
+
+ }
+
+ @Test
+ public void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException {
+ //given
+ proxyMock.stubFor(get(urlMatching(".*"))
+ .willReturn(aResponse().proxiedFrom("http://localhost:8089/")));
+
+ serviceMock.stubFor(get(urlEqualTo("/private"))
+ .willReturn(aResponse().withStatus(200)));
+
+
+ HttpHost proxy = new HttpHost("localhost", 8090);
+ DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
+ HttpClient httpclient = HttpClients.custom()
+ .setRoutePlanner(routePlanner)
+ .build();
+
+ //when
+ final HttpGet httpGet = new HttpGet("http://localhost:8089/private");
+ HttpResponse response = httpclient.execute(httpGet);
+
+ //then
+ assertEquals(response.getStatusLine().getStatusCode(), 200);
+ proxyMock.verify(getRequestedFor(urlEqualTo("/private")));
+ serviceMock.verify(getRequestedFor(urlEqualTo("/private")));
+ }
+
+ @Test
+ public void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException {
+ //given
+ proxyMock.stubFor(get(urlMatching("/private"))
+ .willReturn(aResponse().proxiedFrom("http://localhost:8089/")));
+ serviceMock.stubFor(get(urlEqualTo("/private"))
+ .willReturn(aResponse().withStatus(200)));
+
+
+ HttpHost proxy = new HttpHost("localhost", 8090);
+ DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
+
+ // Client credentials
+ CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(new AuthScope(proxy),
+ new UsernamePasswordCredentials("username_admin", "secret_password"));
+
+
+ // Create AuthCache instance
+ AuthCache authCache = new BasicAuthCache();
+
+ // Generate BASIC scheme object and add it to the local auth cache
+ BasicScheme basicAuth = new BasicScheme();
+ authCache.put(proxy, basicAuth);
+ HttpClientContext context = HttpClientContext.create();
+ context.setCredentialsProvider(credentialsProvider);
+ context.setAuthCache(authCache);
+
+
+ HttpClient httpclient = HttpClients.custom()
+ .setRoutePlanner(routePlanner)
+ .setDefaultCredentialsProvider(credentialsProvider)
+ .build();
+
+
+ //when
+ final HttpGet httpGet = new HttpGet("http://localhost:8089/private");
+ HttpResponse response = httpclient.execute(httpGet, context);
+
+ //then
+ assertEquals(response.getStatusLine().getStatusCode(), 200);
+ proxyMock.verify(getRequestedFor(urlEqualTo("/private")).withHeader("Authorization", containing("Basic")));
+ serviceMock.verify(getRequestedFor(urlEqualTo("/private")));
+ }
+
+
+}
diff --git a/hystrix/pom.xml b/hystrix/pom.xml
index 5e050d726e..ba1a596631 100644
--- a/hystrix/pom.xml
+++ b/hystrix/pom.xml
@@ -11,7 +11,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/jackson/README.md b/jackson/README.md
index 67a03589a8..d9faa377f1 100644
--- a/jackson/README.md
+++ b/jackson/README.md
@@ -25,3 +25,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [More Jackson Annotations](http://www.baeldung.com/jackson-advanced-annotations)
- [Inheritance with Jackson](http://www.baeldung.com/jackson-inheritance)
- [Guide to @JsonFormat in Jackson](http://www.baeldung.com/jackson-jsonformat)
+- [A Guide to Optional with Jackson](http://www.baeldung.com/jackson-optional)
diff --git a/jackson/pom.xml b/jackson/pom.xml
index 53fb82c61e..881ba8e24c 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -67,6 +67,12 @@
${jackson.version}
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
+ ${jackson.version}
+
+
joda-time
joda-time
@@ -128,8 +134,8 @@
${mockito.version}
test
-
-
+
+
org.slf4j
@@ -152,7 +158,7 @@
org.slf4j
log4j-over-slf4j
${org.slf4j.version}
-
+
@@ -189,7 +195,7 @@
- 2.8.5
+ 2.8.6
1.7.21
@@ -198,7 +204,7 @@
19.0
3.5
- 2.5
+ 2.5
2.9.6
2.8.0
4.1
diff --git a/jackson/src/main/java/com/baeldung/jackson/entities/ActorJackson.java b/jackson/src/main/java/com/baeldung/jackson/entities/ActorJackson.java
index f6a8b0cf61..76f87d80b3 100644
--- a/jackson/src/main/java/com/baeldung/jackson/entities/ActorJackson.java
+++ b/jackson/src/main/java/com/baeldung/jackson/entities/ActorJackson.java
@@ -4,6 +4,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
+import java.util.Locale;
import java.util.TimeZone;
public class ActorJackson {
@@ -53,7 +54,7 @@ public class ActorJackson {
}
private String formatDateOfBirth() {
- final DateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy");
+ final DateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
return formatter.format(dateOfBirth);
}
diff --git a/jackson/src/main/java/com/baeldung/jackson/miscellaneous/mixin/Book.java b/jackson/src/main/java/com/baeldung/jackson/miscellaneous/mixin/Book.java
new file mode 100644
index 0000000000..fb961efe85
--- /dev/null
+++ b/jackson/src/main/java/com/baeldung/jackson/miscellaneous/mixin/Book.java
@@ -0,0 +1,25 @@
+package com.baeldung.jackson.miscellaneous.mixin;
+
+import java.util.Optional;
+
+public class Book {
+
+ private String title;
+ private Optional subTitle;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public Optional getSubTitle() {
+ return subTitle;
+ }
+
+ public void setSubTitle(Optional subTitle) {
+ this.subTitle = subTitle;
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/deserialization/JacksonDeserializeTest.java b/jackson/src/test/java/com/baeldung/jackson/deserialization/JacksonDeserializeTest.java
index 7e91df5332..cb3bccb879 100644
--- a/jackson/src/test/java/com/baeldung/jackson/deserialization/JacksonDeserializeTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/deserialization/JacksonDeserializeTest.java
@@ -3,12 +3,10 @@ package com.baeldung.jackson.deserialization;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-
import com.baeldung.jackson.entities.Movie;
-import org.junit.Assert;
import org.junit.Test;
-
import com.fasterxml.jackson.databind.ObjectMapper;
+import static org.junit.Assert.assertEquals;
public class JacksonDeserializeTest {
@@ -20,7 +18,7 @@ public class JacksonDeserializeTest {
final Movie movie = mapper.readValue(jsonInput, Movie.class);
final String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorJackson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]";
- Assert.assertEquals(movie.toString(), expectedOutput);
+ assertEquals(expectedOutput, movie.toString());
}
@Test
@@ -35,7 +33,7 @@ public class JacksonDeserializeTest {
final Movie movie = mapper.readValue(jsonInput, Movie.class);
final String expectedOutput = "Movie [imdbId=tt0472043, director=Mel Gibson, actors=[ActorJackson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]";
- Assert.assertEquals(movie.toString(), expectedOutput);
+ assertEquals(expectedOutput, movie.toString());
}
}
diff --git a/jackson/src/test/java/com/baeldung/jackson/miscellaneous/mixin/OptionalTypeTest.java b/jackson/src/test/java/com/baeldung/jackson/miscellaneous/mixin/OptionalTypeTest.java
new file mode 100644
index 0000000000..c6d51cd57f
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/miscellaneous/mixin/OptionalTypeTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.jackson.miscellaneous.mixin;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import static io.restassured.path.json.JsonPath.from;
+import java.io.IOException;
+import java.util.Optional;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class OptionalTypeTest {
+
+ ObjectMapper mapper = new ObjectMapper().registerModule(new Jdk8Module());
+
+ @Test
+ public void givenPresentOptional_whenSerializing_thenValueInJson() throws JsonProcessingException {
+
+ String subTitle = "The Parish Boy's Progress";
+ Book book = new Book();
+ book.setTitle("Oliver Twist");
+ book.setSubTitle(Optional.of(subTitle));
+
+ String result = mapper.writeValueAsString(book);
+
+ assertThat(from(result).getString("subTitle")).isEqualTo(subTitle);
+ }
+
+ @Test
+ public void givenEmptyOptional_whenSerializing_thenNullValue() throws JsonProcessingException {
+
+ Book book = new Book();
+ book.setTitle("Oliver Twist");
+ book.setSubTitle(Optional.empty());
+
+ String result = mapper.writeValueAsString(book);
+
+ assertThat(from(result).getString("subTitle")).isNull();
+ }
+
+ @Test
+ public void givenField_whenDeserializingIntoOptional_thenIsPresentWithValue() throws IOException {
+
+ String subTitle = "The Parish Boy's Progress";
+ String book = "{ \"title\": \"Oliver Twist\", \"subTitle\": \"" + subTitle + "\" }";
+
+ Book result = mapper.readValue(book, Book.class);
+
+ assertThat(result.getSubTitle()).isEqualTo(Optional.of(subTitle));
+ }
+
+ @Test
+ public void givenNullField_whenDeserializingIntoOptional_thenIsEmpty() throws IOException {
+
+ String book = "{ \"title\": \"Oliver Twist\", \"subTitle\": null }";
+
+ Book result = mapper.readValue(book, Book.class);
+
+ assertThat(result.getSubTitle()).isEmpty();
+ }
+}
diff --git a/java-mongodb/README.md b/java-mongodb/README.md
new file mode 100644
index 0000000000..01245ac6cf
--- /dev/null
+++ b/java-mongodb/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [A Guide to MongoDB with Java](http://www.baeldung.com/java-mongodb)
diff --git a/javaslang/README.md b/javaslang/README.md
index 334ac02f60..e451883516 100644
--- a/javaslang/README.md
+++ b/javaslang/README.md
@@ -1,2 +1,4 @@
### Relevant Articles:
- [Introduction to Javaslang](http://www.baeldung.com/javaslang)
+- [Guide to Try in Javaslang](http://www.baeldung.com/javaslang-try)
+- [Guide to Pattern Matching in Javaslang](http://www.baeldung.com/javaslang-pattern-matching)
diff --git a/jee7/README.md b/jee7/README.md
index 44ca9c2f6e..bc242c3340 100644
--- a/jee7/README.md
+++ b/jee7/README.md
@@ -1,2 +1,3 @@
### Relevant Articles:
- [Scheduling in Java EE](http://www.baeldung.com/scheduling-in-java-enterprise-edition)
+- [JSON Processing in Java EE 7](http://www.baeldung.com/jee7-json)
diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java b/jee7/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java
new file mode 100644
index 0000000000..e3f1667595
--- /dev/null
+++ b/jee7/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java
@@ -0,0 +1,57 @@
+package com.baeldung.javaeeannotations;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.HttpConstraint;
+import javax.servlet.annotation.HttpMethodConstraint;
+import javax.servlet.annotation.ServletSecurity;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@WebServlet(
+ name = "BankAccountServlet",
+ description = "Represents a Bank Account and it's transactions",
+ urlPatterns = {"/account", "/bankAccount" },
+ initParams = { @WebInitParam(name = "type", value = "savings") }
+ )
+@ServletSecurity(
+ value = @HttpConstraint(rolesAllowed = {"admin"}),
+ httpMethodConstraints = {@HttpMethodConstraint(value = "POST", rolesAllowed = {"admin"})}
+ )
+public class AccountServlet extends javax.servlet.http.HttpServlet {
+
+ String accountType = null;
+
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+ accountType = config.getInitParameter("type");
+ }
+
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ PrintWriter writer = response.getWriter();
+ writer.println("Hello, I am an AccountServlet!");
+ writer.flush();
+ }
+
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ double accountBalance = 1000d;
+ double interestRate = Double.parseDouble(request.getAttribute("interest").toString());
+
+ String paramDepositAmt = request.getParameter("dep");
+ double depositAmt = Double.parseDouble(paramDepositAmt);
+
+ accountBalance = accountBalance + depositAmt;
+
+ PrintWriter writer = response.getWriter();
+ writer.println(" Balance of " + accountType + " account is: " +
+ accountBalance + " This account bares an interest rate of " + interestRate +
+ " % ");
+ writer.flush();
+
+ }
+}
diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java b/jee7/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java
new file mode 100644
index 0000000000..6b43dd8a84
--- /dev/null
+++ b/jee7/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java
@@ -0,0 +1,17 @@
+package com.baeldung.javaeeannotations;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+@WebListener
+public class BankAppServletContextListener implements ServletContextListener {
+
+ public void contextInitialized(ServletContextEvent sce) {
+ sce.getServletContext().setAttribute("ATTR_DEFAULT_LANGUAGE", "english");
+ }
+
+ public void contextDestroyed(ServletContextEvent sce) {
+ System.out.println("CONTEXT DESTROYED");
+ }
+}
diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/LoggingFilter.java b/jee7/src/main/java/com/baeldung/javaeeannotations/LoggingFilter.java
new file mode 100644
index 0000000000..97de5ec0de
--- /dev/null
+++ b/jee7/src/main/java/com/baeldung/javaeeannotations/LoggingFilter.java
@@ -0,0 +1,36 @@
+package com.baeldung.javaeeannotations;
+
+import java.io.IOException;
+
+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.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@WebFilter(
+ urlPatterns = "/bankAccount/*",
+ filterName = "LoggingFilter",
+ description = "Filter all account transaction URLs"
+ )
+public class LoggingFilter implements javax.servlet.Filter {
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ HttpServletRequest req = (HttpServletRequest) request;
+ HttpServletResponse res = (HttpServletResponse) response;
+
+ res.sendRedirect(req.getContextPath() + "/login.jsp");
+ chain.doFilter(request, response);
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+}
diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java b/jee7/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java
new file mode 100644
index 0000000000..8a6c709b81
--- /dev/null
+++ b/jee7/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java
@@ -0,0 +1,29 @@
+package com.baeldung.javaeeannotations;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.MultipartConfig;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.Part;
+
+@WebServlet(urlPatterns = { "/uploadCustDocs" })
+@MultipartConfig(
+ fileSizeThreshold = 1024 * 1024 * 20,
+ maxFileSize = 1024 * 1024 * 20,
+ maxRequestSize = 1024 * 1024 * 25,
+ location = "D:/custDocs"
+ )
+public class UploadCustomerDocumentsServlet extends HttpServlet {
+
+ protected void doPost(
+ HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ for (Part part : request.getParts()) {
+ part.write("myFile");
+ }
+ }
+
+}
diff --git a/jee7/src/main/webapp/WEB-INF/web.xml b/jee7/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..0a3d84d2d4
--- /dev/null
+++ b/jee7/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,11 @@
+
+
+
+ BASIC
+ default
+
+
+
\ No newline at end of file
diff --git a/jee7/src/main/webapp/index.jsp b/jee7/src/main/webapp/index.jsp
new file mode 100644
index 0000000000..0c389ef5b1
--- /dev/null
+++ b/jee7/src/main/webapp/index.jsp
@@ -0,0 +1,16 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+My Account
+
+
+
+
+
\ No newline at end of file
diff --git a/jee7/src/main/webapp/login.jsp b/jee7/src/main/webapp/login.jsp
new file mode 100644
index 0000000000..885df0c3d9
--- /dev/null
+++ b/jee7/src/main/webapp/login.jsp
@@ -0,0 +1,12 @@
+<%@ 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/jee7/src/main/webapp/upload.jsp b/jee7/src/main/webapp/upload.jsp
new file mode 100644
index 0000000000..020483b99f
--- /dev/null
+++ b/jee7/src/main/webapp/upload.jsp
@@ -0,0 +1,16 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+Insert title here
+
+
+
+
+
\ No newline at end of file
diff --git a/jjwt/pom.xml b/jjwt/pom.xml
index c1332fa2d7..982b24987b 100644
--- a/jjwt/pom.xml
+++ b/jjwt/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/jooq/pom.xml b/jooq/pom.xml
new file mode 100644
index 0000000000..ef287d0292
--- /dev/null
+++ b/jooq/pom.xml
@@ -0,0 +1,46 @@
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+ jooq
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+ org.jooq
+ jool
+ ${jool.version}
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+ 0.9.12
+ 4.12
+
+
+
+
\ No newline at end of file
diff --git a/jooq/src/test/java/com/baeldung/JOOLTest.java b/jooq/src/test/java/com/baeldung/JOOLTest.java
new file mode 100644
index 0000000000..13bf1a3ec3
--- /dev/null
+++ b/jooq/src/test/java/com/baeldung/JOOLTest.java
@@ -0,0 +1,243 @@
+package com.baeldung;
+
+
+import junit.framework.Assert;
+import org.jooq.lambda.Seq;
+import org.jooq.lambda.Unchecked;
+import org.jooq.lambda.function.Function1;
+import org.jooq.lambda.function.Function2;
+import org.jooq.lambda.tuple.Tuple;
+import org.jooq.lambda.tuple.Tuple2;
+import org.jooq.lambda.tuple.Tuple3;
+import org.jooq.lambda.tuple.Tuple4;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
+import static org.jooq.lambda.tuple.Tuple.tuple;
+
+public class JOOLTest {
+ @Test
+ public void givenSeq_whenCheckContains_shouldReturnTrue() {
+ List concat = Seq.of(1, 2, 3).concat(Seq.of(4, 5, 6)).toList();
+
+ assertEquals(concat, Arrays.asList(1, 2, 3, 4, 5, 6));
+
+
+ assertTrue(Seq.of(1, 2, 3, 4).contains(2));
+
+
+ assertTrue(Seq.of(1, 2, 3, 4).containsAll(2, 3));
+
+
+ assertTrue(Seq.of(1, 2, 3, 4).containsAny(2, 5));
+ }
+
+ @Test
+ public void givenStreams_whenJoin_shouldHaveElementsFromTwoStreams() {
+ //given
+ Stream left = Stream.of(1, 2, 4);
+ Stream right = Stream.of(1, 2, 3);
+
+ //when
+ List rightCollected = right.collect(Collectors.toList());
+ List collect = left.filter(rightCollected::contains).collect(Collectors.toList());
+
+ //then
+ assertEquals(collect, Arrays.asList(1, 2));
+ }
+
+ @Test
+ public void givenSeq_whenJoin_shouldHaveElementsFromBothSeq() {
+ assertEquals(
+ Seq.of(1, 2, 4).innerJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
+ Arrays.asList(tuple(1, 1), tuple(2, 2))
+ );
+
+
+ assertEquals(
+ Seq.of(1, 2, 4).leftOuterJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
+ Arrays.asList(tuple(1, 1), tuple(2, 2), tuple(4, null))
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 4).rightOuterJoin(Seq.of(1, 2, 3), (a, b) -> a == b).toList(),
+ Arrays.asList(tuple(1, 1), tuple(2, 2), tuple(null, 3))
+ );
+
+ assertEquals(
+ Seq.of(1, 2).crossJoin(Seq.of("A", "B")).toList(),
+ Arrays.asList(tuple(1, "A"), tuple(1, "B"), tuple(2, "A"), tuple(2, "B"))
+ );
+ }
+
+ @Test
+ public void givenSeq_whenManipulateSeq_seqShouldHaveNewElementsInIt() {
+ assertEquals(
+ Seq.of(1, 2, 3).cycle().limit(9).toList(),
+ Arrays.asList(1, 2, 3, 1, 2, 3, 1, 2, 3)
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3).duplicate().map((first, second) -> tuple(first.toList(), second.toList())),
+ tuple(Arrays.asList(1, 2, 3), Arrays.asList(1, 2, 3))
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4).intersperse(0).toList(),
+ Arrays.asList(1, 0, 2, 0, 3, 0, 4)
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4, 5).shuffle().toList().size(),
+ 5
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4).partition(i -> i > 2).map((first, second) -> tuple(first.toList(), second.toList())),
+ tuple(Arrays.asList(3, 4), Arrays.asList(1, 2))
+
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4).reverse().toList(),
+ Arrays.asList(4, 3, 2, 1)
+ );
+ }
+
+ @Test
+ public void givenSeq_whenGroupByAndFold_shouldReturnProperSeq() {
+
+ Map> expectedAfterGroupBy = new HashMap<>();
+ expectedAfterGroupBy.put(1, Arrays.asList(1, 3));
+ expectedAfterGroupBy.put(0, Arrays.asList(2, 4));
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4).groupBy(i -> i % 2),
+ expectedAfterGroupBy
+ );
+
+
+ assertEquals(
+ Seq.of("a", "b", "c").foldLeft("!", (u, t) -> u + t),
+ "!abc"
+ );
+
+
+ assertEquals(
+ Seq.of("a", "b", "c").foldRight("!", (t, u) -> t + u),
+ "abc!"
+ );
+ }
+
+ @Test
+ public void givenSeq_whenUsingSeqWhile_shouldBehaveAsWhileLoop() {
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4, 5).skipWhile(i -> i < 3).toList(),
+ Arrays.asList(3, 4, 5)
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3, 4, 5).skipUntil(i -> i == 3).toList(),
+ Arrays.asList(3, 4, 5)
+ );
+ }
+
+ @Test
+ public void givenSeq_whenZip_shouldHaveZippedSeq() {
+
+ assertEquals(
+ Seq.of(1, 2, 3).zip(Seq.of("a", "b", "c")).toList(),
+ Arrays.asList(tuple(1, "a"), tuple(2, "b"), tuple(3, "c"))
+ );
+
+ assertEquals(
+ Seq.of(1, 2, 3).zip(Seq.of("a", "b", "c"), (x, y) -> x + ":" + y).toList(),
+ Arrays.asList("1:a", "2:b", "3:c")
+ );
+
+
+ assertEquals(
+ Seq.of("a", "b", "c").zipWithIndex().toList(),
+ Arrays.asList(tuple("a", 0L), tuple("b", 1L), tuple("c", 2L))
+ );
+ }
+
+
+ public Integer methodThatThrowsChecked(String arg) throws Exception {
+ return arg.length();
+ }
+
+ @Test
+ public void givenOperationThatThrowsCheckedException_whenExecuteAndNeedToWrapCheckedIntoUnchecked_shouldPass() {
+ //when
+ List collect = Stream.of("a", "b", "c").map(elem -> {
+ try {
+ return methodThatThrowsChecked(elem);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }).collect(Collectors.toList());
+
+ //then
+ assertEquals(
+ collect,
+ Arrays.asList(1, 1, 1)
+ );
+ }
+
+
+ @Test
+ public void givenOperationThatThrowsCheckedException_whenExecuteUsingUncheckedFuction_shouldPass() {
+ //when
+ List collect = Stream.of("a", "b", "c")
+ .map(Unchecked.function(elem -> methodThatThrowsChecked(elem)))
+ .collect(Collectors.toList());
+
+ //then
+ assertEquals(
+ collect,
+ Arrays.asList(1, 1, 1)
+ );
+ }
+
+ @Test
+ public void givenFunction_whenAppliedPartially_shouldAddNumberToPartialArgument() {
+ //given
+ Function2 addTwoNumbers = (v1, v2) -> v1 + v2;
+ addTwoNumbers.toBiFunction();
+ Function1 addToTwo = addTwoNumbers.applyPartially(2);
+
+ //when
+ Integer result = addToTwo.apply(5);
+
+ //then
+ assertEquals(result, (Integer) 7);
+ }
+
+ @Test
+ public void givenSeqOfTuples_whenTransformToLowerNumberOfTuples_shouldHaveProperResult() {
+ //given
+ Seq> personDetails = Seq.of(tuple("michael", "similar", 49), tuple("jodie", "variable", 43));
+ Tuple2 tuple = tuple("winter", "summer");
+
+ //when
+ List> result = personDetails.map(t -> t.limit2().concat(tuple)).toList();
+
+ //then
+ assertEquals(
+ result,
+ Arrays.asList(tuple("michael", "similar", "winter", "summer"), tuple("jodie", "variable", "winter", "summer"))
+ );
+ }
+
+}
diff --git a/kotlin/README.md b/kotlin/README.md
new file mode 100644
index 0000000000..6447a26f5c
--- /dev/null
+++ b/kotlin/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Introduction to the Kotlin Language](http://www.baeldung.com/kotlin)
diff --git a/libraries/pom.xml b/libraries/pom.xml
new file mode 100644
index 0000000000..ee93ee934f
--- /dev/null
+++ b/libraries/pom.xml
@@ -0,0 +1,48 @@
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+ libraries
+ libraries
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+
+ cglib
+ cglib
+ ${cglib.version}
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+ 3.2.4
+ 4.12
+
+
+
+
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/cglib/mixin/Class1.java b/libraries/src/main/java/com/baeldung/cglib/mixin/Class1.java
new file mode 100644
index 0000000000..fa0cba5b78
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/cglib/mixin/Class1.java
@@ -0,0 +1,8 @@
+package com.baeldung.cglib.mixin;
+
+public class Class1 implements Interface1 {
+ @Override
+ public String first() {
+ return "first behaviour";
+ }
+}
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/cglib/mixin/Class2.java b/libraries/src/main/java/com/baeldung/cglib/mixin/Class2.java
new file mode 100644
index 0000000000..0db0620ab8
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/cglib/mixin/Class2.java
@@ -0,0 +1,8 @@
+package com.baeldung.cglib.mixin;
+
+public class Class2 implements Interface2 {
+ @Override
+ public String second() {
+ return "second behaviour";
+ }
+}
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/cglib/mixin/Interface1.java b/libraries/src/main/java/com/baeldung/cglib/mixin/Interface1.java
new file mode 100644
index 0000000000..56ad679cad
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/cglib/mixin/Interface1.java
@@ -0,0 +1,5 @@
+package com.baeldung.cglib.mixin;
+
+public interface Interface1 {
+ String first();
+}
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/cglib/mixin/Interface2.java b/libraries/src/main/java/com/baeldung/cglib/mixin/Interface2.java
new file mode 100644
index 0000000000..0dfb8737ab
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/cglib/mixin/Interface2.java
@@ -0,0 +1,5 @@
+package com.baeldung.cglib.mixin;
+
+public interface Interface2 {
+ String second();
+}
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/cglib/mixin/MixinInterface.java b/libraries/src/main/java/com/baeldung/cglib/mixin/MixinInterface.java
new file mode 100644
index 0000000000..e7ed362a25
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/cglib/mixin/MixinInterface.java
@@ -0,0 +1,4 @@
+package com.baeldung.cglib.mixin;
+
+public interface MixinInterface extends Interface1, Interface2 {
+}
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/cglib/proxy/PersonService.java b/libraries/src/main/java/com/baeldung/cglib/proxy/PersonService.java
new file mode 100644
index 0000000000..9085e6c49a
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/cglib/proxy/PersonService.java
@@ -0,0 +1,11 @@
+package com.baeldung.cglib.proxy;
+
+public class PersonService {
+ public String sayHello(String name) {
+ return "Hello " + name;
+ }
+
+ public Integer lengthOfName(String name) {
+ return name.length();
+ }
+}
\ No newline at end of file
diff --git a/libraries/src/test/java/com/baeldung/cglib/proxy/BeanGeneratorTest.java b/libraries/src/test/java/com/baeldung/cglib/proxy/BeanGeneratorTest.java
new file mode 100644
index 0000000000..1e49536065
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/cglib/proxy/BeanGeneratorTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.cglib.proxy;
+
+
+import net.sf.cglib.beans.BeanGenerator;
+import org.junit.Test;
+
+import java.lang.reflect.Method;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class BeanGeneratorTest {
+
+ @Test
+ public void givenBeanCreator_whenAddProperty_thenClassShouldHaveFieldValue() throws Exception {
+ //given
+ BeanGenerator beanGenerator = new BeanGenerator();
+
+ //when
+ beanGenerator.addProperty("name", String.class);
+ Object myBean = beanGenerator.create();
+ Method setter = myBean
+ .getClass()
+ .getMethod("setName", String.class);
+ setter.invoke(myBean, "some string value set by a cglib");
+
+ //then
+ Method getter = myBean
+ .getClass()
+ .getMethod("getName");
+ assertEquals("some string value set by a cglib", getter.invoke(myBean));
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/cglib/proxy/MixinTest.java b/libraries/src/test/java/com/baeldung/cglib/proxy/MixinTest.java
new file mode 100644
index 0000000000..db8453e6c1
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/cglib/proxy/MixinTest.java
@@ -0,0 +1,24 @@
+package com.baeldung.cglib.proxy;
+
+import com.baeldung.cglib.mixin.*;
+import net.sf.cglib.proxy.Mixin;
+import org.junit.Test;
+
+import static junit.framework.TestCase.assertEquals;
+
+public class MixinTest {
+
+ @Test
+ public void givenTwoClasses_whenMixedIntoOne_thenMixinShouldHaveMethodsFromBothClasses() throws Exception {
+ //when
+ Mixin mixin = Mixin.create(
+ new Class[]{Interface1.class, Interface2.class, MixinInterface.class},
+ new Object[]{new Class1(), new Class2()}
+ );
+ MixinInterface mixinDelegate = (MixinInterface) mixin;
+
+ //then
+ assertEquals("first behaviour", mixinDelegate.first());
+ assertEquals("second behaviour", mixinDelegate.second());
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/cglib/proxy/ProxyTest.java b/libraries/src/test/java/com/baeldung/cglib/proxy/ProxyTest.java
new file mode 100644
index 0000000000..195c4b903d
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/cglib/proxy/ProxyTest.java
@@ -0,0 +1,60 @@
+package com.baeldung.cglib.proxy;
+
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.FixedValue;
+import net.sf.cglib.proxy.MethodInterceptor;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ProxyTest {
+ @Test
+ public void givenPersonService_whenSayHello_thenReturnResult() {
+ //given
+ PersonService personService = new PersonService();
+
+ //when
+ String res = personService.sayHello("Tom");
+
+ //then
+ assertEquals(res, "Hello Tom");
+ }
+
+ @Test
+ public void givenEnhancerProxy_whenExtendPersonService_thenInterceptMethod() throws Exception {
+ //given
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(PersonService.class);
+ enhancer.setCallback((FixedValue) () -> "Hello Tom!");
+ PersonService proxy = (PersonService) enhancer.create();
+
+ //when
+ String res = proxy.sayHello(null);
+
+ //then
+ assertEquals("Hello Tom!", res);
+ }
+
+ @Test
+ public void givenEnhancer_whenExecuteMethodOnProxy_thenInterceptOnlyStringReturnTypeMethod() throws Exception {
+ //given
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(PersonService.class);
+ enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
+ if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
+ return "Hello Tom!";
+ } else {
+ return proxy.invokeSuper(obj, args);
+ }
+ });
+
+ //when
+ PersonService proxy = (PersonService) enhancer.create();
+
+ //then
+ assertEquals("Hello Tom!", proxy.sayHello(null));
+ int lengthOfName = proxy.lengthOfName("Mary");
+ assertEquals(4, lengthOfName);
+ }
+
+}
\ No newline at end of file
diff --git a/log-mdc/pom.xml b/log-mdc/pom.xml
index 28c8bb820e..931e68a178 100644
--- a/log-mdc/pom.xml
+++ b/log-mdc/pom.xml
@@ -2,9 +2,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
- logmdc
+ log-mdc
0.0.1-SNAPSHOT
- logmdc
+ log-mdc
war
tutorial on logging with MDC and NDC
diff --git a/log-mdc/src/main/java/com/baeldung/mdc/TransactionFactory.java b/log-mdc/src/main/java/com/baeldung/mdc/TransactionFactory.java
index ec1887eea6..0904e4603f 100644
--- a/log-mdc/src/main/java/com/baeldung/mdc/TransactionFactory.java
+++ b/log-mdc/src/main/java/com/baeldung/mdc/TransactionFactory.java
@@ -7,15 +7,15 @@ import java.util.UUID;
public class TransactionFactory {
- private static final String[] NAMES = {"John", "Susan", "Marc", "Samantha"};
- private static long nextId = 1;
-
- public Transfer newInstance() {
- String transactionId = String.valueOf( nextId++ );
- String owner = NAMES[ (int) floor(random()*NAMES.length) ];
- long amount = (long) (random()*1500 + 500);
- Transfer tx = new Transfer(transactionId, owner, amount);
- return tx;
- }
-
+ private static final String[] NAMES = { "John", "Susan", "Marc", "Samantha" };
+ private static long nextId = 1;
+
+ public Transfer newInstance() {
+ String transactionId = String.valueOf(nextId++);
+ String owner = NAMES[(int) floor(random() * NAMES.length)];
+ long amount = (long) (random() * 1500 + 500);
+ Transfer tx = new Transfer(transactionId, owner, amount);
+ return tx;
+ }
+
}
diff --git a/log-mdc/src/main/java/com/baeldung/mdc/TransferDemo.java b/log-mdc/src/main/java/com/baeldung/mdc/TransferDemo.java
index daf256007c..259e9a8c5c 100644
--- a/log-mdc/src/main/java/com/baeldung/mdc/TransferDemo.java
+++ b/log-mdc/src/main/java/com/baeldung/mdc/TransferDemo.java
@@ -18,11 +18,11 @@ public class TransferDemo {
for (int i = 0; i < 10; i++) {
Transfer tx = transactionFactory.newInstance();
-
- //Runnable task = new Log4JRunnable(tx);
- //Runnable task = new Log4J2Runnable(tx);
+
+ // Runnable task = new Log4JRunnable(tx);
+ // Runnable task = new Log4J2Runnable(tx);
Runnable task = new Slf4jRunnable(tx);
-
+
executor.submit(task);
}
diff --git a/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java b/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java
index b024f3ec81..e581c45cd3 100644
--- a/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java
+++ b/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java
@@ -13,7 +13,6 @@ import org.springframework.web.bind.annotation.RestController;
import com.baeldung.ndc.Investment;
import com.baeldung.ndc.service.InvestmentService;
-
@RestController
public class JBossLoggingController {
@Autowired
diff --git a/log-mdc/src/test/java/com/baeldung/mdc/log4j/Demo.java b/log-mdc/src/test/java/com/baeldung/mdc/log4j/Demo.java
index f9a210606f..665168452a 100644
--- a/log-mdc/src/test/java/com/baeldung/mdc/log4j/Demo.java
+++ b/log-mdc/src/test/java/com/baeldung/mdc/log4j/Demo.java
@@ -17,7 +17,7 @@ public class Demo {
TransactionFactory transactionFactory = new TransactionFactory();
for (int i = 0; i < 10; i++) {
Transfer tx = transactionFactory.newInstance();
- Runnable task = new Log4JRunnable(tx);
+ Runnable task = new Log4JRunnable(tx);
executor.submit(task);
}
executor.shutdown();
diff --git a/log-mdc/src/test/java/com/baeldung/mdc/log4j2/Demo.java b/log-mdc/src/test/java/com/baeldung/mdc/log4j2/Demo.java
index 3f7c1d37d5..78c48c2a83 100644
--- a/log-mdc/src/test/java/com/baeldung/mdc/log4j2/Demo.java
+++ b/log-mdc/src/test/java/com/baeldung/mdc/log4j2/Demo.java
@@ -21,7 +21,7 @@ public class Demo {
TransactionFactory transactionFactory = new TransactionFactory();
for (int i = 0; i < 10; i++) {
Transfer tx = transactionFactory.newInstance();
- Runnable task = new Log4J2Runnable(tx);
+ Runnable task = new Log4J2Runnable(tx);
executor.submit(task);
}
executor.shutdown();
diff --git a/log-mdc/src/test/java/com/baeldung/mdc/slf4j/Demo.java b/log-mdc/src/test/java/com/baeldung/mdc/slf4j/Demo.java
index 98db698f47..de890f9f5d 100644
--- a/log-mdc/src/test/java/com/baeldung/mdc/slf4j/Demo.java
+++ b/log-mdc/src/test/java/com/baeldung/mdc/slf4j/Demo.java
@@ -21,7 +21,7 @@ public class Demo {
TransactionFactory transactionFactory = new TransactionFactory();
for (int i = 0; i < 10; i++) {
Transfer tx = transactionFactory.newInstance();
- Runnable task = new Slf4jRunnable(tx);
+ Runnable task = new Slf4jRunnable(tx);
executor.submit(task);
}
executor.shutdown();
diff --git a/log4j2/pom.xml b/log4j2/pom.xml
index 893c79be72..a4c8f19f69 100644
--- a/log4j2/pom.xml
+++ b/log4j2/pom.xml
@@ -1,105 +1,104 @@
- 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
- log4j2
+ log4j2
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
- ..
-
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+ ..
+
-
-
-
- org.apache.logging.log4j
- log4j-core
- ${log4j-core.version}
-
+
+
+
+ org.apache.logging.log4j
+ log4j-core
+ ${log4j-core.version}
+
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
-
-
- com.fasterxml.jackson.dataformat
- jackson-dataformat-xml
- ${jackson.version}
-
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-xml
+ ${jackson.version}
+
-
-
- com.h2database
- h2
- ${h2.version}
-
-
- org.apache.commons
- commons-dbcp2
- ${commons-dbcp2.version}
-
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+ org.apache.commons
+ commons-dbcp2
+ ${commons-dbcp2.version}
+
-
-
- org.apache.logging.log4j
- log4j-core
- ${log4j-core.version}
- test-jar
- test
-
-
- junit
- junit
- ${junit.version}
- test
-
-
+
+
+ org.apache.logging.log4j
+ log4j-core
+ ${log4j-core.version}
+ test-jar
+ test
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
-
-
+
+
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- 1.8
- 1.8
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${maven-surefire-plugin.version}
-
-
- **/*IntegrationTest.java
- **/*LongRunningUnitTest.java
- **/*ManualTest.java
-
- true
-
-
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ **/*IntegrationTest.java
+ **/*LongRunningUnitTest.java
+ **/*ManualTest.java
+
+ true
+
+
-
-
+
+
-
- 2.8.5
- 1.4.193
- 2.1.1
- 2.7
- 4.12
-
- 3.6.0
- 2.19.1
-
+
+ 2.8.5
+ 1.4.193
+ 2.1.1
+ 2.7
+ 4.12
+ 3.6.0
+ 2.19.1
+
diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/AsyncFileAppenderUsingJsonLayoutTest.java b/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/AsyncFileAppenderUsingJsonLayoutTest.java
deleted file mode 100644
index 0472c2219e..0000000000
--- a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/AsyncFileAppenderUsingJsonLayoutTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.baeldung.logging.log4j2.tests;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import static org.junit.Assert.assertTrue;
-
-@RunWith(JUnit4.class)
-public class AsyncFileAppenderUsingJsonLayoutTest {
- @Rule
- public LoggerContextRule contextRule =
- new LoggerContextRule("log4j2-async-file-appender_json-layout.xml");
-
- @Test
- public void givenLoggerWithAsyncConfig_shouldLogToJsonFile()
- throws Exception {
- Logger logger = contextRule.getLogger(getClass().getSimpleName());
- final int count = 88;
- for (int i = 0; i < count; i++) {
- logger.info("This is async JSON message #{} at INFO level.", count);
- }
- long logEventsCount = Files.lines(Paths.get("target/logfile.json")).count();
- assertTrue(logEventsCount > 0 && logEventsCount <= count);
- }
-}
diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/ConsoleAppenderUsingDefaultLayoutTest.java b/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/ConsoleAppenderUsingDefaultLayoutTest.java
deleted file mode 100644
index 9831030d02..0000000000
--- a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/ConsoleAppenderUsingDefaultLayoutTest.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.baeldung.logging.log4j2.tests;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ConsoleAppenderUsingDefaultLayoutTest {
- @Test
- public void givenLoggerWithDefaultConfig_shouldLogToConsole()
- throws Exception {
- Logger logger = LogManager.getLogger(getClass());
- Exception e = new RuntimeException("This is only a test!");
- logger.info("This is a simple message at INFO level. " +
- "It will be hidden.");
- logger.error("This is a simple message at ERROR level. " +
- "This is the minimum visible level.", e);
- }
-}
diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/ConsoleAppenderUsingPatternLayoutWithColorsTest.java b/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/ConsoleAppenderUsingPatternLayoutWithColorsTest.java
deleted file mode 100644
index 86b005538f..0000000000
--- a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/ConsoleAppenderUsingPatternLayoutWithColorsTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.baeldung.logging.log4j2.tests;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.Marker;
-import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ConsoleAppenderUsingPatternLayoutWithColorsTest {
- @Rule
- public LoggerContextRule contextRule =
- new LoggerContextRule("log4j2-console-appender_pattern-layout.xml");
-
- @Test
- public void givenLoggerWithConsoleConfig_shouldLogToConsoleInColors()
- throws Exception {
- Logger logger = contextRule.getLogger(getClass().getSimpleName());
- logger.trace("This is a colored message at TRACE level.");
- logger.debug("This is a colored message at DEBUG level. " +
- "This is the minimum visible level.");
- logger.info("This is a colored message at INFO level.");
- logger.warn("This is a colored message at WARN level.");
- Exception e = new RuntimeException("This is only a test!");
- logger.error("This is a colored message at ERROR level.", e);
- logger.fatal("This is a colored message at FATAL level.");
- }
-
- @Test
- public void givenLoggerWithConsoleConfig_shouldFilterByMarker() throws Exception {
- Logger logger = contextRule.getLogger("ConnTrace");
- Marker appError = MarkerManager.getMarker("APP_ERROR");
- logger.error(appError, "This marker message at ERROR level should be hidden.");
- Marker connectionTrace = MarkerManager.getMarker("CONN_TRACE");
- logger.trace(connectionTrace, "This is a marker message at TRACE level.");
- }
-
- @Test
- public void givenLoggerWithConsoleConfig_shouldFilterByThreadContext() throws Exception {
- Logger logger = contextRule.getLogger("UserAudit");
- ThreadContext.put("userId", "1000");
- logger.info("This is a log-visible user login. Maybe from an admin account?");
- ThreadContext.put("userId", "1001");
- logger.info("This is a log-invisible user login.");
- boolean b = true;
- }
-}
diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingTest.java b/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingTest.java
new file mode 100644
index 0000000000..1562b67068
--- /dev/null
+++ b/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingTest.java
@@ -0,0 +1,122 @@
+package com.baeldung.logging.log4j2.tests;
+
+import static org.junit.Assert.assertTrue;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.ThreadContext;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory;
+
+@RunWith(JUnit4.class)
+public class CustomLoggingTest {
+
+ @BeforeClass
+ public static void setup() throws Exception {
+ Connection connection = ConnectionFactory.getConnection();
+ connection.createStatement()
+ .execute("CREATE TABLE logs(" + "when TIMESTAMP," + "logger VARCHAR(255)," + "level VARCHAR(255)," + "message VARCHAR(4096)," + "throwable TEXT)");
+ connection.commit();
+ }
+
+ @Test
+ public void givenLoggerWithDefaultConfig_shouldLogToConsole() throws Exception {
+ Logger logger = LogManager.getLogger(getClass());
+ Exception e = new RuntimeException("This is only a test!");
+ logger.info("This is a simple message at INFO level. " + "It will be hidden.");
+ logger.error("This is a simple message at ERROR level. " + "This is the minimum visible level.", e);
+ }
+
+ @Test
+ public void givenLoggerWithConsoleConfig_shouldLogToConsoleInColors() throws Exception {
+ Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER");
+ logger.trace("This is a colored message at TRACE level.");
+ logger.debug("This is a colored message at DEBUG level. " + "This is the minimum visible level.");
+ logger.info("This is a colored message at INFO level.");
+ logger.warn("This is a colored message at WARN level.");
+ Exception e = new RuntimeException("This is only a test!");
+ logger.error("This is a colored message at ERROR level.", e);
+ logger.fatal("This is a colored message at FATAL level.");
+ }
+
+ @Test
+ public void givenLoggerWithConsoleConfig_shouldFilterByMarker() throws Exception {
+ Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER");
+ Marker appError = MarkerManager.getMarker("APP_ERROR");
+ logger.error(appError, "This marker message at ERROR level should be hidden.");
+ Marker connectionTrace = MarkerManager.getMarker("CONN_TRACE");
+ logger.trace(connectionTrace, "This is a marker message at TRACE level.");
+ }
+
+ @Test
+ public void givenLoggerWithConsoleConfig_shouldFilterByThreadContext() throws Exception {
+ Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_THREAD_CONTEXT");
+ ThreadContext.put("userId", "1000");
+ logger.info("This is a log-visible user login. Maybe from an admin account?");
+ ThreadContext.put("userId", "1001");
+ logger.info("This is a log-invisible user login.");
+
+ }
+
+ @Test
+ public void givenLoggerWithAsyncConfig_shouldLogToJsonFile() throws Exception {
+ Logger logger = LogManager.getLogger("ASYNC_JSON_FILE_APPENDER");
+ final int count = 88;
+ for (int i = 0; i < count; i++) {
+ logger.info("This is async JSON message #{} at INFO level.", count);
+ }
+ long logEventsCount = Files.lines(Paths.get("target/logfile.json"))
+ .count();
+ assertTrue(logEventsCount > 0 && logEventsCount <= count);
+ }
+
+ @Test
+ public void givenLoggerWithFailoverConfig_shouldLog() throws Exception {
+ Logger logger = LogManager.getLogger("FAIL_OVER_SYSLOG_APPENDER");
+ logger.trace("This is a syslog message at TRACE level.");
+ logger.debug("This is a syslog message at DEBUG level.");
+ logger.info("This is a syslog message at INFO level. This is the minimum visible level.");
+ logger.warn("This is a syslog message at WARN level.");
+ Exception e = new RuntimeException("This is only a test!");
+ logger.error("This is a syslog message at ERROR level.", e);
+ logger.fatal("This is a syslog message at FATAL level.");
+ }
+
+ @Test
+ public void givenLoggerWithJdbcConfig_shouldLogToDataSource() throws Exception {
+ Logger logger = LogManager.getLogger("JDBC_APPENDER");
+ final int count = 88;
+ for (int i = 0; i < count; i++) {
+ logger.info("This is JDBC message #{} at INFO level.", count);
+ }
+ Connection connection = ConnectionFactory.getConnection();
+ ResultSet resultSet = connection.createStatement()
+ .executeQuery("SELECT COUNT(*) AS ROW_COUNT FROM logs");
+ int logCount = 0;
+ if (resultSet.next()) {
+ logCount = resultSet.getInt("ROW_COUNT");
+ }
+ assertTrue(logCount == count);
+ }
+
+ @Test
+ public void givenLoggerWithRollingFileConfig_shouldLogToXMLFile() throws Exception {
+ Logger logger = LogManager.getLogger("XML_ROLLING_FILE_APPENDER");
+ final int count = 88;
+ for (int i = 0; i < count; i++) {
+ logger.info("This is rolling file XML message #{} at INFO level.", i);
+ }
+ }
+
+}
diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/FailoverSyslogConsoleAppenderTest.java b/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/FailoverSyslogConsoleAppenderTest.java
deleted file mode 100644
index 0653394e5a..0000000000
--- a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/FailoverSyslogConsoleAppenderTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.baeldung.logging.log4j2.tests;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class FailoverSyslogConsoleAppenderTest {
- @Rule
- public LoggerContextRule contextRule =
- new LoggerContextRule("log4j2-failover-syslog-console-appender_pattern-layout.xml");
-
- @Test
- public void givenLoggerWithFailoverConfig_shouldLog() throws Exception {
- Logger logger = contextRule.getLogger(getClass().getSimpleName());
- logger.trace("This is a syslog message at TRACE level.");
- logger.debug("This is a syslog message at DEBUG level.");
- logger.info("This is a syslog message at INFO level. This is the minimum visible level.");
- logger.warn("This is a syslog message at WARN level.");
- Exception e = new RuntimeException("This is only a test!");
- logger.error("This is a syslog message at ERROR level.", e);
- logger.fatal("This is a syslog message at FATAL level.");
- }
-}
diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JDBCAppenderTest.java b/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JDBCAppenderTest.java
deleted file mode 100644
index 1b8d33e2bf..0000000000
--- a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JDBCAppenderTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.baeldung.logging.log4j2.tests;
-
-import com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-
-import static org.junit.Assert.assertTrue;
-
-@RunWith(JUnit4.class)
-public class JDBCAppenderTest {
- @Rule
- public LoggerContextRule contextRule = new LoggerContextRule("log4j2-jdbc-appender.xml");
-
- @BeforeClass
- public static void setup() throws Exception {
- Connection connection = ConnectionFactory.getConnection();
- connection.createStatement()
- .execute("CREATE TABLE logs(" +
- "when TIMESTAMP," +
- "logger VARCHAR(255)," +
- "level VARCHAR(255)," +
- "message VARCHAR(4096)," +
- "throwable TEXT)");
- //connection.commit();
- }
-
- @Test
- public void givenLoggerWithJdbcConfig_shouldLogToDataSource() throws Exception {
- Logger logger = contextRule.getLogger(getClass().getSimpleName());
- final int count = 88;
- for (int i = 0; i < count; i++) {
- logger.info("This is JDBC message #{} at INFO level.", count);
- }
- Connection connection = ConnectionFactory.getConnection();
- ResultSet resultSet = connection.createStatement()
- .executeQuery("SELECT COUNT(*) AS ROW_COUNT FROM logs");
- int logCount = 0;
- if (resultSet.next()) {
- logCount = resultSet.getInt("ROW_COUNT");
- }
- assertTrue(logCount == count);
- }
-}
diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/RollingFileAppenderUsingXMLLayoutTest.java b/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/RollingFileAppenderUsingXMLLayoutTest.java
deleted file mode 100644
index 3ab69d263c..0000000000
--- a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/RollingFileAppenderUsingXMLLayoutTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.baeldung.logging.log4j2.tests;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.stream.Collectors;
-
-import static org.junit.Assert.assertTrue;
-
-@RunWith(JUnit4.class)
-public class RollingFileAppenderUsingXMLLayoutTest {
- @Rule
- public LoggerContextRule contextRule =
- new LoggerContextRule("log4j2-rolling-file-appender_xml-layout.xml");
-
- @Test
- public void givenLoggerWithRollingFileConfig_shouldLogToXMLFile() throws Exception {
- Logger logger = contextRule.getLogger(getClass().getSimpleName());
- final int count = 88;
- for (int i = 0; i < count; i++) {
- logger.info("This is rolling file XML message #{} at INFO level.", i);
- }
- String[] logEvents = Files.readAllLines(Paths.get("target/logfile.xml")).stream()
- .collect(Collectors.joining(System.lineSeparator()))
- .split("\\n\\n+");
- assertTrue(logEvents.length == 39);
- }
-}
diff --git a/log4j2/src/test/resources/log4j2-async-file-appender_json-layout.xml b/log4j2/src/test/resources/log4j2-async-file-appender_json-layout.xml
deleted file mode 100644
index c291eacd59..0000000000
--- a/log4j2/src/test/resources/log4j2-async-file-appender_json-layout.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/log4j2/src/test/resources/log4j2-console-appender_pattern-layout.xml b/log4j2/src/test/resources/log4j2-console-appender_pattern-layout.xml
deleted file mode 100644
index d6621f9166..0000000000
--- a/log4j2/src/test/resources/log4j2-console-appender_pattern-layout.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/log4j2/src/test/resources/log4j2-failover-syslog-console-appender_pattern-layout.xml b/log4j2/src/test/resources/log4j2-failover-syslog-console-appender_pattern-layout.xml
deleted file mode 100644
index 62ba37f28c..0000000000
--- a/log4j2/src/test/resources/log4j2-failover-syslog-console-appender_pattern-layout.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/log4j2/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml b/log4j2/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml
index c2b9c65430..fd61e4581f 100644
--- a/log4j2/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml
+++ b/log4j2/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml
@@ -1,4 +1,5 @@
-
+
diff --git a/log4j2/src/test/resources/log4j2-jdbc-appender.xml b/log4j2/src/test/resources/log4j2-jdbc-appender.xml
deleted file mode 100644
index 6b50f7d5a4..0000000000
--- a/log4j2/src/test/resources/log4j2-jdbc-appender.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/log4j2/src/test/resources/log4j2-rolling-file-appender_xml-layout.xml b/log4j2/src/test/resources/log4j2-rolling-file-appender_xml-layout.xml
deleted file mode 100644
index 9de1a29186..0000000000
--- a/log4j2/src/test/resources/log4j2-rolling-file-appender_xml-layout.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/log4j2/src/test/resources/log4j2.xml b/log4j2/src/test/resources/log4j2.xml
index 8f7608aa78..83c1184f1f 100644
--- a/log4j2/src/test/resources/log4j2.xml
+++ b/log4j2/src/test/resources/log4j2.xml
@@ -1,13 +1,69 @@
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/mesos-marathon/Dockerfile b/mesos-marathon/Dockerfile
new file mode 100644
index 0000000000..ca79f2dc82
--- /dev/null
+++ b/mesos-marathon/Dockerfile
@@ -0,0 +1,4 @@
+FROM openjdk:8-jre-alpine
+ADD target/mesos-marathon-0.0.1-SNAPSHOT.jar app.jar
+EXPOSE 8082
+ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
diff --git a/mesos-marathon/dockerise.sh b/mesos-marathon/dockerise.sh
new file mode 100755
index 0000000000..50f5d38306
--- /dev/null
+++ b/mesos-marathon/dockerise.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+set -e
+docker login -u mogronalol -p $DOCKER_PASSWORD
+docker build -t baeldung/mesos-marathon-demo:$BUILD_NUMBER .
+docker push baeldung/mesos-marathon-demo:$BUILD_NUMBER
diff --git a/mesos-marathon/marathon.json b/mesos-marathon/marathon.json
new file mode 100644
index 0000000000..6471259e92
--- /dev/null
+++ b/mesos-marathon/marathon.json
@@ -0,0 +1,14 @@
+{
+ "id": "mesos-marathon-demo",
+ "container": {
+ "type": "DOCKER",
+ "docker": {
+ "image": "",
+ "network": "BRIDGE",
+ "portMappings": [
+ { "containerPort": 8082, "hostPort": 0 }
+ ]
+ },
+ "volumes": []
+ }
+}
\ No newline at end of file
diff --git a/mesos-marathon/pom.xml b/mesos-marathon/pom.xml
new file mode 100644
index 0000000000..ca17a5c4c4
--- /dev/null
+++ b/mesos-marathon/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ mesos-marathon
+ 0.0.1-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.1.RELEASE
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 1.5.1.RELEASE
+
+
+
+ repackage
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mesos-marathon/src/main/java/com/mogronalol/DemoApplication.java b/mesos-marathon/src/main/java/com/mogronalol/DemoApplication.java
new file mode 100644
index 0000000000..f757178026
--- /dev/null
+++ b/mesos-marathon/src/main/java/com/mogronalol/DemoApplication.java
@@ -0,0 +1,14 @@
+package com.mogronalol;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import javax.annotation.PostConstruct;
+
+@SpringBootApplication
+public class DemoApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(DemoApplication.class, args);
+ }
+}
diff --git a/mesos-marathon/src/main/java/com/mogronalol/HelloController.java b/mesos-marathon/src/main/java/com/mogronalol/HelloController.java
new file mode 100644
index 0000000000..2059280ba0
--- /dev/null
+++ b/mesos-marathon/src/main/java/com/mogronalol/HelloController.java
@@ -0,0 +1,17 @@
+package com.mogronalol;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController(value = "/")
+public class HelloController {
+
+ @GetMapping
+ @ResponseBody
+ public String getMapping() {
+ return "Hello world";
+ }
+
+}
diff --git a/mesos-marathon/src/main/resources/application.properties b/mesos-marathon/src/main/resources/application.properties
new file mode 100644
index 0000000000..8d51d0c619
--- /dev/null
+++ b/mesos-marathon/src/main/resources/application.properties
@@ -0,0 +1 @@
+server.port=8082
\ No newline at end of file
diff --git a/mesos-marathon/src/test/java/com/mogronalol/DemoApplicationTests.java b/mesos-marathon/src/test/java/com/mogronalol/DemoApplicationTests.java
new file mode 100644
index 0000000000..5e88f9a70f
--- /dev/null
+++ b/mesos-marathon/src/test/java/com/mogronalol/DemoApplicationTests.java
@@ -0,0 +1,34 @@
+package com.mogronalol;
+
+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.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.web.client.RestTemplate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = {DemoApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class DemoApplicationTests {
+
+ private RestTemplate restTemplate;
+
+ @LocalServerPort
+ private int port;
+
+ @Before
+ public void setUp() {
+ restTemplate = new RestTemplate();
+ }
+
+ @Test
+ public void contextLoads() {
+ final String result = restTemplate.getForObject("http://localhost:" + port + "/", String.class);
+ assertThat(result).isEqualTo("Hello world");
+ }
+
+}
diff --git a/metrics/README.md b/metrics/README.md
new file mode 100644
index 0000000000..c98024c479
--- /dev/null
+++ b/metrics/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Intro to Dropwizard Metrics](http://www.baeldung.com/dropwizard-metrics)
diff --git a/metrics/src/test/java/com/baeldung/metrics/core/MetricsTest.java b/metrics/src/test/java/com/baeldung/metrics/core/MetricsTest.java
index f670acfaef..e876de6e65 100644
--- a/metrics/src/test/java/com/baeldung/metrics/core/MetricsTest.java
+++ b/metrics/src/test/java/com/baeldung/metrics/core/MetricsTest.java
@@ -138,15 +138,15 @@ public class MetricsTest {
long elapsed1 = context1.stop();
- assertEquals(5000000000L, elapsed1, 10000000);
+ assertEquals(5000000000L, elapsed1, 1000000000);
assertThat(timer.getCount(), equalTo(1L));
- assertEquals(0.2, timer.getMeanRate(), 0.1);
+ assertEquals(0.2, timer.getMeanRate(), 0.2);
Timer.Context context2 = timer.time();
TimeUnit.SECONDS.sleep(2);
context2.close();
assertThat(timer.getCount(), equalTo(2L));
- assertEquals(0.3, timer.getMeanRate(), 0.1);
+ assertEquals(0.3, timer.getMeanRate(), 0.2);
}
}
diff --git a/pdf/README.md b/pdf/README.md
index 7160df4081..5454d2b2de 100644
--- a/pdf/README.md
+++ b/pdf/README.md
@@ -1,2 +1,3 @@
### Relevant Articles:
- [PDF Conversions in Java](http://www.baeldung.com/pdf-conversions-java)
+- [Creating PDF Files in Java](http://www.baeldung.com/java-pdf-creation)
diff --git a/pom.xml b/pom.xml
index 41235dcc26..9d6c5931e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,9 +8,10 @@
parent-modules
pom
-
UTF-8
+ refs/heads/master
+ false
@@ -63,6 +64,7 @@
jaxb
jee7
jjwt
+ jooq
jpa-storedprocedure
jsf
json-path
@@ -72,6 +74,7 @@
kotlin
+ libraries
log-mdc
log4j
log4j2
@@ -79,6 +82,7 @@
mapstruct
metrics
+ mesos-marathon
mockito
mocks
@@ -106,6 +110,7 @@
spring-autowire
spring-batch
spring-boot
+ spring-boot-servlet
spring-cloud-data-flow
spring-cloud
spring-core
@@ -147,6 +152,7 @@
spring-rest-docs
spring-rest
spring-security-basic-auth
+ 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
@@ -155,7 +161,7 @@
spring-security-client/spring-security-thymeleaf-authorize
spring-security-client/spring-security-thymeleaf-config
spring-security-core
- spring-security-custom-permission
+ spring-security-mvc-boot
spring-security-mvc-custom
spring-security-mvc-digest-auth
spring-security-mvc-ldap
@@ -178,6 +184,7 @@
spring-reactor
testing
+ testng
video-tutorials
@@ -188,7 +195,21 @@
xstream
struts2
+ apache-velocity
+ apache-solrj
-
+ rabbitmq
+
+
+
+
+
+
+
+
diff --git a/rabbitmq/pom.xml b/rabbitmq/pom.xml
new file mode 100644
index 0000000000..03f192e4e1
--- /dev/null
+++ b/rabbitmq/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+ 4.0.0
+ com.baeldung
+ rabbitmq
+ 0.1-SNAPSHOT
+
+ rabbitmq
+ http://maven.apache.org
+
+
+
+ com.rabbitmq
+ amqp-client
+ 3.6.6
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+
+ UTF-8
+
+ 3.6.0
+
+
+
\ No newline at end of file
diff --git a/rabbitmq/src/main/java/com/baeldung/consumer/Receiver.java b/rabbitmq/src/main/java/com/baeldung/consumer/Receiver.java
new file mode 100644
index 0000000000..d0612406e9
--- /dev/null
+++ b/rabbitmq/src/main/java/com/baeldung/consumer/Receiver.java
@@ -0,0 +1,31 @@
+package com.baeldung.consumer;
+
+import com.rabbitmq.client.*;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+public class Receiver {
+
+ private static final String QUEUE_NAME = "products_queue";
+
+ public static void main (String[] args) throws IOException, TimeoutException {
+ ConnectionFactory factory = new ConnectionFactory();
+ factory.setHost("localhost");
+ Connection connection = factory.newConnection();
+ Channel channel = connection.createChannel();
+
+ channel.queueDeclare(QUEUE_NAME, false, false, false, null);
+
+ Consumer consumer = new DefaultConsumer(channel) {
+ @Override
+ public void handleDelivery(String consumerTag,
+ Envelope envelope, AMQP.BasicProperties properties,
+ byte[] body) throws IOException {
+ String message = new String(body, "UTF-8");
+ System.out.println(" [x] Received '" + message + "'");
+ }
+ };
+ channel.basicConsume(QUEUE_NAME, true, consumer);
+ }
+}
diff --git a/rabbitmq/src/main/java/com/baeldung/producer/Publisher.java b/rabbitmq/src/main/java/com/baeldung/producer/Publisher.java
new file mode 100644
index 0000000000..f9130c5d86
--- /dev/null
+++ b/rabbitmq/src/main/java/com/baeldung/producer/Publisher.java
@@ -0,0 +1,27 @@
+package com.baeldung.producer;
+
+import com.rabbitmq.client.*;
+
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+
+public class Publisher {
+
+ private final static String QUEUE_NAME = "products_queue";
+
+ public static void main(String[]args) throws IOException, TimeoutException {
+ ConnectionFactory factory = new ConnectionFactory();
+ factory.setHost("localhost");
+ Connection connection = factory.newConnection();
+ Channel channel = connection.createChannel();
+
+ String message = "product details";
+ channel.queueDeclare(QUEUE_NAME, false, false, false, null);
+
+ channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
+ System.out.println(" [x] Sent '" + message + "'");
+
+ channel.close();
+ connection.close();
+ }
+}
diff --git a/rxjava/README.md b/rxjava/README.md
new file mode 100644
index 0000000000..7670dd4ed3
--- /dev/null
+++ b/rxjava/README.md
@@ -0,0 +1,4 @@
+## Relevant articles:
+
+- [Dealing with Backpressure with RxJava](http://www.baeldung.com/rxjava-backpressure)
+- [How to Test RxJava?](http://www.baeldung.com/rxjava-testing)
diff --git a/rxjava/pom.xml b/rxjava/pom.xml
index 63aa1f127e..b3936bf78d 100644
--- a/rxjava/pom.xml
+++ b/rxjava/pom.xml
@@ -26,10 +26,25 @@
rxjava
${rx.java.version}
+
+ junit
+ junit
+ ${junit.version}
+
+
+ org.hamcrest
+ hamcrest-all
+ ${hamcrest.version}
+ test
+
+
+
+ 4.12
1.2.5
+ 1.3
\ No newline at end of file
diff --git a/rxjava/src/main/java/com/baelding/rxjava/ColdObservableBackpressure.java b/rxjava/src/main/java/com/baelding/rxjava/ColdObservableBackpressure.java
deleted file mode 100644
index 9855123a3b..0000000000
--- a/rxjava/src/main/java/com/baelding/rxjava/ColdObservableBackpressure.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.baelding.rxjava;
-
-import rx.Observable;
-import rx.schedulers.Schedulers;
-
-public class ColdObservableBackpressure {
- public static void main(String[] args) throws InterruptedException {
- Observable.range(1, 1_000_000).observeOn(Schedulers.computation()).subscribe(v -> ComputeFunction.compute(v), Throwable::printStackTrace);
-
- Thread.sleep(10_000);
-
- // Observable.range(1, 1_000_000) //implementation of reactive pull backpressure on cold observable
- // .subscribe(new Subscriber() {
- // @Override
- // public void onStart() {
- // request(1);
- // }
- //
- // public void onNext(Integer v) {
- // compute(v);
- //
- // request(1);
- // }
- //
- // @Override
- // public void onError(Throwable ex) {
- // ex.printStackTrace();
- // }
- //
- // @Override
- // public void onCompleted() {
- // System.out.println("Done!");
- // }
- // });
-
- }
-
-}
diff --git a/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureBatching.java b/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureBatching.java
deleted file mode 100644
index 6acda7eaad..0000000000
--- a/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureBatching.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.baelding.rxjava;
-
-import rx.schedulers.Schedulers;
-import rx.subjects.PublishSubject;
-
-public class HotObservableBackpressureBatching {
- public static void main(String[] args) throws InterruptedException {
- PublishSubject source = PublishSubject.create();
-
- source.window(500).observeOn(Schedulers.computation()).subscribe(ComputeFunction::compute, Throwable::printStackTrace);
-
- for (int i = 0; i < 1_000_000; i++) {
- source.onNext(i);
- }
- Thread.sleep(10_000);
- }
-
-}
diff --git a/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureBuffering.java b/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureBuffering.java
deleted file mode 100644
index 50638f4c8a..0000000000
--- a/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureBuffering.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.baelding.rxjava;
-
-import rx.schedulers.Schedulers;
-import rx.subjects.PublishSubject;
-
-public class HotObservableBackpressureBuffering {
- public static void main(String[] args) throws InterruptedException {
- PublishSubject source = PublishSubject.create();
-
- source.buffer(1024).observeOn(Schedulers.computation()).subscribe(ComputeFunction::compute, Throwable::printStackTrace);
-
- for (int i = 0; i < 1_000_000; i++) {
- source.onNext(i);
- }
- Thread.sleep(10_000);
- }
-}
diff --git a/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureSkipping.java b/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureSkipping.java
deleted file mode 100644
index f6f8b9f563..0000000000
--- a/rxjava/src/main/java/com/baelding/rxjava/HotObservableBackpressureSkipping.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.baelding.rxjava;
-
-import rx.schedulers.Schedulers;
-import rx.subjects.PublishSubject;
-
-import java.util.concurrent.TimeUnit;
-
-public class HotObservableBackpressureSkipping {
- public static void main(String[] args) throws InterruptedException {
- PublishSubject source = PublishSubject.create();
-
- source.sample(100, TimeUnit.MILLISECONDS)
- // .throttleFirst(100, TimeUnit.MILLISECONDS)
- .observeOn(Schedulers.computation()).subscribe(ComputeFunction::compute, Throwable::printStackTrace);
-
- for (int i = 0; i < 1_000_000; i++) {
- source.onNext(i);
- }
- Thread.sleep(10_000);
- }
-}
diff --git a/rxjava/src/main/java/com/baelding/rxjava/HotObservableOnBackpressure.java b/rxjava/src/main/java/com/baelding/rxjava/HotObservableOnBackpressure.java
deleted file mode 100644
index afef8027bf..0000000000
--- a/rxjava/src/main/java/com/baelding/rxjava/HotObservableOnBackpressure.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.baelding.rxjava;
-
-import rx.BackpressureOverflow;
-import rx.Observable;
-import rx.schedulers.Schedulers;
-
-public class HotObservableOnBackpressure {
- public static void main(String[] args) throws InterruptedException {
- Observable.range(1, 1_000_000).onBackpressureBuffer(16, () -> {
- }, BackpressureOverflow.ON_OVERFLOW_DROP_OLDEST).observeOn(Schedulers.computation()).subscribe(e -> {
- }, Throwable::printStackTrace);
-
- Observable.range(1, 1_000_000).onBackpressureDrop().observeOn(Schedulers.io()).doOnNext(ComputeFunction::compute).subscribe(v -> {
- }, Throwable::printStackTrace);
- Thread.sleep(10_000);
-
- }
-}
diff --git a/rxjava/src/main/java/com/baelding/rxjava/HotObservableWithoutBackpressure.java b/rxjava/src/main/java/com/baelding/rxjava/HotObservableWithoutBackpressure.java
deleted file mode 100644
index 7745dbe5c4..0000000000
--- a/rxjava/src/main/java/com/baelding/rxjava/HotObservableWithoutBackpressure.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.baelding.rxjava;
-
-
-import rx.schedulers.Schedulers;
-import rx.subjects.PublishSubject;
-
-public class HotObservableWithoutBackpressure {
- public static void main(String[] args) throws InterruptedException {
- PublishSubject source = PublishSubject.create();
-
- source.observeOn(Schedulers.computation())
- .subscribe(ComputeFunction::compute, Throwable::printStackTrace);
-
-
- for (int i = 0; i < 1_000_000; i++) {
- source.onNext(i);
- }
- Thread.sleep(10_000);
- }
-}
diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureTest.java b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureTest.java
new file mode 100644
index 0000000000..8a495650b3
--- /dev/null
+++ b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureTest.java
@@ -0,0 +1,130 @@
+package com.baeldung.rxjava;
+
+import org.junit.Test;
+import rx.BackpressureOverflow;
+import rx.Observable;
+import rx.exceptions.MissingBackpressureException;
+import rx.observers.TestSubscriber;
+import rx.schedulers.Schedulers;
+import rx.subjects.PublishSubject;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+import static org.junit.Assert.assertTrue;
+
+public class RxJavaBackpressureTest {
+
+ @Test
+ public void givenColdObservable_shouldNotThrowException() {
+ // given
+ TestSubscriber testSubscriber = new TestSubscriber<>();
+
+ // when
+ Observable.range(1, 1_000_000).observeOn(Schedulers.computation()).subscribe(testSubscriber);
+
+ // then
+ testSubscriber.awaitTerminalEvent();
+ assertTrue(testSubscriber.getOnErrorEvents().size() == 0);
+
+ }
+
+ @Test
+ public void givenHotObservable_whenBackpressureNotDefined_shouldTrowException() {
+ // given
+ TestSubscriber testSubscriber = new TestSubscriber<>();
+ PublishSubject source = PublishSubject. create();
+
+ source.observeOn(Schedulers.computation()).subscribe(testSubscriber);
+
+ // when
+ IntStream.range(0, 1_000_000).forEach(source::onNext);
+
+ // then
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertError(MissingBackpressureException.class);
+ }
+
+ @Test
+ public void givenHotObservable_whenWindowIsDefined_shouldNotThrowException() {
+ // given
+ TestSubscriber> testSubscriber = new TestSubscriber<>();
+ PublishSubject source = PublishSubject. create();
+
+ // when
+ source.window(500).observeOn(Schedulers.computation()).subscribe(testSubscriber);
+
+ IntStream.range(0, 1_000).forEach(source::onNext);
+
+ // then
+ testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS);
+ assertTrue(testSubscriber.getOnErrorEvents().size() == 0);
+
+ }
+
+ @Test
+ public void givenHotObservable_whenBufferIsDefined_shouldNotThrowException() {
+ // given
+ TestSubscriber> testSubscriber = new TestSubscriber<>();
+ PublishSubject source = PublishSubject. create();
+
+ // when
+ source.buffer(1024).observeOn(Schedulers.computation()).subscribe(testSubscriber);
+
+ IntStream.range(0, 1_000).forEach(source::onNext);
+
+ // then
+ testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS);
+ assertTrue(testSubscriber.getOnErrorEvents().size() == 0);
+
+ }
+
+ @Test
+ public void givenHotObservable_whenSkippingOperationIsDefined_shouldNotThrowException() {
+ // given
+ TestSubscriber testSubscriber = new TestSubscriber<>();
+ PublishSubject source = PublishSubject. create();
+
+ // when
+ source.sample(100, TimeUnit.MILLISECONDS)
+ // .throttleFirst(100, TimeUnit.MILLISECONDS)
+ .observeOn(Schedulers.computation()).subscribe(testSubscriber);
+
+ IntStream.range(0, 1_000).forEach(source::onNext);
+
+ // then
+ testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS);
+ assertTrue(testSubscriber.getOnErrorEvents().size() == 0);
+
+ }
+
+ @Test
+ public void givenHotObservable_whenOnBackpressureBufferDefined_shouldNotThrowException() {
+ // given
+ TestSubscriber testSubscriber = new TestSubscriber<>();
+
+ // when
+ Observable.range(1, 1_000_000).onBackpressureBuffer(16, () -> {
+ }, BackpressureOverflow.ON_OVERFLOW_DROP_OLDEST).observeOn(Schedulers.computation()).subscribe(testSubscriber);
+
+ // then
+ testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS);
+ assertTrue(testSubscriber.getOnErrorEvents().size() == 0);
+
+ }
+
+ @Test
+ public void givenHotObservable_whenOnBackpressureDropDefined_shouldNotThrowException() {
+ // given
+ TestSubscriber testSubscriber = new TestSubscriber<>();
+
+ // when
+ Observable.range(1, 1_000_000).onBackpressureDrop().observeOn(Schedulers.computation()).subscribe(testSubscriber);
+
+ // then
+ testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS);
+ assertTrue(testSubscriber.getOnErrorEvents().size() == 0);
+
+ }
+}
diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaTesting.java b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaTesting.java
new file mode 100644
index 0000000000..91c8ed540e
--- /dev/null
+++ b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaTesting.java
@@ -0,0 +1,98 @@
+package com.baeldung.rxjava;
+
+import org.junit.Test;
+import rx.Observable;
+import rx.observers.TestSubscriber;
+import rx.schedulers.TestScheduler;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.assertThat;
+
+public class RxJavaTesting {
+ @Test
+ public void givenObservable_whenZip_shouldAssertBlockingInASameThread() {
+ // given
+ List letters = Arrays.asList("A", "B", "C", "D", "E");
+ List results = new ArrayList<>();
+ Observable observable = Observable.from(letters).zipWith(Observable.range(1, Integer.MAX_VALUE), (string, index) -> index + "-" + string);
+
+ // when
+ observable.subscribe(results::add);
+
+ // then
+ assertThat(results, notNullValue());
+ assertThat(results, hasSize(5));
+ assertThat(results, hasItems("1-A", "2-B", "3-C", "4-D", "5-E"));
+ }
+
+ @Test
+ public void givenObservable_whenZip_shouldAssertOnTestSubscriber() {
+ // given
+ List letters = Arrays.asList("A", "B", "C", "D", "E");
+ TestSubscriber subscriber = new TestSubscriber<>();
+
+ Observable observable = Observable.from(letters).zipWith(Observable.range(1, Integer.MAX_VALUE), ((string, index) -> index + "-" + string));
+
+ // when
+ observable.subscribe(subscriber);
+
+ // then
+ subscriber.assertCompleted();
+ subscriber.assertNoErrors();
+ subscriber.assertValueCount(5);
+ assertThat(subscriber.getOnNextEvents(), hasItems("1-A", "2-B", "3-C", "4-D", "5-E"));
+ }
+
+ @Test
+ public void givenTestObserver_whenExceptionWasThrowsOnObservable_observerShouldGetError() {
+ // given
+ List letters = Arrays.asList("A", "B", "C", "D", "E");
+ TestSubscriber subscriber = new TestSubscriber<>();
+
+ Observable observable = Observable.from(letters).zipWith(Observable.range(1, Integer.MAX_VALUE), ((string, index) -> index + "-" + string)).concatWith(Observable.error(new RuntimeException("error in Observable")));
+
+ // when
+ observable.subscribe(subscriber);
+
+ // then
+ subscriber.assertError(RuntimeException.class);
+ subscriber.assertNotCompleted();
+ }
+
+ @Test
+ public void givenObservableThatEmitsEventPerSecond_whenUseAdvanceByTime_shouldEmitEventPerSecond() {
+ // given
+ List letters = Arrays.asList("A", "B", "C", "D", "E");
+ TestScheduler scheduler = new TestScheduler();
+ TestSubscriber subscriber = new TestSubscriber<>();
+ Observable tick = Observable.interval(1, TimeUnit.SECONDS, scheduler);
+
+ Observable observable = Observable.from(letters).zipWith(tick, (string, index) -> index + "-" + string);
+
+ observable.subscribeOn(scheduler).subscribe(subscriber);
+
+ // expect
+ subscriber.assertNoValues();
+ subscriber.assertNotCompleted();
+
+ // when
+ scheduler.advanceTimeBy(1, TimeUnit.SECONDS);
+
+ // then
+ subscriber.assertNoErrors();
+ subscriber.assertValueCount(1);
+ subscriber.assertValues("0-A");
+
+ // when
+ scheduler.advanceTimeTo(6, TimeUnit.SECONDS);
+ subscriber.assertCompleted();
+ subscriber.assertNoErrors();
+ subscriber.assertValueCount(5);
+ assertThat(subscriber.getOnNextEvents(), hasItems("0-A", "1-B", "2-C", "3-D", "4-E"));
+ }
+}
diff --git a/spring-5/.gitignore b/spring-5/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/spring-5/.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-5/README.md b/spring-5/README.md
new file mode 100644
index 0000000000..0914388b49
--- /dev/null
+++ b/spring-5/README.md
@@ -0,0 +1,6 @@
+## Spring REST Example Project
+
+###The Course
+The "REST With Spring" Classes: http://bit.ly/restwithspring
+
+### Relevant Articles:
diff --git a/spring-5/pom.xml b/spring-5/pom.xml
new file mode 100644
index 0000000000..ab05918ae4
--- /dev/null
+++ b/spring-5/pom.xml
@@ -0,0 +1,116 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ spring-5
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-5
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.BUILD-SNAPSHOT
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+
+
+
diff --git a/spring-5/src/main/java/com/baeldung/Spring5Application.java b/spring-5/src/main/java/com/baeldung/Spring5Application.java
new file mode 100644
index 0000000000..41b5c1eed1
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/Spring5Application.java
@@ -0,0 +1,13 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Spring5Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Spring5Application.class, args);
+ }
+
+}
diff --git a/spring-5/src/main/java/com/baeldung/persistence/DataSetupBean.java b/spring-5/src/main/java/com/baeldung/persistence/DataSetupBean.java
new file mode 100644
index 0000000000..7936a2b7af
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/persistence/DataSetupBean.java
@@ -0,0 +1,26 @@
+package com.baeldung.persistence;
+
+import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
+
+import java.util.stream.IntStream;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.baeldung.web.Foo;
+
+@Component
+public class DataSetupBean implements InitializingBean {
+
+ @Autowired
+ private FooRepository repo;
+
+ //
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ IntStream.range(1, 20).forEach(i -> repo.save(new Foo(randomAlphabetic(8))));
+ }
+
+}
diff --git a/spring-5/src/main/java/com/baeldung/persistence/FooRepository.java b/spring-5/src/main/java/com/baeldung/persistence/FooRepository.java
new file mode 100644
index 0000000000..1f1e071158
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/persistence/FooRepository.java
@@ -0,0 +1,10 @@
+package com.baeldung.persistence;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+import com.baeldung.web.Foo;
+
+public interface FooRepository extends JpaRepository, JpaSpecificationExecutor {
+
+}
diff --git a/spring-5/src/main/java/com/baeldung/web/Foo.java b/spring-5/src/main/java/com/baeldung/web/Foo.java
new file mode 100644
index 0000000000..c4868a9958
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/web/Foo.java
@@ -0,0 +1,84 @@
+package com.baeldung.web;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Foo {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ 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;
+ }
+
+ //
+
+ @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(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ 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() {
+ return "Foo [name=" + name + "]";
+ }
+
+}
\ No newline at end of file
diff --git a/spring-5/src/main/java/com/baeldung/web/FooController.java b/spring-5/src/main/java/com/baeldung/web/FooController.java
new file mode 100644
index 0000000000..de6928033e
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/web/FooController.java
@@ -0,0 +1,62 @@
+package com.baeldung.web;
+
+import java.util.List;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+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.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.persistence.FooRepository;
+
+@RestController("/foos")
+public class FooController {
+
+ @Autowired
+ private FooRepository repo;
+
+ // API - read
+
+ @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}")
+ @ResponseBody
+ @Validated
+ public Foo findById(@PathVariable @Min(0) final long id) {
+ return repo.findOne(id);
+ }
+
+ @RequestMapping(method = RequestMethod.GET)
+ @ResponseBody
+ public List findAll() {
+ return repo.findAll();
+ }
+
+ @RequestMapping(params = { "page", "size" }, method = RequestMethod.GET)
+ @ResponseBody
+ @Validated
+ public List findPaginated(@RequestParam("page") @Min(0) final int page, @Max(100) @RequestParam("size") final int size) {
+ final Page resultPage = repo.findAll(new PageRequest(page, size));
+ return resultPage.getContent();
+ }
+
+ // API - write
+
+ @RequestMapping(method = RequestMethod.PUT, value = "/foos/{id}")
+ @ResponseStatus(HttpStatus.OK)
+ @ResponseBody
+ public Foo update(@PathVariable("id") final String id, @RequestBody final Foo foo) {
+ return foo;
+ }
+
+}
diff --git a/spring-5/src/main/resources/application.properties b/spring-5/src/main/resources/application.properties
new file mode 100644
index 0000000000..886ea1978b
--- /dev/null
+++ b/spring-5/src/main/resources/application.properties
@@ -0,0 +1,6 @@
+server.port=8081
+
+security.user.name=user
+security.user.password=pass
+
+logging.level.root=INFO
\ No newline at end of file
diff --git a/spring-5/src/test/java/com/baeldung/IntegrationTestExample1.java b/spring-5/src/test/java/com/baeldung/IntegrationTestExample1.java
new file mode 100644
index 0000000000..0a27be4a95
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/IntegrationTestExample1.java
@@ -0,0 +1,29 @@
+package com.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
+public class IntegrationTestExample1 {
+
+ @Test
+ public void test1a() {
+ block(3000);
+ }
+
+ @Test
+ public void test1b() {
+ block(3000);
+ }
+
+ public static void block(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ System.out.println("Thread interrupted");
+ }
+ }
+}
diff --git a/spring-5/src/test/java/com/baeldung/IntegrationTestExample2.java b/spring-5/src/test/java/com/baeldung/IntegrationTestExample2.java
new file mode 100644
index 0000000000..0bb2d47ef5
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/IntegrationTestExample2.java
@@ -0,0 +1,29 @@
+package com.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
+public class IntegrationTestExample2 {
+
+ @Test
+ public void test1a() {
+ block(3000);
+ }
+
+ @Test
+ public void test1b() {
+ block(3000);
+ }
+
+ public static void block(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ System.out.println("Thread Interrupted");
+ }
+ }
+}
diff --git a/spring-5/src/test/java/com/baeldung/ParallelTestExample.java b/spring-5/src/test/java/com/baeldung/ParallelTestExample.java
new file mode 100644
index 0000000000..e73b8d4649
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/ParallelTestExample.java
@@ -0,0 +1,24 @@
+package com.baeldung;
+
+import org.junit.Test;
+import org.junit.experimental.ParallelComputer;
+import org.junit.runner.Computer;
+import org.junit.runner.JUnitCore;
+
+public class ParallelTestExample {
+
+ @Test
+ public void runTests() {
+ final Class>[] classes = { IntegrationTestExample1.class, IntegrationTestExample2.class };
+
+ JUnitCore.runClasses(new Computer(), classes);
+ }
+
+ @Test
+ public void runTestsInParallel() {
+ final Class>[] classes = { IntegrationTestExample1.class, IntegrationTestExample2.class };
+
+ JUnitCore.runClasses(new ParallelComputer(true, true), classes);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-5/src/test/java/com/baeldung/Spring5ApplicationTests.java b/spring-5/src/test/java/com/baeldung/Spring5ApplicationTests.java
new file mode 100644
index 0000000000..537ec56a89
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/Spring5ApplicationTests.java
@@ -0,0 +1,16 @@
+package com.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
+public class Spring5ApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-all/README.md b/spring-all/README.md
index 90ae69300a..a8ea7c58c7 100644
--- a/spring-all/README.md
+++ b/spring-all/README.md
@@ -16,3 +16,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Quick Guide to Spring Controllers](http://www.baeldung.com/spring-controllers)
- [Quick Guide to Spring Bean Scopes](http://www.baeldung.com/spring-bean-scopes)
- [Introduction To Ehcache](http://www.baeldung.com/ehcache)
+- [A Guide to the Spring Task Scheduler](http://www.baeldung.com/spring-task-scheduler)
+- [Guide to Spring Retry](http://www.baeldung.com/spring-retry)
diff --git a/spring-all/pom.xml b/spring-all/pom.xml
index deb6bd6f6a..f28fe1f10d 100644
--- a/spring-all/pom.xml
+++ b/spring-all/pom.xml
@@ -11,7 +11,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-all/src/test/java/org/baeldung/properties/external/ExternalPropertiesWithXmlIntegrationTest.java b/spring-all/src/test/java/org/baeldung/properties/external/ExternalPropertiesWithXmlManualTest.java
similarity index 95%
rename from spring-all/src/test/java/org/baeldung/properties/external/ExternalPropertiesWithXmlIntegrationTest.java
rename to spring-all/src/test/java/org/baeldung/properties/external/ExternalPropertiesWithXmlManualTest.java
index 2ea2822b9a..a8a7bda91c 100644
--- a/spring-all/src/test/java/org/baeldung/properties/external/ExternalPropertiesWithXmlIntegrationTest.java
+++ b/spring-all/src/test/java/org/baeldung/properties/external/ExternalPropertiesWithXmlManualTest.java
@@ -13,7 +13,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ExternalPropertiesWithXmlConfig.class }, loader = AnnotationConfigContextLoader.class)
@Ignore("manual only")
-public class ExternalPropertiesWithXmlIntegrationTest {
+public class ExternalPropertiesWithXmlManualTest {
@Autowired
private Environment env;
diff --git a/spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java b/spring-all/src/test/java/org/baeldung/springretry/SpringRetryIntegrationTest.java
similarity index 96%
rename from spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java
rename to spring-all/src/test/java/org/baeldung/springretry/SpringRetryIntegrationTest.java
index 2f3411957e..d7d0943e6b 100644
--- a/spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java
+++ b/spring-all/src/test/java/org/baeldung/springretry/SpringRetryIntegrationTest.java
@@ -12,7 +12,7 @@ import java.sql.SQLException;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader = AnnotationConfigContextLoader.class)
-public class SpringRetryTest {
+public class SpringRetryIntegrationTest {
@Autowired
private MyService myService;
diff --git a/spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerTest.java b/spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerIntegrationTest.java
similarity index 90%
rename from spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerTest.java
rename to spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerIntegrationTest.java
index cc247cb384..d95857d384 100644
--- a/spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerTest.java
+++ b/spring-all/src/test/java/org/baeldung/taskscheduler/ThreadPoolTaskSchedulerIntegrationTest.java
@@ -8,7 +8,8 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ThreadPoolTaskSchedulerConfig.class }, loader = AnnotationConfigContextLoader.class)
-public class ThreadPoolTaskSchedulerTest {
+public class ThreadPoolTaskSchedulerIntegrationTest {
+
@Test
public void testThreadPoolTaskSchedulerAnnotation() throws InterruptedException {
Thread.sleep(2550);
diff --git a/spring-all/src/test/java/org/baeldung/test/IntegrationTestSuite.java b/spring-all/src/test/java/org/baeldung/test/IntegrationTestSuite.java
index f9845f42a7..470ae9e538 100644
--- a/spring-all/src/test/java/org/baeldung/test/IntegrationTestSuite.java
+++ b/spring-all/src/test/java/org/baeldung/test/IntegrationTestSuite.java
@@ -5,7 +5,7 @@ import org.baeldung.properties.basic.PropertiesWithMultipleXmlsIntegrationTest;
import org.baeldung.properties.basic.PropertiesWithXmlIntegrationTest;
import org.baeldung.properties.external.ExternalPropertiesWithJavaIntegrationTest;
import org.baeldung.properties.external.ExternalPropertiesWithMultipleXmlsIntegrationTest;
-import org.baeldung.properties.external.ExternalPropertiesWithXmlIntegrationTest;
+import org.baeldung.properties.external.ExternalPropertiesWithXmlManualTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@@ -15,7 +15,7 @@ import org.junit.runners.Suite.SuiteClasses;
PropertiesWithXmlIntegrationTest.class,
ExternalPropertiesWithJavaIntegrationTest.class,
ExternalPropertiesWithMultipleXmlsIntegrationTest.class,
- ExternalPropertiesWithXmlIntegrationTest.class,
+ ExternalPropertiesWithXmlManualTest.class,
ExtendedPropertiesWithJavaIntegrationTest.class,
PropertiesWithMultipleXmlsIntegrationTest.class,
})// @formatter:on
diff --git a/spring-amqp/README.md b/spring-amqp/README.md
new file mode 100644
index 0000000000..b0d16c9305
--- /dev/null
+++ b/spring-amqp/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Messaging With Spring AMQP](http://www.baeldung.com/spring-amqp)
diff --git a/spring-boot-servlet/.gitignore b/spring-boot-servlet/.gitignore
new file mode 100644
index 0000000000..60be5b80aa
--- /dev/null
+++ b/spring-boot-servlet/.gitignore
@@ -0,0 +1,4 @@
+/target/
+.settings/
+.classpath
+.project
diff --git a/spring-boot-servlet/README.md b/spring-boot-servlet/README.md
new file mode 100644
index 0000000000..262a11fc36
--- /dev/null
+++ b/spring-boot-servlet/README.md
@@ -0,0 +1,2 @@
+###Relevant Articles:
+- [How to Register a Servlet in a Java Web Application](http://www.baeldung.com/how-to-register-a-servlet-in-a-java-web-application/)
\ No newline at end of file
diff --git a/spring-boot-servlet/pom.xml b/spring-boot-servlet/pom.xml
new file mode 100644
index 0000000000..3818e3468f
--- /dev/null
+++ b/spring-boot-servlet/pom.xml
@@ -0,0 +1,55 @@
+
+ 4.0.0
+ com.baeldung
+ spring-boot-servlet
+ 0.0.1-SNAPSHOT
+ war
+ spring-boot-servlet
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 1.5.1.RELEASE
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ ${tomcat.version}
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-jasper
+ ${tomcat.version}
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+ UTF-8
+ 1.8
+ 8.5.11
+
+
+
diff --git a/spring-boot-servlet/src/main/java/META-INF/MANIFEST.MF b/spring-boot-servlet/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..69ebae1751
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.baeldung.ApplicationMain
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/ApplicationMain.java b/spring-boot-servlet/src/main/java/com/baeldung/ApplicationMain.java
new file mode 100644
index 0000000000..66f2e85999
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/ApplicationMain.java
@@ -0,0 +1,19 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+
+@SpringBootApplication
+public class ApplicationMain extends SpringBootServletInitializer {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ApplicationMain.class, args);
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(ApplicationMain.class);
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/configuration/WebAppInitializer.java b/spring-boot-servlet/src/main/java/com/baeldung/configuration/WebAppInitializer.java
new file mode 100644
index 0000000000..b7e22500f4
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/configuration/WebAppInitializer.java
@@ -0,0 +1,32 @@
+package com.baeldung.configuration;
+
+import org.springframework.web.WebApplicationInitializer;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+import org.springframework.web.context.support.XmlWebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+
+public class WebAppInitializer implements WebApplicationInitializer {
+
+ public void onStartup(ServletContext container) throws ServletException {
+
+ AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
+ ctx.register(WebMvcConfigure.class);
+ ctx.setServletContext(container);
+
+ ServletRegistration.Dynamic servletOne = container.addServlet("SpringProgrammaticDispatcherServlet", new DispatcherServlet(ctx));
+ servletOne.setLoadOnStartup(1);
+ servletOne.addMapping("/");
+
+ XmlWebApplicationContext xctx = new XmlWebApplicationContext();
+ xctx.setConfigLocation("/WEB-INF/context.xml");
+ xctx.setServletContext(container);
+
+ ServletRegistration.Dynamic servletTwo = container.addServlet("SpringProgrammaticXMLDispatcherServlet", new DispatcherServlet(xctx));
+ servletTwo.setLoadOnStartup(1);
+ servletTwo.addMapping("/");
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/configuration/WebMvcConfigure.java b/spring-boot-servlet/src/main/java/com/baeldung/configuration/WebMvcConfigure.java
new file mode 100644
index 0000000000..de9067de6e
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/configuration/WebMvcConfigure.java
@@ -0,0 +1,40 @@
+package com.baeldung.configuration;
+
+import org.springframework.boot.web.support.ErrorPageFilter;
+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.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.resource.PathResourceResolver;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+@Configuration
+public class WebMvcConfigure extends WebMvcConfigurerAdapter {
+
+ @Bean
+ public ViewResolver getViewResolver() {
+ InternalResourceViewResolver resolver = new InternalResourceViewResolver();
+ resolver.setPrefix("/WEB-INF/");
+ resolver.setSuffix(".jsp");
+ return resolver;
+ }
+
+ @Override
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ configurer.enable();
+ }
+
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(3600).resourceChain(true).addResolver(new PathResourceResolver());
+ }
+
+ @Bean
+ public ErrorPageFilter errorPageFilter() {
+ return new ErrorPageFilter();
+ }
+}
+
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/props/Constants.java b/spring-boot-servlet/src/main/java/com/baeldung/props/Constants.java
new file mode 100644
index 0000000000..421401eec7
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/props/Constants.java
@@ -0,0 +1,20 @@
+package com.baeldung.props;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Properties;
+
+public final class Constants {
+
+ @Autowired
+ PropertySourcesLoader psl;
+
+ public static final String breakLine = System.getProperty("line.separator");
+ private static final PropertyLoader pl = new PropertyLoader();
+ private static final Properties mainProps = pl.getProperties("custom.properties");
+ public static final String DISPATCHER_SERVLET_NAME = mainProps.getProperty("dispatcher.servlet.name");
+ public static final String DISPATCHER_SERVLET_MAPPING = mainProps.getProperty("dispatcher.servlet.mapping");
+ private final String EXAMPLE_SERVLET_NAME = psl.getProperty("example.servlet.name");
+ private final String EXAMPLE_SERVLET_MAPPING = psl.getProperty("example.servlet.mapping");
+
+}
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/props/PropertyLoader.java b/spring-boot-servlet/src/main/java/com/baeldung/props/PropertyLoader.java
new file mode 100644
index 0000000000..5d890d96fa
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/props/PropertyLoader.java
@@ -0,0 +1,27 @@
+package com.baeldung.props;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class PropertyLoader {
+ private static final Logger log = LoggerFactory.getLogger(PropertyLoader.class);
+
+ public Properties getProperties(String file) {
+ Properties prop = new Properties();
+ InputStream input = null;
+ try {
+ input = getClass().getResourceAsStream(file);
+ prop.load(input);
+ if (input != null) {
+ input.close();
+ }
+ } catch (IOException ex) {
+ log.error("IOException: " + ex);
+ }
+ return prop;
+ }
+}
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/props/PropertySourcesLoader.java b/spring-boot-servlet/src/main/java/com/baeldung/props/PropertySourcesLoader.java
new file mode 100644
index 0000000000..8c7b3a4af5
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/props/PropertySourcesLoader.java
@@ -0,0 +1,23 @@
+package com.baeldung.props;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.ConfigurableEnvironment;
+
+@Configuration
+@ComponentScan(basePackages = { "com.baeldung.*" })
+@PropertySource("classpath:custom.properties") public class PropertySourcesLoader {
+
+ private static final Logger log = LoggerFactory.getLogger(PropertySourcesLoader.class);
+
+ @Autowired
+ ConfigurableEnvironment env;
+
+ public String getProperty(String key) {
+ return env.getProperty(key);
+ }
+}
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/servlets/GenericCustomServlet.java b/spring-boot-servlet/src/main/java/com/baeldung/servlets/GenericCustomServlet.java
new file mode 100644
index 0000000000..c6543c9eef
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/servlets/GenericCustomServlet.java
@@ -0,0 +1,18 @@
+package com.baeldung.servlets;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class GenericCustomServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ out.println("Hello World
");
+ }
+}
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/servlets/javaee/AnnotationServlet.java b/spring-boot-servlet/src/main/java/com/baeldung/servlets/javaee/AnnotationServlet.java
new file mode 100644
index 0000000000..d971e68cfa
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/servlets/javaee/AnnotationServlet.java
@@ -0,0 +1,20 @@
+package com.baeldung.servlets.javaee;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@WebServlet(name = "AnnotationServlet",
+ description = "Example Servlet Using Annotations",
+ urlPatterns = { "/annotationservlet" })
+public class AnnotationServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ request.getRequestDispatcher("/annotationservlet.jsp").forward(request, response);
+ }
+}
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/servlets/javaee/EEWebXmlServlet.java b/spring-boot-servlet/src/main/java/com/baeldung/servlets/javaee/EEWebXmlServlet.java
new file mode 100644
index 0000000000..4209e815cd
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/servlets/javaee/EEWebXmlServlet.java
@@ -0,0 +1,20 @@
+package com.baeldung.servlets.javaee;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public class EEWebXmlServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ response.setContentType("text/html");
+ PrintWriter out = response.getWriter();
+ out.println("Hello World
");
+ }
+}
\ No newline at end of file
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/servlets/springboot/SpringRegistrationBeanServlet.java b/spring-boot-servlet/src/main/java/com/baeldung/servlets/springboot/SpringRegistrationBeanServlet.java
new file mode 100644
index 0000000000..4a34465894
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/servlets/springboot/SpringRegistrationBeanServlet.java
@@ -0,0 +1,19 @@
+package com.baeldung.servlets.springboot;
+
+import com.baeldung.servlets.GenericCustomServlet;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class SpringRegistrationBeanServlet {
+
+ @Bean
+ public ServletRegistrationBean genericCustomServlet() {
+ ServletRegistrationBean bean = new ServletRegistrationBean(new GenericCustomServlet(), "/springregistrationbeanservlet/*");
+ bean.setLoadOnStartup(1);
+ return bean;
+ }
+}
+
+
diff --git a/spring-boot-servlet/src/main/java/com/baeldung/servlets/springboot/embedded/EmbeddedTomcatExample.java b/spring-boot-servlet/src/main/java/com/baeldung/servlets/springboot/embedded/EmbeddedTomcatExample.java
new file mode 100644
index 0000000000..b2458f33c7
--- /dev/null
+++ b/spring-boot-servlet/src/main/java/com/baeldung/servlets/springboot/embedded/EmbeddedTomcatExample.java
@@ -0,0 +1,16 @@
+package com.baeldung.servlets.springboot.embedded;
+
+import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
+import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class EmbeddedTomcatExample {
+
+ @Bean
+ public EmbeddedServletContainerFactory servletContainer() {
+ TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
+ return tomcat;
+ }
+}
diff --git a/spring-boot-servlet/src/main/resources/application.properties b/spring-boot-servlet/src/main/resources/application.properties
new file mode 100644
index 0000000000..4e9e2b4cf1
--- /dev/null
+++ b/spring-boot-servlet/src/main/resources/application.properties
@@ -0,0 +1,10 @@
+#Server Configuration
+#server.port=8080
+#server.context-path=/javabootdata
+#Resource Handling
+#spring.resources.static-locations=classpath:/WEB-INF/resources
+#spring.mvc.view.prefix=/WEB-INF/
+#spring.mvc.view.suffix=.jsp
+#spring.resources.cache-period=3600
+servlet.name=dispatcherExample
+servlet.mapping=/dispatcherExampleURL
\ No newline at end of file
diff --git a/spring-boot-servlet/src/main/resources/custom.properties b/spring-boot-servlet/src/main/resources/custom.properties
new file mode 100644
index 0000000000..34f31bcd50
--- /dev/null
+++ b/spring-boot-servlet/src/main/resources/custom.properties
@@ -0,0 +1,4 @@
+dispatcher.servlet.name=dispatcherExample
+dispatcher.servlet.mapping=/dispatcherExampleURL
+example.servlet.name=dispatcherExample
+example.servlet.mapping=/dispatcherExampleURL
\ No newline at end of file
diff --git a/spring-boot-servlet/src/main/webapp/WEB-INF/context.xml b/spring-boot-servlet/src/main/webapp/WEB-INF/context.xml
new file mode 100644
index 0000000000..263bed4430
--- /dev/null
+++ b/spring-boot-servlet/src/main/webapp/WEB-INF/context.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-servlet/src/main/webapp/WEB-INF/dispatcher.xml b/spring-boot-servlet/src/main/webapp/WEB-INF/dispatcher.xml
new file mode 100644
index 0000000000..ade8e66777
--- /dev/null
+++ b/spring-boot-servlet/src/main/webapp/WEB-INF/dispatcher.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-servlet/src/main/webapp/WEB-INF/web.xml b/spring-boot-servlet/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..60a4b079de
--- /dev/null
+++ b/spring-boot-servlet/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,40 @@
+
+
+ JSP
+
+ index.html
+ index.htm
+ index.jsp
+
+
+
+
+ EEWebXmlServlet
+ com.baeldung.servlets.javaee.EEWebXmlServlet
+
+
+
+ EEWebXmlServlet
+ /eewebxmlservlet
+
+
+
+
+ SpringBootWebXmlServlet
+ org.springframework.web.servlet.DispatcherServlet
+
+ contextConfigLocation
+ /WEB-INF/dispatcher.xml
+
+ 1
+
+
+
+ SpringBootWebXmlServlet
+ /
+
+
+
+
diff --git a/spring-boot-servlet/src/main/webapp/annotationservlet.jsp b/spring-boot-servlet/src/main/webapp/annotationservlet.jsp
new file mode 100644
index 0000000000..f21748df50
--- /dev/null
+++ b/spring-boot-servlet/src/main/webapp/annotationservlet.jsp
@@ -0,0 +1 @@
+Annotation Servlet!
\ No newline at end of file
diff --git a/spring-boot-servlet/src/main/webapp/index.jsp b/spring-boot-servlet/src/main/webapp/index.jsp
new file mode 100644
index 0000000000..e534282777
--- /dev/null
+++ b/spring-boot-servlet/src/main/webapp/index.jsp
@@ -0,0 +1 @@
+Hello!
\ No newline at end of file
diff --git a/spring-boot/README.MD b/spring-boot/README.MD
index 05173ef318..d0a02c69fc 100644
--- a/spring-boot/README.MD
+++ b/spring-boot/README.MD
@@ -7,3 +7,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [A Guide to Spring in Eclipse STS](http://www.baeldung.com/eclipse-sts-spring)
- [Introduction to WebJars](http://www.baeldung.com/maven-webjars)
- [Create a Fat Jar App with Spring Boot](http://www.baeldung.com/deployable-fat-jar-spring-boot)
+- [The @ServletComponentScan Annotation in Spring Boot](http://www.baeldung.com/spring-servletcomponentscan)
+- [A Custom Data Binder in Spring MVC](http://www.baeldung.com/spring-mvc-custom-data-binder)
+- [Intro to Building an Application with Spring Boot](http://www.baeldung.com/intro-to-spring-boot)
diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml
index 68a5857865..e77ab10aff 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
@@ -12,8 +12,8 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
-
+ 1.5.1.RELEASE
+
@@ -87,6 +87,14 @@
jquery
${jquery.version}
+
+
+ org.apache.tomcat
+ tomcat-servlet-api
+ ${tomee-servlet-api.version}
+ provided
+
+
@@ -166,7 +174,7 @@
- json
+ json
@@ -186,6 +194,7 @@
3.1.1
3.3.7-1
3.1.7
+ 8.5.11
diff --git a/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java
new file mode 100644
index 0000000000..b4d416dd96
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java
@@ -0,0 +1,25 @@
+package com.baeldung.annotation.servletcomponentscan;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+
+/**
+ * using the following annotations are equivalent:
+ *
+ * @ServletComponentScan
+ *
+ * @ServletComponentScan(basePackages = "com.baeldung.annotation.servletcomponentscan.components")
+ *
+ * @ServletComponentScan(basePackageClasses = {AttrListener.class, HelloFilter.class, HelloServlet.class, EchoServlet.class})
+ *
+ */
+@SpringBootApplication
+@ServletComponentScan("com.baeldung.annotation.servletcomponentscan.components")
+public class SpringBootAnnotatedApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootAnnotatedApp.class, args);
+ }
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java
new file mode 100644
index 0000000000..8a39078aac
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java
@@ -0,0 +1,13 @@
+package com.baeldung.annotation.servletcomponentscan;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan(basePackages = "com.baeldung.annotation.servletcomponentscan.components")
+public class SpringBootPlainApp {
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java
new file mode 100644
index 0000000000..bad39c52c4
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java
@@ -0,0 +1,23 @@
+package com.baeldung.annotation.servletcomponentscan.components;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+@WebListener
+public class AttrListener implements ServletContextListener {
+
+ @Override
+ public void contextInitialized(ServletContextEvent servletContextEvent) {
+ servletContextEvent
+ .getServletContext()
+ .setAttribute("servlet-context-attr", "test");
+ System.out.println("context init");
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent servletContextEvent) {
+ System.out.println("context destroy");
+ }
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java
new file mode 100644
index 0000000000..3419cd0eaf
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java
@@ -0,0 +1,29 @@
+package com.baeldung.annotation.servletcomponentscan.components;
+
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+
+@WebServlet(name = "echo servlet", urlPatterns = "/echo")
+public class EchoServlet extends HttpServlet {
+
+ @Override
+ public void doPost(HttpServletRequest request, HttpServletResponse response) {
+ try {
+ Path path = File
+ .createTempFile("echo", "tmp")
+ .toPath();
+ Files.copy(request.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
+ Files.copy(path, response.getOutputStream());
+ Files.delete(path);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java
new file mode 100644
index 0000000000..dc2368c5b2
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java
@@ -0,0 +1,32 @@
+package com.baeldung.annotation.servletcomponentscan.components;
+
+import javax.servlet.*;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.annotation.WebInitParam;
+import java.io.IOException;
+
+@WebFilter(urlPatterns = "/hello", description = "a filter for hello servlet", initParams = { @WebInitParam(name = "msg", value = "filtering ") }, filterName = "hello filter", servletNames = { "echo servlet" })
+public class HelloFilter implements Filter {
+
+ private FilterConfig filterConfig;
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ System.out.println("filter init");
+ this.filterConfig = filterConfig;
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+ servletResponse
+ .getOutputStream()
+ .print(filterConfig.getInitParameter("msg"));
+ filterChain.doFilter(servletRequest, servletResponse);
+ }
+
+ @Override
+ public void destroy() {
+ System.out.println("filter destroy");
+ }
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java
new file mode 100644
index 0000000000..aeae7aecc9
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java
@@ -0,0 +1,32 @@
+package com.baeldung.annotation.servletcomponentscan.components;
+
+import javax.servlet.ServletConfig;
+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;
+import java.io.IOException;
+
+@WebServlet(urlPatterns = "/hello", initParams = { @WebInitParam(name = "msg", value = "hello")})
+public class HelloServlet extends HttpServlet {
+
+ private ServletConfig servletConfig;
+
+ @Override
+ public void init(ServletConfig servletConfig){
+ this.servletConfig = servletConfig;
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response) {
+ try {
+ response
+ .getOutputStream()
+ .write(servletConfig.getInitParameter("msg").getBytes());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/utils/Application.java b/spring-boot/src/main/java/com/baeldung/utils/Application.java
new file mode 100644
index 0000000000..a3d9f9130c
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/utils/Application.java
@@ -0,0 +1,18 @@
+package com.baeldung.utils;
+
+import javax.annotation.security.RolesAllowed;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan(basePackages="com.baeldung.utils")
+public class Application {
+
+ @RolesAllowed("*")
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/utils/controller/UtilsController.java b/spring-boot/src/main/java/com/baeldung/utils/controller/UtilsController.java
new file mode 100644
index 0000000000..7b4827cdf2
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/utils/controller/UtilsController.java
@@ -0,0 +1,49 @@
+package com.baeldung.utils.controller;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.ServletRequestBindingException;
+import org.springframework.web.bind.ServletRequestUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.util.WebUtils;
+
+@Controller
+public class UtilsController {
+
+ @GetMapping("/utils")
+ public String webUtils(Model model) {
+ return "utils";
+ }
+
+ @PostMapping("/setParam")
+ public String post(HttpServletRequest request, Model model) {
+ String param = ServletRequestUtils.getStringParameter(request, "param", "DEFAULT");
+
+// Long param = ServletRequestUtils.getLongParameter(request, "param",1L);
+// boolean param = ServletRequestUtils.getBooleanParameter(request, "param", true);
+// double param = ServletRequestUtils.getDoubleParameter(request, "param", 1000);
+// float param = ServletRequestUtils.getFloatParameter(request, "param", (float) 1.00);
+// int param = ServletRequestUtils.getIntParameter(request, "param", 100);
+
+// try {
+// ServletRequestUtils.getRequiredStringParameter(request, "param");
+// } catch (ServletRequestBindingException e) {
+// e.printStackTrace();
+// }
+
+ WebUtils.setSessionAttribute(request, "parameter", param);
+ model.addAttribute("parameter", "You set: "+(String) WebUtils.getSessionAttribute(request, "parameter"));
+ return "utils";
+ }
+
+ @GetMapping("/other")
+ public String other(HttpServletRequest request, Model model) {
+ String param = (String) WebUtils.getSessionAttribute(request, "parameter");
+ model.addAttribute("parameter", param);
+ return "other";
+ }
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/TestController.java b/spring-boot/src/main/java/com/baeldung/webjar/TestController.java
similarity index 91%
rename from spring-boot/src/main/java/com/baeldung/TestController.java
rename to spring-boot/src/main/java/com/baeldung/webjar/TestController.java
index 0e28ca67f8..e8e7fd5ce9 100644
--- a/spring-boot/src/main/java/com/baeldung/TestController.java
+++ b/spring-boot/src/main/java/com/baeldung/webjar/TestController.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.webjar;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
diff --git a/spring-boot/src/main/java/com/baeldung/WebjarsdemoApplication.java b/spring-boot/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java
similarity index 77%
rename from spring-boot/src/main/java/com/baeldung/WebjarsdemoApplication.java
rename to spring-boot/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java
index 35490131c6..d2135754c9 100644
--- a/spring-boot/src/main/java/com/baeldung/WebjarsdemoApplication.java
+++ b/spring-boot/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java
@@ -1,7 +1,8 @@
-package com.baeldung;
+package com.baeldung.webjar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
public class WebjarsdemoApplication {
diff --git a/spring-boot/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java b/spring-boot/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java
index 78680baf7d..723afddd06 100644
--- a/spring-boot/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java
+++ b/spring-boot/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java
@@ -1,8 +1,8 @@
package org.baeldung.common.error;
-import javax.servlet.Servlet;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
-import org.springframework.boot.context.embedded.ServletRegistrationBean;
+import javax.servlet.Servlet;
public class SpringHelloServletRegistrationBean extends ServletRegistrationBean {
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 97130bed6a..9b5a0aa948 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
@@ -2,7 +2,7 @@ package org.baeldung.common.properties;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
-import org.springframework.boot.context.embedded.ErrorPage;
+import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
diff --git a/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java b/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
index 7d6293056a..7d1ad7d899 100644
--- a/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
+++ b/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
@@ -54,8 +54,6 @@ public class GenericEntityController {
@GetMapping("/entity/findbyversion")
public ResponseEntity findByVersion(@Version String version) {
- return version != null
- ? new ResponseEntity(entityList.stream().findFirst().get(), HttpStatus.OK)
- : new ResponseEntity(HttpStatus.NOT_FOUND);
+ return version != null ? new ResponseEntity(entityList.stream().findFirst().get(), HttpStatus.OK) : new ResponseEntity(HttpStatus.NOT_FOUND);
}
}
diff --git a/spring-boot/src/main/resources/templates/other.html b/spring-boot/src/main/resources/templates/other.html
new file mode 100644
index 0000000000..d13373f9fe
--- /dev/null
+++ b/spring-boot/src/main/resources/templates/other.html
@@ -0,0 +1,16 @@
+
+
+
+
+Spring Utils Demo
+
+
+
+ Parameter set by you:
+
+
\ No newline at end of file
diff --git a/spring-boot/src/main/resources/templates/utils.html b/spring-boot/src/main/resources/templates/utils.html
new file mode 100644
index 0000000000..93030f424f
--- /dev/null
+++ b/spring-boot/src/main/resources/templates/utils.html
@@ -0,0 +1,23 @@
+
+
+
+
+Spring Utils Demo
+
+
+
+
+
+Another Page
+
+
\ No newline at end of file
diff --git a/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java
new file mode 100644
index 0000000000..8d5eb56bf4
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java
@@ -0,0 +1,65 @@
+package com.baeldung.annotation.servletcomponentscan;
+
+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.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+
+import static org.junit.Assert.*;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootAnnotatedApp.class)
+@AutoConfigureMockMvc
+@TestPropertySource(properties = { "security.basic.enabled=false" })
+public class SpringBootWithServletComponentIntegrationTest {
+
+ @Autowired private ServletContext servletContext;
+
+ @Test
+ public void givenServletContext_whenAccessAttrs_thenFoundAttrsPutInServletListner() {
+ assertNotNull(servletContext);
+ assertNotNull(servletContext.getAttribute("servlet-context-attr"));
+ assertEquals("test", servletContext.getAttribute("servlet-context-attr"));
+ }
+
+ @Test
+ public void givenServletContext_whenCheckHelloFilterMappings_thenCorrect() {
+ assertNotNull(servletContext);
+ FilterRegistration filterRegistration = servletContext.getFilterRegistration("hello filter");
+
+ assertNotNull(filterRegistration);
+ assertTrue(filterRegistration
+ .getServletNameMappings()
+ .contains("echo servlet"));
+ }
+
+ @Autowired private TestRestTemplate restTemplate;
+
+ @Test
+ public void givenServletFilter_whenGetHello_thenRequestFiltered() {
+ ResponseEntity responseEntity = this.restTemplate.getForEntity("/hello", String.class);
+ assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
+ assertEquals("filtering hello", responseEntity.getBody());
+ }
+
+ @Test
+ public void givenFilterAndServlet_whenPostEcho_thenEchoFiltered() {
+ ResponseEntity responseEntity = this.restTemplate.postForEntity("/echo", "echo", String.class);
+ assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
+ assertEquals("filtering echo", responseEntity.getBody());
+ }
+
+
+
+}
+
+
diff --git a/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java
new file mode 100644
index 0000000000..64507ad02c
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java
@@ -0,0 +1,50 @@
+package com.baeldung.annotation.servletcomponentscan;
+
+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.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+
+import static org.junit.Assert.*;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootPlainApp.class)
+@AutoConfigureMockMvc
+@TestPropertySource(properties = { "security.basic.enabled=false" })
+public class SpringBootWithoutServletComponentIntegrationTest {
+
+ @Autowired private ServletContext servletContext;
+
+ @Autowired private TestRestTemplate restTemplate;
+
+ @Test
+ public void givenServletContext_whenAccessAttrs_thenNotFound() {
+ assertNull(servletContext.getAttribute("servlet-context-attr"));
+ }
+
+ @Test
+ public void givenServletFilter_whenGetHello_thenEndpointNotFound() {
+ ResponseEntity responseEntity = this.restTemplate.getForEntity("/hello", String.class);
+ assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode());
+ }
+
+ @Test
+ public void givenServletContext_whenCheckFilterMappings_thenEmpty() {
+ assertNotNull(servletContext);
+ FilterRegistration filterRegistration = servletContext.getFilterRegistration("hello filter");
+
+ assertNull(filterRegistration);
+ }
+
+}
+
+
diff --git a/spring-boot/src/test/java/com/baeldung/intro/AppTest.java b/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java
similarity index 89%
rename from spring-boot/src/test/java/com/baeldung/intro/AppTest.java
rename to spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java
index 749fe68838..af46fe0423 100644
--- a/spring-boot/src/test/java/com/baeldung/intro/AppTest.java
+++ b/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java
@@ -1,39 +1,41 @@
-package com.baeldung.intro;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-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.AutoConfigureMockMvc;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest
-@AutoConfigureMockMvc
-public class AppTest {
-
- @Autowired
- private MockMvc mvc;
-
- @Test
- public void getIndex() throws Exception {
- mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
- .andExpect(status().isOk())
- .andExpect(content().string(equalTo("Index Page")));
- }
-
- @Test
- public void getLocal() throws Exception {
- mvc.perform(MockMvcRequestBuilders.get("/local").accept(MediaType.APPLICATION_JSON))
- .andExpect(status().isOk())
- .andExpect(content().string(equalTo("/local")));
- }
-
+package com.baeldung.intro;
+
+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.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@AutoConfigureMockMvc
+@TestPropertySource(properties = { "security.basic.enabled=false" })
+public class AppLiveTest {
+
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void getIndex() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("Index Page")));
+ }
+
+ @Test
+ public void getLocal() throws Exception {
+ mvc.perform(MockMvcRequestBuilders.get("/local").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string(equalTo("/local")));
+ }
+
}
\ No newline at end of file
diff --git a/spring-boot/src/test/java/com/baeldung/utils/UtilsControllerTest.java b/spring-boot/src/test/java/com/baeldung/utils/UtilsControllerTest.java
new file mode 100644
index 0000000000..7aed45dbb0
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/utils/UtilsControllerTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.utils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.MockitoAnnotations;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+
+import com.baeldung.utils.controller.UtilsController;
+
+public class UtilsControllerTest {
+
+ @InjectMocks
+ private UtilsController utilsController;
+
+ private MockMvc mockMvc;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ this.mockMvc = MockMvcBuilders.standaloneSetup(utilsController)
+ .build();
+
+ }
+
+ @Test
+ public void givenParameter_setRequestParam_andSetSessionAttribute() throws Exception {
+ String param = "testparam";
+ this.mockMvc.perform(
+ post("/setParam")
+ .param("param", param)
+ .sessionAttr("parameter", param))
+ .andExpect(status().isOk());
+ }
+
+}
diff --git a/spring-boot/src/test/java/com/baeldung/WebjarsdemoApplicationIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java
similarity index 68%
rename from spring-boot/src/test/java/com/baeldung/WebjarsdemoApplicationIntegrationTest.java
rename to spring-boot/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java
index 3558682b97..d6e71dcf6b 100644
--- a/spring-boot/src/test/java/com/baeldung/WebjarsdemoApplicationIntegrationTest.java
+++ b/spring-boot/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java
@@ -1,13 +1,13 @@
-package com.baeldung;
+package com.baeldung.webjar;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
-@SpringApplicationConfiguration(classes = WebjarsdemoApplication.class)
+@SpringBootTest(classes = WebjarsdemoApplication.class)
@WebAppConfiguration
public class WebjarsdemoApplicationIntegrationTest {
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java
index 8cdcdb2216..87c59a4662 100644
--- a/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java
@@ -9,7 +9,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.SpringApplicationConfiguration;
+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;
@@ -22,7 +22,7 @@ import org.springframework.web.context.WebApplicationContext;
import java.nio.charset.Charset;
@RunWith(SpringJUnit4ClassRunner.class)
-@SpringApplicationConfiguration(classes = Application.class)
+@SpringBootTest(classes = Application.class)
@WebAppConfiguration
public class SpringBootApplicationIntegrationTest {
@Autowired
@@ -45,29 +45,22 @@ public class SpringBootApplicationIntegrationTest {
public void givenRequestHasBeenMade_whenMeetsFindByDateOfGivenConditions_thenCorrect() throws Exception {
MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
- mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbydate/{date}", "2011-12-03T10:15:30"))
- .andExpect(MockMvcResultMatchers.status().isOk())
- .andExpect(MockMvcResultMatchers.content().contentType(contentType))
- .andExpect(jsonPath("$.id", equalTo(1)));
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbydate/{date}", "2011-12-03T10:15:30")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().contentType(contentType))
+ .andExpect(jsonPath("$.id", equalTo(1)));
}
@Test
public void givenRequestHasBeenMade_whenMeetsFindByModeOfGivenConditions_thenCorrect() throws Exception {
MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
- mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbymode/{mode}", Modes.ALPHA.name()))
- .andExpect(MockMvcResultMatchers.status().isOk())
- .andExpect(MockMvcResultMatchers.content().contentType(contentType))
- .andExpect(jsonPath("$.id", equalTo(1)));
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbymode/{mode}", Modes.ALPHA.name())).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().contentType(contentType)).andExpect(jsonPath("$.id", equalTo(1)));
}
@Test
public void givenRequestHasBeenMade_whenMeetsFindByVersionOfGivenConditions_thenCorrect() throws Exception {
MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
- mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbyversion").header("Version", "1.0.0"))
- .andExpect(MockMvcResultMatchers.status().isOk())
- .andExpect(MockMvcResultMatchers.content().contentType(contentType))
- .andExpect(jsonPath("$.id", equalTo(1)));
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/findbyversion").header("Version", "1.0.0")).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.content().contentType(contentType))
+ .andExpect(jsonPath("$.id", equalTo(1)));
}
}
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java
index 233684bc24..d4b19e6a1d 100644
--- a/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java
@@ -5,14 +5,14 @@ import org.baeldung.repository.GenericEntityRepository;
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.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringJUnit4ClassRunner.class)
-@SpringApplicationConfiguration(classes = Application.class)
+@SpringBootTest(classes = Application.class)
public class SpringBootJPAIntegrationTest {
@Autowired
private GenericEntityRepository genericEntityRepository;
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java
index cec25f20f9..10e3d6d60b 100644
--- a/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java
@@ -5,7 +5,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.SpringApplicationConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -23,7 +23,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
-@SpringApplicationConfiguration(classes = Application.class)
+@SpringBootTest(classes = Application.class)
public class SpringBootMailIntegrationTest {
@Autowired
private JavaMailSender javaMailSender;
diff --git a/spring-cloud-data-flow/batch-job/pom.xml b/spring-cloud-data-flow/batch-job/pom.xml
index 3d05732027..5e519e9a35 100644
--- a/spring-cloud-data-flow/batch-job/pom.xml
+++ b/spring-cloud-data-flow/batch-job/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud-data-flow/data-flow-server/pom.xml b/spring-cloud-data-flow/data-flow-server/pom.xml
index b1f920c94e..1ed2d4fb74 100644
--- a/spring-cloud-data-flow/data-flow-server/pom.xml
+++ b/spring-cloud-data-flow/data-flow-server/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud-data-flow/data-flow-shell/pom.xml b/spring-cloud-data-flow/data-flow-shell/pom.xml
index 55fa995052..d3bd297152 100644
--- a/spring-cloud-data-flow/data-flow-shell/pom.xml
+++ b/spring-cloud-data-flow/data-flow-shell/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud-data-flow/log-sink/pom.xml b/spring-cloud-data-flow/log-sink/pom.xml
index 6443ed88c8..dc21132b9f 100644
--- a/spring-cloud-data-flow/log-sink/pom.xml
+++ b/spring-cloud-data-flow/log-sink/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud-data-flow/time-processor/pom.xml b/spring-cloud-data-flow/time-processor/pom.xml
index d7553b110f..51a66014e0 100644
--- a/spring-cloud-data-flow/time-processor/pom.xml
+++ b/spring-cloud-data-flow/time-processor/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud-data-flow/time-source/pom.xml b/spring-cloud-data-flow/time-source/pom.xml
index 2523dfabea..57933c2833 100644
--- a/spring-cloud-data-flow/time-source/pom.xml
+++ b/spring-cloud-data-flow/time-source/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties b/spring-cloud/spring-cloud-bootstrap/application-config/book-service.properties
similarity index 91%
rename from spring-cloud/spring-cloud-bootstrap/application-config/resource.properties
rename to spring-cloud/spring-cloud-bootstrap/application-config/book-service.properties
index 9fb610d655..e1244a0cf0 100644
--- a/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties
+++ b/spring-cloud/spring-cloud-bootstrap/application-config/book-service.properties
@@ -1,4 +1,4 @@
-spring.application.name=resource
+spring.application.name=book-service
server.port=8083
resource.returnString=hello cloud
diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties b/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties
index 6f52a59db9..09f7f3bf4a 100644
--- a/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties
+++ b/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties
@@ -6,9 +6,13 @@ eureka.client.registryFetchIntervalSeconds = 5
management.security.sessions=always
-zuul.routes.resource.path=/resource/**
-zuul.routes.resource.sensitive-headers=Set-Cookie,Authorization
-hystrix.command.resource.execution.isolation.thread.timeoutInMilliseconds=600000
+zuul.routes.book-service.path=/book-service/**
+zuul.routes.book-service.sensitive-headers=Set-Cookie,Authorization
+hystrix.command.book-service.execution.isolation.thread.timeoutInMilliseconds=600000
+
+zuul.routes.rating-service.path=/rating-service/**
+zuul.routes.rating-service.sensitive-headers=Set-Cookie,Authorization
+hystrix.command.rating-service.execution.isolation.thread.timeoutInMilliseconds=600000
zuul.routes.discovery.path=/discovery/**
zuul.routes.discovery.sensitive-headers=Set-Cookie,Authorization
diff --git a/spring-cloud/spring-cloud-bootstrap/application-config/rating-service.properties b/spring-cloud/spring-cloud-bootstrap/application-config/rating-service.properties
new file mode 100644
index 0000000000..4817d12c83
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/application-config/rating-service.properties
@@ -0,0 +1,17 @@
+spring.application.name=rating-service
+server.port=8084
+
+resource.returnString=hello cloud
+resource.user.returnString=hello cloud user
+resource.admin.returnString=hello cloud admin
+
+eureka.client.region = default
+eureka.client.registryFetchIntervalSeconds = 5
+
+management.security.sessions=never
+
+logging.level.org.springframework.web.=debug
+logging.level.org.springframework.security=debug
+
+spring.redis.host=localhost
+spring.redis.port=6379
diff --git a/spring-cloud/spring-cloud-bootstrap/config/pom.xml b/spring-cloud/spring-cloud-bootstrap/config/pom.xml
index 24d054a87b..2c8ad65102 100644
--- a/spring-cloud/spring-cloud-bootstrap/config/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/config/pom.xml
@@ -10,7 +10,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml
index be3bfbb0be..40a186350c 100644
--- a/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml
@@ -10,7 +10,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml
index 9186f12226..044730ba22 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml
@@ -10,7 +10,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java
index 60dccf9042..9e5c424403 100644
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/bootstrap/gateway/SecurityConfig.java
@@ -22,14 +22,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
- .antMatchers("/resource/hello/cloud").permitAll()
+ .antMatchers("/book-service/books").permitAll()
.antMatchers("/eureka/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout().permitAll()
- .logoutSuccessUrl("/resource/hello/cloud").permitAll()
+ .logoutSuccessUrl("/book-service/books").permitAll()
.and()
.csrf()
.disable();
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplicationLiveTest.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplicationLiveTest.java
deleted file mode 100644
index cea431d461..0000000000
--- a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/GatewayApplicationLiveTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.baeldung.spring.cloud.bootstrap.gateway;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.springframework.boot.test.web.client.TestRestTemplate;
-import org.springframework.http.*;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-
-public class GatewayApplicationLiveTest {
-
- @Test
- public void testAccess() throws Exception {
- TestRestTemplate testRestTemplate = new TestRestTemplate();
- String testUrl = "http://localhost:8080";
-
- ResponseEntity response = testRestTemplate.getForEntity(testUrl + "/resource/hello/cloud", String.class);
- Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
- Assert.assertEquals("hello cloud", response.getBody());
-
- //try the protected resource and confirm the redirect to login
- response = testRestTemplate.getForEntity(testUrl + "/resource/hello/user", String.class);
- Assert.assertEquals(HttpStatus.FOUND, response.getStatusCode());
- Assert.assertEquals("http://localhost:8080/login", response.getHeaders().get("Location").get(0));
-
- //login as user/password
- MultiValueMap form = new LinkedMultiValueMap<>();
- form.add("username", "user");
- form.add("password", "password");
- response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class);
-
- //extract the session from the cookie and propagate it to the next request
- String sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0];
- HttpHeaders headers = new HttpHeaders();
- headers.add("Cookie", sessionCookie);
- HttpEntity httpEntity = new HttpEntity<>(headers);
-
- //request the protected resource
- response = testRestTemplate.exchange(testUrl + "/resource/hello/user", HttpMethod.GET, httpEntity, String.class);
- Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
- Assert.assertEquals("hello cloud user", response.getBody());
-
- //request the admin protected resource to determine it is still protected
- response = testRestTemplate.exchange(testUrl + "/resource/hello/admin", HttpMethod.GET, httpEntity, String.class);
- Assert.assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode());
-
- //login as the admin
- form.clear();
- form.add("username", "admin");
- form.add("password", "admin");
- response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class);
-
- //extract the session from the cookie and propagate it to the next request
- sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0];
- headers = new HttpHeaders();
- headers.add("Cookie", sessionCookie);
- httpEntity = new HttpEntity<>(headers);
-
- //request the protected resource
- response = testRestTemplate.exchange(testUrl + "/resource/hello/admin", HttpMethod.GET, httpEntity, String.class);
- Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
- Assert.assertEquals("hello cloud admin", response.getBody());
-
- //request the discovery resources as the admin
- response = testRestTemplate.exchange(testUrl + "/discovery", HttpMethod.GET, httpEntity, String.class);
- Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
- }
-
-}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/IntegrationLiveTest.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/IntegrationLiveTest.java
new file mode 100644
index 0000000000..47a4b744eb
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/gateway/src/test/java/com/baeldung/spring/cloud/bootstrap/gateway/IntegrationLiveTest.java
@@ -0,0 +1,201 @@
+package com.baeldung.spring.cloud.bootstrap.gateway;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import org.apache.http.entity.ContentType;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.*;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+public class IntegrationLiveTest {
+
+ private TestRestTemplate testRestTemplate = new TestRestTemplate();
+ private String testUrl = "http://localhost:8080";
+
+ @Test
+ public void testAccess() throws Exception {
+ ResponseEntity response = testRestTemplate.getForEntity(testUrl + "/book-service/books", String.class);
+ Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
+ Assert.assertNotNull(response.getBody());
+
+ //try the protected resource and confirm the redirect to login
+ response = testRestTemplate.getForEntity(testUrl + "/book-service/books/1", String.class);
+ Assert.assertEquals(HttpStatus.FOUND, response.getStatusCode());
+ Assert.assertEquals("http://localhost:8080/login", response.getHeaders().get("Location").get(0));
+
+ //login as user/password
+ MultiValueMap form = new LinkedMultiValueMap<>();
+ form.add("username", "user");
+ form.add("password", "password");
+ response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class);
+
+ //extract the session from the cookie and propagate it to the next request
+ String sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0];
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("Cookie", sessionCookie);
+ HttpEntity httpEntity = new HttpEntity<>(headers);
+
+ addBook();
+
+ //request the protected resource
+ response = testRestTemplate.exchange(testUrl + "/book-service/books/1", HttpMethod.GET, httpEntity, String.class);
+ Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
+ Assert.assertNotNull(response.getBody());
+
+ addRatings();
+
+ //request the admin protected resource to determine it is still protected
+ response = testRestTemplate.exchange(testUrl + "/rating-service/ratings", HttpMethod.GET, httpEntity, String.class);
+ Assert.assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode());
+
+ //login as the admin
+ form.clear();
+ form.add("username", "admin");
+ form.add("password", "admin");
+ response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class);
+
+ //extract the session from the cookie and propagate it to the next request
+ sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0];
+ headers = new HttpHeaders();
+ headers.add("Cookie", sessionCookie);
+ httpEntity = new HttpEntity<>(headers);
+
+ //request the protected resource
+ response = testRestTemplate.exchange(testUrl + "/rating-service/ratings", HttpMethod.GET, httpEntity, String.class);
+ Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
+ Assert.assertNotNull(response.getBody());
+
+ //request the discovery resources as the admin
+ response = testRestTemplate.exchange(testUrl + "/discovery", HttpMethod.GET, httpEntity, String.class);
+ Assert.assertEquals(HttpStatus.OK, response.getStatusCode());
+ }
+
+ private void addRatings() {
+ //login as user/password
+ MultiValueMap form = new LinkedMultiValueMap<>();
+ form.add("username", "user");
+ form.add("password", "password");
+ ResponseEntity response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class);
+
+ //extract the session from the cookie and propagate it to the next request
+ String sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0];
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("Cookie", sessionCookie);
+ headers.add("ContentType", ContentType.APPLICATION_JSON.getMimeType());
+ Rating rating = new Rating(1L, 4);
+
+ HttpEntity httpEntity = new HttpEntity<>(rating, headers);
+
+ //request the protected resource
+ ResponseEntity bookResponse = testRestTemplate.postForEntity(testUrl + "/rating-service/ratings", httpEntity, Rating.class);
+ Assert.assertEquals(HttpStatus.OK, bookResponse.getStatusCode());
+ Assert.assertEquals(rating.getBookId(), bookResponse.getBody().getBookId());
+ Assert.assertEquals(rating.getStars(), bookResponse.getBody().getStars());
+ }
+
+ private void addBook(){
+ //login as user/password
+ MultiValueMap form = new LinkedMultiValueMap<>();
+ form.add("username", "admin");
+ form.add("password", "admin");
+ ResponseEntity response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class);
+
+ //extract the session from the cookie and propagate it to the next request
+ String sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0];
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("Cookie", sessionCookie);
+ headers.add("ContentType", ContentType.APPLICATION_JSON.getMimeType());
+ Book book = new Book("Baeldung", "How to spring cloud");
+
+ HttpEntity httpEntity = new HttpEntity<>(book, headers);
+
+ //request the protected resource
+ ResponseEntity bookResponse = testRestTemplate.postForEntity(testUrl + "/book-service/books", httpEntity, Book.class);
+ Assert.assertEquals(HttpStatus.OK, bookResponse.getStatusCode());
+ Assert.assertEquals(book.getAuthor(), bookResponse.getBody().getAuthor());
+ Assert.assertEquals(book.getTitle(), bookResponse.getBody().getTitle());
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class Book {
+
+ private Long id;
+ private String author;
+ private String title;
+
+ public Book() {
+ }
+
+ public Book(String author, String title) {
+ this.author = author;
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class Rating {
+ private Long id;
+ private Long bookId;
+ private int stars;
+
+ public Rating() {
+ }
+
+ public Rating(Long bookId, int stars) {
+ this.bookId = bookId;
+ this.stars = stars;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getBookId() {
+ return bookId;
+ }
+
+ public void setBookId(Long bookId) {
+ this.bookId = bookId;
+ }
+
+ public int getStars() {
+ return stars;
+ }
+
+ public void setStars(int stars) {
+ this.stars = stars;
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/pom.xml b/spring-cloud/spring-cloud-bootstrap/pom.xml
index 9a1b2e6d0e..ccfbdb9735 100644
--- a/spring-cloud/spring-cloud-bootstrap/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/pom.xml
@@ -14,7 +14,8 @@
config
discovery
gateway
- resource
+ svc-book
+ svc-rating
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/ResourceApplication.java b/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/ResourceApplication.java
deleted file mode 100644
index accef18a14..0000000000
--- a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/ResourceApplication.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.baeldung.spring.cloud.bootstrap.resource;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@SpringBootApplication
-@EnableEurekaClient
-@RestController
-public class ResourceApplication {
- public static void main(String[] args) {
- SpringApplication.run(ResourceApplication.class, args);
- }
-
- @Value("${resource.returnString}")
- private String returnString;
-
- @Value("${resource.user.returnString}")
- private String userReturnString;
-
- @Value("${resource.admin.returnString}")
- private String adminReturnString;
-
- @RequestMapping("/hello/cloud")
- public String getString() {
- return returnString;
- }
-
- @RequestMapping("/hello/user")
- public String getUserString() {
- return userReturnString;
- }
-
- @RequestMapping("/hello/admin")
- public String getAdminString() {
- return adminReturnString;
- }
-}
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/pom.xml b/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml
similarity index 86%
rename from spring-cloud/spring-cloud-bootstrap/resource/pom.xml
rename to spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml
index 1472693de8..c351c444f6 100644
--- a/spring-cloud/spring-cloud-bootstrap/resource/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/pom.xml
@@ -4,13 +4,14 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- resource
+ com.baeldung.spring.cloud
+ svc-book
1.0.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
@@ -41,6 +42,17 @@
spring-boot-starter-data-redis
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
org.springframework.boot
spring-boot-starter-test
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java
new file mode 100644
index 0000000000..c5499cd924
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/BookServiceApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.spring.cloud.bootstrap.svcbook;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+
+@SpringBootApplication
+@EnableEurekaClient
+public class BookServiceApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(BookServiceApplication.class, args);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java
similarity index 72%
rename from spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SecurityConfig.java
rename to spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java
index 0b0de6ec20..6aa996c575 100644
--- a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SecurityConfig.java
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SecurityConfig.java
@@ -1,7 +1,8 @@
-package com.baeldung.spring.cloud.bootstrap.resource;
+package com.baeldung.spring.cloud.bootstrap.svcbook;
import org.springframework.beans.factory.annotation.Autowired;
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;
@@ -22,9 +23,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
http.httpBasic()
.disable()
.authorizeRequests()
- .antMatchers("/hello/cloud").permitAll()
- .antMatchers("/hello/user").hasAnyRole("USER", "ADMIN")
- .antMatchers("/hello/admin").hasRole("ADMIN")
+ .antMatchers(HttpMethod.GET, "/books").permitAll()
+ .antMatchers(HttpMethod.GET, "/books/*").permitAll()
+ .antMatchers(HttpMethod.POST, "/books").hasRole("ADMIN")
+ .antMatchers(HttpMethod.PATCH, "/books/*").hasRole("ADMIN")
+ .antMatchers(HttpMethod.DELETE, "/books/*").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.csrf()
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SessionConfig.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java
similarity index 87%
rename from spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SessionConfig.java
rename to spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java
index f11f316826..dbde068069 100644
--- a/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/bootstrap/resource/SessionConfig.java
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/SessionConfig.java
@@ -1,4 +1,4 @@
-package com.baeldung.spring.cloud.bootstrap.resource;
+package com.baeldung.spring.cloud.bootstrap.svcbook;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java
new file mode 100644
index 0000000000..33ea8dcb81
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/Book.java
@@ -0,0 +1,45 @@
+package com.baeldung.spring.cloud.bootstrap.svcbook.book;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Book {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+ private String author;
+ private String title;
+
+ public Book() {
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java
new file mode 100644
index 0000000000..d00f114b8c
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookController.java
@@ -0,0 +1,40 @@
+package com.baeldung.spring.cloud.bootstrap.svcbook.book;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/books")
+public class BookController {
+
+ @Autowired
+ private BookService bookService;
+
+ @GetMapping("")
+ public List findAllBooks() {
+ return bookService.findAllBooks();
+ }
+
+ @GetMapping("/{bookId}")
+ public Book findBook(@PathVariable Long bookId) {
+ return bookService.findBookById(bookId);
+ }
+
+ @PostMapping("")
+ public Book createBook(@RequestBody Book book) {
+ return bookService.createBook(book);
+ }
+
+ @DeleteMapping("/{bookId}")
+ public void deleteBook(@PathVariable Long bookId) {
+ bookService.deleteBook(bookId);
+ }
+
+ @PatchMapping("/{bookId")
+ public Book updateBook(@RequestBody Map updates, @PathVariable Long bookId) {
+ return bookService.updateBook(updates, bookId);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java
new file mode 100644
index 0000000000..f0a4797387
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookNotFoundException.java
@@ -0,0 +1,11 @@
+package com.baeldung.spring.cloud.bootstrap.svcbook.book;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)
+class BookNotFoundException extends RuntimeException {
+ BookNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java
new file mode 100644
index 0000000000..66fd3880c5
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookRepository.java
@@ -0,0 +1,6 @@
+package com.baeldung.spring.cloud.bootstrap.svcbook.book;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+interface BookRepository extends JpaRepository{
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java
new file mode 100644
index 0000000000..cfcbf15757
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/java/com/baeldung/spring/cloud/bootstrap/svcbook/book/BookService.java
@@ -0,0 +1,55 @@
+package com.baeldung.spring.cloud.bootstrap.svcbook.book;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@Service
+@Transactional(readOnly = true)
+public class BookService {
+
+ @Autowired
+ private BookRepository bookRepository;
+
+ public List findAllBooks() {
+ return bookRepository.findAll();
+ }
+
+ public Book findBookById(Long bookId) {
+ return Optional.ofNullable(bookRepository.findOne(bookId))
+ .orElseThrow(() -> new BookNotFoundException("Book not found. ID: " + bookId));
+ }
+
+ @Transactional(propagation = Propagation.REQUIRED)
+ public Book createBook(Book book) {
+ Book newBook = new Book();
+ newBook.setTitle(book.getTitle());
+ newBook.setAuthor(book.getAuthor());
+ return bookRepository.save(newBook);
+ }
+
+ @Transactional(propagation = Propagation.REQUIRED)
+ public void deleteBook(Long bookId) {
+ bookRepository.delete(bookId);
+ }
+
+ @Transactional(propagation = Propagation.REQUIRED)
+ public Book updateBook(Map updates, Long bookId) {
+ Book book = findBookById(bookId);
+ updates.keySet().forEach(key -> {
+ switch (key) {
+ case "author":
+ book.setAuthor(updates.get(key));
+ break;
+ case "title":
+ book.setTitle(updates.get(key));
+ }
+ });
+ return bookRepository.save(book);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/resources/bootstrap.properties
similarity index 87%
rename from spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties
rename to spring-cloud/spring-cloud-bootstrap/svc-book/src/main/resources/bootstrap.properties
index 9ecfb46125..8f3a3261ac 100644
--- a/spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties
+++ b/spring-cloud/spring-cloud-bootstrap/svc-book/src/main/resources/bootstrap.properties
@@ -1,4 +1,4 @@
-spring.cloud.config.name=resource
+spring.cloud.config.name=book-service
spring.cloud.config.discovery.service-id=config
spring.cloud.config.discovery.enabled=true
spring.cloud.config.username=configUser
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml b/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml
new file mode 100644
index 0000000000..2285286812
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/pom.xml
@@ -0,0 +1,96 @@
+
+
+ 4.0.0
+
+ com.baeldung.spring.cloud
+ svc-rating
+ 1.0.0-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.4.4.RELEASE
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-config
+
+
+ org.springframework.cloud
+ spring-cloud-starter-eureka
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.session
+ spring-session
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud-dependencies.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+
+
+ Brixton.SR7
+ 3.6.0
+
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java
new file mode 100644
index 0000000000..61074e0bcc
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/RatingServiceApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.spring.cloud.bootstrap.svcrating;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+
+@SpringBootApplication
+@EnableEurekaClient
+public class RatingServiceApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(RatingServiceApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java
new file mode 100644
index 0000000000..171fbba7af
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SecurityConfig.java
@@ -0,0 +1,36 @@
+package com.baeldung.spring.cloud.bootstrap.svcrating;
+
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+
+@EnableWebSecurity
+@Configuration
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Autowired
+ public void configureGlobal1(AuthenticationManagerBuilder auth) throws Exception {
+ //try in memory auth with no users to support the case that this will allow for users that are logged in to go anywhere
+ auth.inMemoryAuthentication();
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.httpBasic()
+ .disable()
+ .authorizeRequests()
+ .regexMatchers("^/ratings\\?bookId.*$").authenticated()
+ .antMatchers(HttpMethod.POST,"/ratings").authenticated()
+ .antMatchers(HttpMethod.PATCH,"/ratings/*").hasRole("ADMIN")
+ .antMatchers(HttpMethod.DELETE,"/ratings/*").hasRole("ADMIN")
+ .antMatchers(HttpMethod.GET,"/ratings").hasRole("ADMIN")
+ .anyRequest().authenticated()
+ .and()
+ .csrf()
+ .disable();
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java
new file mode 100644
index 0000000000..62bc701868
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/SessionConfig.java
@@ -0,0 +1,10 @@
+package com.baeldung.spring.cloud.bootstrap.svcrating;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
+import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
+
+@Configuration
+@EnableRedisHttpSession
+public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java
new file mode 100644
index 0000000000..ae44f9ae2e
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/Rating.java
@@ -0,0 +1,52 @@
+package com.baeldung.spring.cloud.bootstrap.svcrating.rating;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Rating {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+ private Long bookId;
+ private int stars;
+
+ public Rating() {
+ }
+
+ public Rating(Long id, Long bookId, int stars) {
+ this.id = id;
+ this.bookId = bookId;
+ this.stars = stars;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Long getBookId() {
+ return bookId;
+ }
+
+ public void setBookId(Long bookId) {
+ this.bookId = bookId;
+ }
+
+ public int getStars() {
+ return stars;
+ }
+
+ public void setStars(int stars) {
+ this.stars = stars;
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java
new file mode 100644
index 0000000000..83452ad747
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingController.java
@@ -0,0 +1,38 @@
+package com.baeldung.spring.cloud.bootstrap.svcrating.rating;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/ratings")
+public class RatingController {
+
+ @Autowired
+ private RatingService ratingService;
+
+ @GetMapping("")
+ public List findRatingsByBookId(@RequestParam(required = false, defaultValue = "0") Long bookId) {
+ if (bookId.equals(0L)) {
+ return ratingService.findAllRatings();
+ }
+ return ratingService.findRatingsByBookId(bookId);
+ }
+
+ @PostMapping("")
+ public Rating createRating(@RequestBody Rating rating) {
+ return ratingService.createRating(rating);
+ }
+
+ @DeleteMapping("/{ratingId}")
+ public void deleteRating(@PathVariable Long ratingId) {
+ ratingService.deleteRating(ratingId);
+ }
+
+ @PatchMapping("/{ratingId")
+ public Rating updateRating(@RequestBody Map updates, @PathVariable Long ratingId) {
+ return ratingService.updateRating(updates, ratingId);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java
new file mode 100644
index 0000000000..473d636a71
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingNotFoundException.java
@@ -0,0 +1,11 @@
+package com.baeldung.spring.cloud.bootstrap.svcrating.rating;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)
+class RatingNotFoundException extends RuntimeException {
+ RatingNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java
new file mode 100644
index 0000000000..08d781b5a3
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.spring.cloud.bootstrap.svcrating.rating;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+interface RatingRepository extends JpaRepository{
+ List findRatingsByBookId(Long bookId);
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java
new file mode 100644
index 0000000000..a2360b7be5
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/java/com/baeldung/spring/cloud/bootstrap/svcrating/rating/RatingService.java
@@ -0,0 +1,57 @@
+package com.baeldung.spring.cloud.bootstrap.svcrating.rating;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@Service
+@Transactional(readOnly = true)
+public class RatingService {
+
+ @Autowired
+ private RatingRepository ratingRepository;
+
+ public Rating findRatingById(Long ratingId) {
+ return Optional.ofNullable(ratingRepository.findOne(ratingId))
+ .orElseThrow(() -> new RatingNotFoundException("Rating not found. ID: " + ratingId));
+ }
+
+ public List findRatingsByBookId(Long bookId) {
+ return ratingRepository.findRatingsByBookId(bookId);
+ }
+
+ public List findAllRatings() {
+ return ratingRepository.findAll();
+ }
+
+ @Transactional(propagation = Propagation.REQUIRED)
+ public Rating createRating(Rating rating) {
+ Rating newRating = new Rating();
+ newRating.setBookId(rating.getBookId());
+ newRating.setStars(rating.getStars());
+ return ratingRepository.save(newRating);
+ }
+
+ @Transactional(propagation = Propagation.REQUIRED)
+ public void deleteRating(Long ratingId) {
+ ratingRepository.delete(ratingId);
+ }
+
+ @Transactional(propagation = Propagation.REQUIRED)
+ public Rating updateRating(Map updates, Long ratingId) {
+ Rating rating = findRatingById(ratingId);
+ updates.keySet().forEach(key -> {
+ switch (key) {
+ case "stars":
+ rating.setStars(Integer.parseInt(updates.get(key)));
+ break;
+ }
+ });
+ return ratingRepository.save(rating);
+ }
+}
diff --git a/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000000..be5cf7f1e1
--- /dev/null
+++ b/spring-cloud/spring-cloud-bootstrap/svc-rating/src/main/resources/bootstrap.properties
@@ -0,0 +1,7 @@
+spring.cloud.config.name=rating-service
+spring.cloud.config.discovery.service-id=config
+spring.cloud.config.discovery.enabled=true
+spring.cloud.config.username=configUser
+spring.cloud.config.password=configPassword
+
+eureka.client.serviceUrl.defaultZone=http://discUser:discPassword@localhost:8082/eureka/
diff --git a/spring-cloud/spring-cloud-config/pom.xml b/spring-cloud/spring-cloud-config/pom.xml
index d25037a49f..56ff377956 100644
--- a/spring-cloud/spring-cloud-config/pom.xml
+++ b/spring-cloud/spring-cloud-config/pom.xml
@@ -16,7 +16,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-cloud/spring-cloud-ribbon-client/pom.xml b/spring-cloud/spring-cloud-ribbon-client/pom.xml
index 8aee41f5c4..d70de51a58 100644
--- a/spring-cloud/spring-cloud-ribbon-client/pom.xml
+++ b/spring-cloud/spring-cloud-ribbon-client/pom.xml
@@ -11,7 +11,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-core/README.md b/spring-core/README.md
index f6aaaf44a0..a32d30939f 100644
--- a/spring-core/README.md
+++ b/spring-core/README.md
@@ -3,4 +3,4 @@
- [Exploring the Spring BeanFactory API](http://www.baeldung.com/spring-beanfactory)
- [How to use the Spring FactoryBean?](http://www.baeldung.com/spring-factorybean)
- [Constructor Dependency Injection in Spring](http://www.baeldung.com/constructor-injection-in-spring)
-- [Constructor Injection in Spring with Lombok](http://inprogress.baeldung.com/constructor-injection-in-spring-with-lombok)
+- [Constructor Injection in Spring with Lombok](http://www.baeldung.com/spring-injection-lombok)
diff --git a/spring-core/src/main/java/com/baeldung/Ebook.java b/spring-core/src/main/java/com/baeldung/Ebook.java
new file mode 100644
index 0000000000..fc29ddfcf5
--- /dev/null
+++ b/spring-core/src/main/java/com/baeldung/Ebook.java
@@ -0,0 +1,20 @@
+package com.baeldung;
+
+public class Ebook {
+
+ private int bookId;
+ private String bookTitle;
+
+ public int getBookId() {
+ return bookId;
+ }
+ public void setBookId(int bookId) {
+ this.bookId = bookId;
+ }
+ public String getBookTitle() {
+ return bookTitle;
+ }
+ public void setBookTitle(String bookTitle) {
+ this.bookTitle = bookTitle;
+ }
+}
diff --git a/spring-core/src/main/java/com/baeldung/EbookRepository.java b/spring-core/src/main/java/com/baeldung/EbookRepository.java
new file mode 100644
index 0000000000..661283c355
--- /dev/null
+++ b/spring-core/src/main/java/com/baeldung/EbookRepository.java
@@ -0,0 +1,5 @@
+package com.baeldung;
+
+public interface EbookRepository {
+ String titleById(int id);
+}
diff --git a/spring-core/src/main/java/com/baeldung/LibraryUtils.java b/spring-core/src/main/java/com/baeldung/LibraryUtils.java
new file mode 100644
index 0000000000..49af60c89d
--- /dev/null
+++ b/spring-core/src/main/java/com/baeldung/LibraryUtils.java
@@ -0,0 +1,12 @@
+package com.baeldung;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class LibraryUtils {
+ @Autowired
+ private EbookRepository eBookRepository;
+
+ public String findBook(int id) {
+ return eBookRepository.titleById(id);
+ }
+}
diff --git a/spring-core/src/main/java/com/baeldung/Member.java b/spring-core/src/main/java/com/baeldung/Member.java
new file mode 100644
index 0000000000..ceebb32017
--- /dev/null
+++ b/spring-core/src/main/java/com/baeldung/Member.java
@@ -0,0 +1,20 @@
+package com.baeldung;
+
+public class Member {
+
+ private int memberId;
+ private String memberName;
+
+ public int getMemberId() {
+ return memberId;
+ }
+ public void setMemberId(int memberId) {
+ this.memberId = memberId;
+ }
+ public String getMemberName() {
+ return memberName;
+ }
+ public void setMemberName(String memberName) {
+ this.memberName = memberName;
+ }
+}
diff --git a/spring-core/src/main/java/com/baeldung/Reservation.java b/spring-core/src/main/java/com/baeldung/Reservation.java
new file mode 100644
index 0000000000..ed33bb6464
--- /dev/null
+++ b/spring-core/src/main/java/com/baeldung/Reservation.java
@@ -0,0 +1,14 @@
+package com.baeldung;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class Reservation {
+ private Member member;
+ private Ebook eBook;
+
+ @Autowired
+ public Reservation(Member member, Ebook eBook) {
+ this.member = member;
+ this.eBook = eBook;
+ }
+}
diff --git a/spring-core/src/main/java/com/baeldung/lombok/Apologizer.java b/spring-core/src/main/java/com/baeldung/lombok/ApologizeService.java
similarity index 83%
rename from spring-core/src/main/java/com/baeldung/lombok/Apologizer.java
rename to spring-core/src/main/java/com/baeldung/lombok/ApologizeService.java
index ddce9cdc52..25ef65cad2 100644
--- a/spring-core/src/main/java/com/baeldung/lombok/Apologizer.java
+++ b/spring-core/src/main/java/com/baeldung/lombok/ApologizeService.java
@@ -6,13 +6,13 @@ import org.springframework.stereotype.Component;
@Component
@AllArgsConstructor
-public class Apologizer {
+public class ApologizeService {
private final Translator translator;
private final String message;
@Autowired
- public Apologizer(Translator translator) {
+ public ApologizeService(Translator translator) {
this(translator, "sorry");
}
diff --git a/spring-core/src/main/java/com/baeldung/lombok/Fareweller.java b/spring-core/src/main/java/com/baeldung/lombok/FarewellService.java
similarity index 79%
rename from spring-core/src/main/java/com/baeldung/lombok/Fareweller.java
rename to spring-core/src/main/java/com/baeldung/lombok/FarewellService.java
index b10ebb72b9..4e8c4993cb 100644
--- a/spring-core/src/main/java/com/baeldung/lombok/Fareweller.java
+++ b/spring-core/src/main/java/com/baeldung/lombok/FarewellService.java
@@ -4,11 +4,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class Fareweller {
+public class FarewellService {
private final Translator translator;
- public Fareweller(Translator translator) {
+ public FarewellService(Translator translator) {
this.translator = translator;
}
diff --git a/spring-core/src/main/java/com/baeldung/lombok/Greeter.java b/spring-core/src/main/java/com/baeldung/lombok/GreetingService.java
similarity index 90%
rename from spring-core/src/main/java/com/baeldung/lombok/Greeter.java
rename to spring-core/src/main/java/com/baeldung/lombok/GreetingService.java
index ddbc024ce7..0e03e177e1 100644
--- a/spring-core/src/main/java/com/baeldung/lombok/Greeter.java
+++ b/spring-core/src/main/java/com/baeldung/lombok/GreetingService.java
@@ -4,7 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
-public class Greeter {
+public class GreetingService {
@Autowired
private Translator translator;
diff --git a/spring-core/src/main/java/com/baeldung/lombok/Thanker.java b/spring-core/src/main/java/com/baeldung/lombok/ThankingService.java
similarity index 76%
rename from spring-core/src/main/java/com/baeldung/lombok/Thanker.java
rename to spring-core/src/main/java/com/baeldung/lombok/ThankingService.java
index 784100c258..f3bdf8bb7f 100644
--- a/spring-core/src/main/java/com/baeldung/lombok/Thanker.java
+++ b/spring-core/src/main/java/com/baeldung/lombok/ThankingService.java
@@ -1,12 +1,11 @@
package com.baeldung.lombok;
import lombok.AllArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@AllArgsConstructor
-public class Thanker {
+public class ThankingService {
private final Translator translator;
diff --git a/spring-core/src/test/java/com/baeldung/lombok/ApologizerAutowiringTest.java b/spring-core/src/test/java/com/baeldung/lombok/ApologizeServiceAutowiringTest.java
similarity index 84%
rename from spring-core/src/test/java/com/baeldung/lombok/ApologizerAutowiringTest.java
rename to spring-core/src/test/java/com/baeldung/lombok/ApologizeServiceAutowiringTest.java
index 3e7c775f91..755fc5868b 100644
--- a/spring-core/src/test/java/com/baeldung/lombok/ApologizerAutowiringTest.java
+++ b/spring-core/src/test/java/com/baeldung/lombok/ApologizeServiceAutowiringTest.java
@@ -14,12 +14,12 @@ import static org.mockito.Mockito.when;
@ContextConfiguration(
loader = AnnotationConfigContextLoader.class,
classes = TestConfig.class)
-public class ApologizerAutowiringTest {
+public class ApologizeServiceAutowiringTest {
private final static String TRANSLATED = "TRANSLATED";
@Autowired
- private Apologizer apologizer;
+ private ApologizeService apologizeService;
@Autowired
private Translator translator;
@@ -27,7 +27,7 @@ public class ApologizerAutowiringTest {
@Test
public void apologizeWithTranslatedMessage() {
when(translator.translate("sorry")).thenReturn(TRANSLATED);
- assertEquals(TRANSLATED, apologizer.apologize());
+ assertEquals(TRANSLATED, apologizeService.apologize());
}
}
\ No newline at end of file
diff --git a/spring-core/src/test/java/com/baeldung/lombok/ApologizerTest.java b/spring-core/src/test/java/com/baeldung/lombok/ApologizeServiceTest.java
similarity index 72%
rename from spring-core/src/test/java/com/baeldung/lombok/ApologizerTest.java
rename to spring-core/src/test/java/com/baeldung/lombok/ApologizeServiceTest.java
index 28bd08c89f..ab545e7adf 100644
--- a/spring-core/src/test/java/com/baeldung/lombok/ApologizerTest.java
+++ b/spring-core/src/test/java/com/baeldung/lombok/ApologizeServiceTest.java
@@ -6,7 +6,7 @@ import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-public class ApologizerTest {
+public class ApologizeServiceTest {
private final static String MESSAGE = "MESSAGE";
private final static String TRANSLATED = "TRANSLATED";
@@ -14,8 +14,8 @@ public class ApologizerTest {
@Test
public void apologizeWithCustomTranslatedMessage() {
Translator translator = mock(Translator.class);
- Apologizer apologizer = new Apologizer(translator, MESSAGE);
+ ApologizeService apologizeService = new ApologizeService(translator, MESSAGE);
when(translator.translate(MESSAGE)).thenReturn(TRANSLATED);
- assertEquals(TRANSLATED, apologizer.apologize());
+ assertEquals(TRANSLATED, apologizeService.apologize());
}
}
diff --git a/spring-core/src/test/java/com/baeldung/lombok/FarewellAutowiringTest.java b/spring-core/src/test/java/com/baeldung/lombok/FarewellAutowiringTest.java
index d55d44fb3e..592e309236 100644
--- a/spring-core/src/test/java/com/baeldung/lombok/FarewellAutowiringTest.java
+++ b/spring-core/src/test/java/com/baeldung/lombok/FarewellAutowiringTest.java
@@ -17,7 +17,7 @@ import static org.mockito.Mockito.when;
public class FarewellAutowiringTest {
@Autowired
- private Fareweller fareweller;
+ private FarewellService farewellService;
@Autowired
private Translator translator;
@@ -26,6 +26,6 @@ public class FarewellAutowiringTest {
public void sayByeWithTranslatedMessage() {
String translated = "translated";
when(translator.translate("bye")).thenReturn(translated);
- assertEquals(translated, fareweller.farewell());
+ assertEquals(translated, farewellService.farewell());
}
}
diff --git a/spring-core/src/test/java/com/baeldung/lombok/FarewellerTest.java b/spring-core/src/test/java/com/baeldung/lombok/FarewellServiceTest.java
similarity index 70%
rename from spring-core/src/test/java/com/baeldung/lombok/FarewellerTest.java
rename to spring-core/src/test/java/com/baeldung/lombok/FarewellServiceTest.java
index a02ad1d8ac..9ad593a489 100644
--- a/spring-core/src/test/java/com/baeldung/lombok/FarewellerTest.java
+++ b/spring-core/src/test/java/com/baeldung/lombok/FarewellServiceTest.java
@@ -6,7 +6,7 @@ import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-public class FarewellerTest {
+public class FarewellServiceTest {
private final static String TRANSLATED = "TRANSLATED";
@@ -14,7 +14,7 @@ public class FarewellerTest {
public void sayByeWithTranslatedMessage() {
Translator translator = mock(Translator.class);
when(translator.translate("bye")).thenReturn(TRANSLATED);
- Fareweller fareweller = new Fareweller(translator);
- assertEquals(TRANSLATED, fareweller.farewell());
+ FarewellService farewellService = new FarewellService(translator);
+ assertEquals(TRANSLATED, farewellService.farewell());
}
}
\ No newline at end of file
diff --git a/spring-core/src/test/java/com/baeldung/lombok/GreeterTest.java b/spring-core/src/test/java/com/baeldung/lombok/GreetingServiceTest.java
similarity index 79%
rename from spring-core/src/test/java/com/baeldung/lombok/GreeterTest.java
rename to spring-core/src/test/java/com/baeldung/lombok/GreetingServiceTest.java
index 0f66eaf301..d0207d681b 100644
--- a/spring-core/src/test/java/com/baeldung/lombok/GreeterTest.java
+++ b/spring-core/src/test/java/com/baeldung/lombok/GreetingServiceTest.java
@@ -14,10 +14,10 @@ import static org.mockito.Mockito.when;
@ContextConfiguration(
loader = AnnotationConfigContextLoader.class,
classes = TestConfig.class)
-public class GreeterTest {
+public class GreetingServiceTest {
@Autowired
- private Greeter greeter;
+ private GreetingService greetingService;
@Autowired
private Translator translator;
@@ -26,12 +26,12 @@ public class GreeterTest {
public void greetWithTranslatedMessage() {
String translated = "translated";
when(translator.translate("hello")).thenReturn(translated);
- assertEquals(translated, greeter.greet());
+ assertEquals(translated, greetingService.greet());
}
@Test(expected = NullPointerException.class)
public void throwWhenInstantiated() {
- Greeter greeter = new Greeter();
- greeter.greet();
+ GreetingService greetingService = new GreetingService();
+ greetingService.greet();
}
}
\ No newline at end of file
diff --git a/spring-core/src/test/java/com/baeldung/lombok/ThankerAutowiringTest.java b/spring-core/src/test/java/com/baeldung/lombok/ThankingServiceAutowiringTest.java
similarity index 84%
rename from spring-core/src/test/java/com/baeldung/lombok/ThankerAutowiringTest.java
rename to spring-core/src/test/java/com/baeldung/lombok/ThankingServiceAutowiringTest.java
index 59aded5831..b2a338b18f 100644
--- a/spring-core/src/test/java/com/baeldung/lombok/ThankerAutowiringTest.java
+++ b/spring-core/src/test/java/com/baeldung/lombok/ThankingServiceAutowiringTest.java
@@ -14,10 +14,10 @@ import static org.mockito.Mockito.when;
@ContextConfiguration(
loader = AnnotationConfigContextLoader.class,
classes = TestConfig.class)
-public class ThankerAutowiringTest {
+public class ThankingServiceAutowiringTest {
@Autowired
- private Thanker thanker;
+ private ThankingService thankingService;
@Autowired
private Translator translator;
@@ -26,6 +26,6 @@ public class ThankerAutowiringTest {
public void thankWithTranslatedMessage() {
String translated = "translated";
when(translator.translate("thank you")).thenReturn(translated);
- assertEquals(translated, thanker.thank());
+ assertEquals(translated, thankingService.thank());
}
}
\ No newline at end of file
diff --git a/spring-core/src/test/java/com/baeldung/lombok/ThankerTest.java b/spring-core/src/test/java/com/baeldung/lombok/ThankingServiceTest.java
similarity index 71%
rename from spring-core/src/test/java/com/baeldung/lombok/ThankerTest.java
rename to spring-core/src/test/java/com/baeldung/lombok/ThankingServiceTest.java
index 466762fa50..7dc663622b 100644
--- a/spring-core/src/test/java/com/baeldung/lombok/ThankerTest.java
+++ b/spring-core/src/test/java/com/baeldung/lombok/ThankingServiceTest.java
@@ -6,7 +6,7 @@ import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-public class ThankerTest {
+public class ThankingServiceTest {
private final static String TRANSLATED = "TRANSLATED";
@@ -14,7 +14,7 @@ public class ThankerTest {
public void thankWithTranslatedMessage() {
Translator translator = mock(Translator.class);
when(translator.translate("thank you")).thenReturn(TRANSLATED);
- Thanker thanker = new Thanker(translator);
- assertEquals(TRANSLATED, thanker.thank());
+ ThankingService thankingService = new ThankingService(translator);
+ assertEquals(TRANSLATED, thankingService.thank());
}
}
\ No newline at end of file
diff --git a/spring-cucumber/pom.xml b/spring-cucumber/pom.xml
index 644ddff1d8..55c0af670a 100644
--- a/spring-cucumber/pom.xml
+++ b/spring-cucumber/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-data-dynamodb/pom.xml b/spring-data-dynamodb/pom.xml
index 0ce9b3a399..8b06c0b36f 100644
--- a/spring-data-dynamodb/pom.xml
+++ b/spring-data-dynamodb/pom.xml
@@ -11,7 +11,7 @@
spring-boot-starter-parent
org.springframework.boot
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java b/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java
index 8fe3e96940..05badc74b4 100644
--- a/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java
+++ b/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java
@@ -44,8 +44,8 @@ public class ProductInfoRepositoryIntegrationTest {
private static final String EXPECTED_PRICE = "50";
@Before
- @Ignore //TODO Remove Ignore annotations when running locally with Local DynamoDB instance
- public void setup() throws Exception {
+ @Ignore // TODO Remove Ignore annotations when running locally with Local DynamoDB instance
+ public void setup() throws Exception {
try {
dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB);
@@ -64,7 +64,7 @@ public class ProductInfoRepositoryIntegrationTest {
}
@Test
- @Ignore //TODO Remove Ignore annotations when running locally with Local DynamoDB instance
+ @Ignore // TODO Remove Ignore annotations when running locally with Local DynamoDB instance
public void givenItemWithExpectedCost_whenRunFindAll_thenItemIsFound() {
ProductInfo productInfo = new ProductInfo(EXPECTED_COST, EXPECTED_PRICE);
diff --git a/spring-data-mongodb/README.md b/spring-data-mongodb/README.md
index d656bc897c..c2a1f703b5 100644
--- a/spring-data-mongodb/README.md
+++ b/spring-data-mongodb/README.md
@@ -9,3 +9,4 @@
- [Custom Cascading in Spring Data MongoDB](http://www.baeldung.com/cascading-with-dbref-and-lifecycle-events-in-spring-data-mongodb)
- [GridFS in Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-gridfs)
- [Introduction to Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-tutorial)
+- [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations)
diff --git a/spring-data-mongodb/src/main/java/org/baeldung/config/SimpleMongoConfig.java b/spring-data-mongodb/src/main/java/org/baeldung/config/SimpleMongoConfig.java
new file mode 100644
index 0000000000..6140382f82
--- /dev/null
+++ b/spring-data-mongodb/src/main/java/org/baeldung/config/SimpleMongoConfig.java
@@ -0,0 +1,25 @@
+package org.baeldung.config;
+
+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.Mongo;
+import com.mongodb.MongoClient;
+
+@Configuration
+@EnableMongoRepositories(basePackages = "org.baeldung.repository")
+public class SimpleMongoConfig {
+
+ @Bean
+ public Mongo mongo() throws Exception {
+ return new MongoClient("localhost");
+ }
+
+ @Bean
+ public MongoTemplate mongoTemplate() throws Exception {
+ return new MongoTemplate(mongo(), "test");
+ }
+
+}
diff --git a/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateProjectionLiveTest.java b/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateProjectionLiveTest.java
index 04e474f71b..61115faede 100644
--- a/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateProjectionLiveTest.java
+++ b/spring-data-mongodb/src/test/java/org/baeldung/mongotemplate/MongoTemplateProjectionLiveTest.java
@@ -1,8 +1,10 @@
package org.baeldung.mongotemplate;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
-import org.baeldung.config.MongoConfig;
+import org.baeldung.config.SimpleMongoConfig;
import org.baeldung.model.User;
import org.junit.After;
import org.junit.Before;
@@ -15,7 +17,7 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = MongoConfig.class)
+@ContextConfiguration(classes = SimpleMongoConfig.class)
public class MongoTemplateProjectionLiveTest {
@Autowired
@@ -38,7 +40,7 @@ public class MongoTemplateProjectionLiveTest {
mongoTemplate.insert(new User("John", 30));
mongoTemplate.insert(new User("Ringo", 35));
- Query query = new Query();
+ final Query query = new Query();
query.fields()
.include("name");
@@ -55,7 +57,7 @@ public class MongoTemplateProjectionLiveTest {
mongoTemplate.insert(new User("John", 30));
mongoTemplate.insert(new User("Ringo", 35));
- Query query = new Query();
+ final Query query = new Query();
query.fields()
.exclude("_id");
@@ -64,7 +66,7 @@ public class MongoTemplateProjectionLiveTest {
assertNull(user.getId());
assertNotNull(user.getAge());
});
-
+
}
}
diff --git a/spring-data-neo4j/README.md b/spring-data-neo4j/README.md
index 0f13d9dbc9..03c9ed333d 100644
--- a/spring-data-neo4j/README.md
+++ b/spring-data-neo4j/README.md
@@ -2,6 +2,7 @@
### Relevant Articles:
- [Introduction to Spring Data Neo4j](http://www.baeldung.com/spring-data-neo4j-intro)
+- [A Guide to Neo4J with Java](http://www.baeldung.com/java-neo4j)
### Build the Project with Tests Running
```
diff --git a/spring-data-neo4j/pom.xml b/spring-data-neo4j/pom.xml
index ce10313b2e..96606d597b 100644
--- a/spring-data-neo4j/pom.xml
+++ b/spring-data-neo4j/pom.xml
@@ -7,10 +7,41 @@
1.0
+
+ org.neo4j
+ neo4j
+ 3.1.0
+
+
+
+ org.neo4j
+ neo4j-ogm-core
+ 2.1.1
+
+
+
+ org.neo4j
+ neo4j-ogm-embedded-driver
+ 2.1.1
+
+
+
+ org.neo4j.driver
+ neo4j-java-driver
+ 1.1.1
+
+
+
+ org.springframework.data
+ spring-data-neo4j
+ 4.2.0.RELEASE
+
+
org.springframework.data
spring-data-neo4j
${spring-data-neo4j.version}
+ test-jar
@@ -27,13 +58,6 @@
test
-
- org.springframework.data
- spring-data-neo4j
- ${spring-data-neo4j.version}
- test-jar
-
-
org.neo4j
neo4j-kernel
@@ -72,9 +96,9 @@
spring-test
${spring-test.version}
-
+
@@ -130,16 +154,18 @@
+ 1.8
+ 1.8
1.8
UTF-8
UTF-8
- 3.0.7
+ 3.1.0
4.1.6.RELEASE
1.1
1.4.3.RELEASE
4.3.5.RELEASE
- 2.0.6
+ 2.1.1
4.12
diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java
index fb4fda1497..344282d665 100644
--- a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java
+++ b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java
@@ -4,15 +4,12 @@ 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.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.transaction.annotation.EnableTransactionManagement;
@ComponentScan(basePackages = { "com.baeldung.spring.data.neo4j.services" })
@Configuration
@EnableNeo4jRepositories(basePackages = "com.baeldung.spring.data.neo4j.repostory")
-public class MovieDatabaseNeo4jConfiguration extends Neo4jConfiguration {
+public class MovieDatabaseNeo4jConfiguration {
public static final String URL = System.getenv("NEO4J_URL") != null ? System.getenv("NEO4J_URL") : "http://neo4j:movies@localhost:7474";
@@ -23,7 +20,7 @@ public class MovieDatabaseNeo4jConfiguration extends Neo4jConfiguration {
return config;
}
- @Override
+ @Bean
public SessionFactory getSessionFactory() {
return new SessionFactory(getConfiguration(), "com.baeldung.spring.data.neo4j.domain");
}
diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java
index 81935b2293..7bb1b78a09 100644
--- a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java
+++ b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java
@@ -5,9 +5,7 @@ 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.server.Neo4jServer;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@@ -15,7 +13,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableNeo4jRepositories(basePackages = "com.baeldung.spring.data.neo4j.repostory")
@Profile({ "embedded", "test" })
-public class MovieDatabaseNeo4jTestConfiguration extends Neo4jConfiguration {
+public class MovieDatabaseNeo4jTestConfiguration {
@Bean
public org.neo4j.ogm.config.Configuration getConfiguration() {
@@ -24,7 +22,7 @@ public class MovieDatabaseNeo4jTestConfiguration extends Neo4jConfiguration {
return config;
}
- @Override
+ @Bean
public SessionFactory getSessionFactory() {
return new SessionFactory(getConfiguration(), "com.baeldung.spring.data.neo4j.domain");
}
diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java
new file mode 100644
index 0000000000..f2325a334f
--- /dev/null
+++ b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java
@@ -0,0 +1,47 @@
+package com.baeldung.spring.data.neo4j.domain;
+
+import org.neo4j.ogm.annotation.GraphId;
+import org.neo4j.ogm.annotation.NodeEntity;
+import org.neo4j.ogm.annotation.Relationship;
+
+@NodeEntity
+public class Car {
+ @GraphId
+ private Long id;
+
+ private String make;
+
+ @Relationship(direction = "INCOMING")
+ private Company company;
+
+ public Car(String make, String model) {
+ this.make = make;
+ this.model = model;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getMake() {
+ return make;
+ }
+
+ public void setMake(String make) {
+ this.make = make;
+ }
+
+ public String getModel() {
+ return model;
+ }
+
+ public void setModel(String model) {
+ this.model = model;
+ }
+
+ private String model;
+}
diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Company.java b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Company.java
new file mode 100644
index 0000000000..4422ade44f
--- /dev/null
+++ b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Company.java
@@ -0,0 +1,42 @@
+package com.baeldung.spring.data.neo4j.domain;
+
+import org.neo4j.ogm.annotation.NodeEntity;
+import org.neo4j.ogm.annotation.Relationship;
+
+@NodeEntity
+public class Company {
+ private Long id;
+
+ private String name;
+
+ @Relationship(type="owns")
+ private Car car;
+
+ 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 Car getCar() {
+ return car;
+ }
+
+ public void setCar(Car car) {
+ this.car = car;
+ }
+}
diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java
index 1bd605a7bc..afb82551e7 100644
--- a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java
+++ b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java
@@ -12,6 +12,7 @@ import java.util.Map;
@Repository
public interface MovieRepository extends GraphRepository {
+
Movie findByTitle(@Param("title") String title);
@Query("MATCH (m:Movie) WHERE m.title =~ ('(?i).*'+{title}+'.*') RETURN m")
diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java
index f7f694c07f..4ac40ef75b 100644
--- a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java
+++ b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java
@@ -6,5 +6,4 @@ import org.springframework.stereotype.Repository;
@Repository
public interface PersonRepository extends GraphRepository {
-
}
diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java
index d760d19066..ae1f6eb8e5 100644
--- a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java
+++ b/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java
@@ -12,11 +12,11 @@ import java.util.*;
public class MovieService {
@Autowired
- MovieRepository movieRepository;
+ private MovieRepository movieRepository;
private Map toD3Format(Iterator> result) {
- List> nodes = new ArrayList>();
- List> rels = new ArrayList>();
+ List> nodes = new ArrayList<>();
+ List> rels = new ArrayList<>();
int i = 0;
while (result.hasNext()) {
Map row = result.next();
@@ -37,7 +37,7 @@ public class MovieService {
}
private Map map(String key1, Object value1, String key2, Object value2) {
- Map result = new HashMap(2);
+ Map result = new HashMap<>(2);
result.put(key1, value1);
result.put(key2, value2);
return result;
diff --git a/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerTest.java b/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerTest.java
new file mode 100644
index 0000000000..e959e0237d
--- /dev/null
+++ b/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerTest.java
@@ -0,0 +1,60 @@
+package com.baeldung.neo4j;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.neo4j.driver.v1.AuthTokens;
+import org.neo4j.driver.v1.Driver;
+import org.neo4j.driver.v1.GraphDatabase;
+import org.neo4j.driver.v1.Session;
+import org.neo4j.driver.v1.StatementResult;
+
+@Ignore
+public class Neo4JServerTest {
+
+ @Test
+ public void standAloneDriver() {
+ Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "12345"));
+ Session session = driver.session();
+
+ session.run("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
+ "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
+ "RETURN baeldung, tesla");
+
+ StatementResult result = session.run("MATCH (company:Company)-[:owns]-> (car:Car)" +
+ "WHERE car.make='tesla' and car.model='modelX'" +
+ "RETURN company.name");
+
+ Assert.assertTrue(result.hasNext());
+ Assert.assertEquals(result.next().get("company.name").asString(), "Baeldung");
+
+ session.close();
+ driver.close();
+ }
+
+ @Test
+ public void standAloneJdbc() throws Exception {
+ Connection con = DriverManager.getConnection("jdbc:neo4j:bolt://localhost/?user=neo4j,password=12345,scheme=basic");
+
+ // Querying
+ try (Statement stmt = con.createStatement()) {
+ stmt.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
+ "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
+ "RETURN baeldung, tesla");
+
+ ResultSet rs = stmt.executeQuery("MATCH (company:Company)-[:owns]-> (car:Car)" +
+ "WHERE car.make='tesla' and car.model='modelX'" +
+ "RETURN company.name");
+
+ while (rs.next()) {
+ Assert.assertEquals(rs.getString("company.name"), "Baeldung");
+ }
+ }
+ con.close();
+ }
+}
diff --git a/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java b/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java
new file mode 100644
index 0000000000..1ff01b93a1
--- /dev/null
+++ b/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java
@@ -0,0 +1,167 @@
+package com.baeldung.neo4j;
+
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.neo4j.graphdb.GraphDatabaseService;
+import org.neo4j.graphdb.Label;
+import org.neo4j.graphdb.Node;
+import org.neo4j.graphdb.NotFoundException;
+import org.neo4j.graphdb.RelationshipType;
+import org.neo4j.graphdb.Result;
+import org.neo4j.graphdb.factory.GraphDatabaseFactory;
+
+public class Neo4jLiveTest {
+
+ private static GraphDatabaseService graphDb;
+
+ @Before
+ public void setUp() {
+ GraphDatabaseFactory graphDbFactory = new GraphDatabaseFactory();
+ graphDb = graphDbFactory.newEmbeddedDatabase(new File("data/cars"));
+ }
+
+ @After
+ public void tearDown() {
+ graphDb.shutdown();
+ }
+
+ @Test
+ public void testPersonCar() {
+ graphDb.beginTx();
+ Node car = graphDb.createNode(Label.label("Car"));
+ car.setProperty("make", "tesla");
+ car.setProperty("model", "model3");
+
+ Node owner = graphDb.createNode(Label.label("Person"));
+ owner.setProperty("firstName", "baeldung");
+ owner.setProperty("lastName", "baeldung");
+
+ owner.createRelationshipTo(car, RelationshipType.withName("owner"));
+
+ Result result = graphDb.execute("MATCH (c:Car) <-[owner]- (p:Person) " +
+ "WHERE c.make = 'tesla'" +
+ "RETURN p.firstName, p.lastName");
+
+ Map firstResult = result.next();
+ Assert.assertEquals("baeldung", firstResult.get("p.firstName"));
+ }
+
+ @Test
+ public void testCreateNode() {
+
+ graphDb.beginTx();
+
+ Result result = graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"})" +
+ "RETURN baeldung");
+
+ Map firstResult = result.next();
+ Node firstNode = (Node) firstResult.get("baeldung");
+ Assert.assertEquals(firstNode.getProperty("name"), "Baeldung");
+ }
+
+ @Test
+ public void testCreateNodeAndLink() {
+ graphDb.beginTx();
+
+ Result result = graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
+ "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
+ "RETURN baeldung, tesla");
+
+ Map firstResult = result.next();
+ Assert.assertTrue(firstResult.containsKey("baeldung"));
+ Assert.assertTrue(firstResult.containsKey("tesla"));
+ }
+
+ @Test
+ public void testFindAndReturn() {
+ graphDb.beginTx();
+
+ graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
+ "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
+ "RETURN baeldung, tesla");
+
+ Result result = graphDb.execute("MATCH (company:Company)-[:owns]-> (car:Car)" +
+ "WHERE car.make='tesla' and car.model='modelX'" +
+ "RETURN company.name");
+
+ Map firstResult = result.next();
+ Assert.assertEquals(firstResult.get("company.name"), "Baeldung");
+ }
+
+ @Test
+ public void testUpdate() {
+ graphDb.beginTx();
+
+ graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
+ "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
+ "RETURN baeldung, tesla");
+
+ Result result = graphDb.execute("MATCH (car:Car)" +
+ "WHERE car.make='tesla'" +
+ " SET car.milage=120" +
+ " SET car :Car:Electro" +
+ " SET car.model=NULL" +
+ " RETURN car");
+
+ Map firstResult = result.next();
+ Node car = (Node) firstResult.get("car");
+
+ Assert.assertEquals(car.getProperty("milage"), 120L);
+ Assert.assertEquals(car.getLabels(), Arrays.asList(Label.label("Car"), Label.label("Electro")));
+
+ try {
+ car.getProperty("model");
+ Assert.fail();
+ } catch (NotFoundException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testDelete() {
+ graphDb.beginTx();
+
+ graphDb.execute("CREATE (baeldung:Company {name:\"Baeldung\"}) " +
+ "-[:owns]-> (tesla:Car {make: 'tesla', model: 'modelX'})" +
+ "RETURN baeldung, tesla");
+
+ graphDb.execute("MATCH (company:Company)" +
+ " WHERE company.name='Baeldung'" +
+ " DELETE company");
+
+ Result result = graphDb.execute("MATCH (company:Company)" +
+ " WHERE company.name='Baeldung'" +
+ " RETURN company");
+
+ Assert.assertFalse(result.hasNext());
+ }
+
+ @Test
+ public void testBindings() {
+ graphDb.beginTx();
+
+ Map params = new HashMap<>();
+ params.put("name", "baeldung");
+ params.put("make", "tesla");
+ params.put("model", "modelS");
+
+ Result result = graphDb.execute("CREATE (baeldung:Company {name:$name}) " +
+ "-[:owns]-> (tesla:Car {make: $make, model: $model})" +
+ "RETURN baeldung, tesla", params);
+
+ Map firstResult = result.next();
+ Assert.assertTrue(firstResult.containsKey("baeldung"));
+ Assert.assertTrue(firstResult.containsKey("tesla"));
+
+ Node car = (Node) firstResult.get("tesla");
+ Assert.assertEquals(car.getProperty("model"), "modelS");
+ }
+}
diff --git a/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java b/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java
new file mode 100644
index 0000000000..06b31667dd
--- /dev/null
+++ b/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java
@@ -0,0 +1,49 @@
+package com.baeldung.neo4j;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.neo4j.ogm.config.Configuration;
+import org.neo4j.ogm.model.Result;
+import org.neo4j.ogm.session.Session;
+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");
+
+ SessionFactory factory = new SessionFactory(conf, "com.baeldung.spring.data.neo4j.domain");
+ Session session = factory.openSession();
+
+ Car tesla = new Car("tesla", "modelS");
+ Company baeldung = new Company("baeldung");
+
+ baeldung.setCar(tesla);
+
+ session.save(baeldung);
+
+ Assert.assertEquals(1, session.countEntitiesOfType(Company.class));
+
+ Map params = new HashMap<>();
+ params.put("make", "tesla");
+ Result result = session.query("MATCH (car:Car) <-[:owns]- (company:Company)" +
+ " WHERE car.make=$make" +
+ " RETURN company", params);
+
+ Map firstResult = result.iterator().next();
+
+ Assert.assertEquals(firstResult.size(), 1);
+
+ Company actual = (Company) firstResult.get("company");
+ Assert.assertEquals(actual.getName(), baeldung.getName());
+ }
+}
diff --git a/spring-data-neo4j/src/test/resources/logback.xml b/spring-data-neo4j/src/test/resources/logback.xml
new file mode 100644
index 0000000000..39a6538324
--- /dev/null
+++ b/spring-data-neo4j/src/test/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ %d %5p %40.40c:%4L - %m%n
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-data-rest/pom.xml b/spring-data-rest/pom.xml
index da5d844211..4e8001ae7b 100644
--- a/spring-data-rest/pom.xml
+++ b/spring-data-rest/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.4.2.RELEASE
+ 1.4.4.RELEASE
diff --git a/spring-data-rest/src/main/java/com/baeldung/config/ValidatorEventRegister.java b/spring-data-rest/src/main/java/com/baeldung/config/ValidatorEventRegister.java
index 89ab848e81..8f14d6c1c6 100644
--- a/spring-data-rest/src/main/java/com/baeldung/config/ValidatorEventRegister.java
+++ b/spring-data-rest/src/main/java/com/baeldung/config/ValidatorEventRegister.java
@@ -22,9 +22,15 @@ public class ValidatorEventRegister implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
List events = Arrays.asList("beforeCreate", "afterCreate", "beforeSave", "afterSave", "beforeLinkSave", "afterLinkSave", "beforeDelete", "afterDelete");
-
+
for (Map.Entry entry : validators.entrySet()) {
- events.stream().filter(p -> entry.getKey().startsWith(p)).findFirst().ifPresent(p -> validatingRepositoryEventListener.addValidator(p, entry.getValue()));
+ events
+ .stream()
+ .filter(p -> entry
+ .getKey()
+ .startsWith(p))
+ .findFirst()
+ .ifPresent(p -> validatingRepositoryEventListener.addValidator(p, entry.getValue()));
}
}
}
diff --git a/spring-data-rest/src/main/java/com/baeldung/exception/handlers/RestResponseEntityExceptionHandler.java b/spring-data-rest/src/main/java/com/baeldung/exception/handlers/RestResponseEntityExceptionHandler.java
index ee84738e7a..aa24fccac7 100644
--- a/spring-data-rest/src/main/java/com/baeldung/exception/handlers/RestResponseEntityExceptionHandler.java
+++ b/spring-data-rest/src/main/java/com/baeldung/exception/handlers/RestResponseEntityExceptionHandler.java
@@ -1,16 +1,17 @@
package com.baeldung.exception.handlers;
-import java.util.stream.Collectors;
-
import org.springframework.data.rest.core.RepositoryConstraintViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+import java.util.stream.Collectors;
+
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@@ -18,8 +19,13 @@ public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionH
public ResponseEntity handleAccessDeniedException(Exception ex, WebRequest request) {
RepositoryConstraintViolationException nevEx = (RepositoryConstraintViolationException) ex;
- String errors = nevEx.getErrors().getAllErrors().stream().map(p -> p.toString()).collect(Collectors.joining("\n"));
- return new ResponseEntity(errors, new HttpHeaders(), HttpStatus.NOT_ACCEPTABLE);
+ String errors = nevEx
+ .getErrors()
+ .getAllErrors()
+ .stream()
+ .map(ObjectError::toString)
+ .collect(Collectors.joining("\n"));
+ return new ResponseEntity<>(errors, new HttpHeaders(), HttpStatus.NOT_ACCEPTABLE);
}
}
\ No newline at end of file
diff --git a/spring-data-rest/src/main/test/com/baeldung/validator/SpringDataRestValidatorTest.java b/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorTest.java
similarity index 75%
rename from spring-data-rest/src/main/test/com/baeldung/validator/SpringDataRestValidatorTest.java
rename to spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorTest.java
index b185c6d5ab..300fc081d3 100644
--- a/spring-data-rest/src/main/test/com/baeldung/validator/SpringDataRestValidatorTest.java
+++ b/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorTest.java
@@ -1,100 +1,86 @@
-package com.baeldung.validator;
-
-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.MockMvcResultHandlers.print;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-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.SpringApplicationConfiguration;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.web.WebAppConfiguration;
-import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.ResultActions;
-import org.springframework.test.web.servlet.ResultMatcher;
-import org.springframework.web.context.WebApplicationContext;
-
-import com.baeldung.SpringDataRestApplication;
-import com.baeldung.models.WebsiteUser;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@SpringApplicationConfiguration(classes = SpringDataRestApplication.class)
-@WebAppConfiguration
-public class SpringDataRestValidatorTest {
- public static final String URL = "http://localhost";
-
- private MockMvc mockMvc;
-
- @Autowired
- protected WebApplicationContext wac;
-
- @Before
- public void setup() {
- mockMvc = webAppContextSetup(wac).build();
- }
-
- @Test
- public void whenStartingApplication_thenCorrectStatusCode() throws Exception {
- mockMvc.perform(get("/users")).andExpect(status().is2xxSuccessful());
- };
-
- @Test
- public void whenAddingNewCorrectUser_thenCorrectStatusCodeAndResponse() throws Exception {
- WebsiteUser user = new WebsiteUser();
- user.setEmail("john.doe@john.com");
- user.setName("John Doe");
-
- mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user)))
- .andExpect(status().is2xxSuccessful())
- .andExpect(redirectedUrl("http://localhost/users/1"));
- }
-
- @Test
- public void whenAddingNewUserWithoutName_thenErrorStatusCodeAndResponse() throws Exception {
- WebsiteUser user = new WebsiteUser();
- user.setEmail("john.doe@john.com");
-
- mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user)))
- .andExpect(status().isNotAcceptable())
- .andExpect(redirectedUrl(null));
- }
-
- @Test
- public void whenAddingNewUserWithEmptyName_thenErrorStatusCodeAndResponse() throws Exception {
- WebsiteUser user = new WebsiteUser();
- user.setEmail("john.doe@john.com");
- user.setName("");
- mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user)))
- .andExpect(status().isNotAcceptable())
- .andExpect(redirectedUrl(null));
- }
-
- @Test
- public void whenAddingNewUserWithoutEmail_thenErrorStatusCodeAndResponse() throws Exception {
- WebsiteUser user = new WebsiteUser();
- user.setName("John Doe");
-
- mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user)))
- .andExpect(status().isNotAcceptable())
- .andExpect(redirectedUrl(null));
- }
-
- @Test
- public void whenAddingNewUserWithEmptyEmail_thenErrorStatusCodeAndResponse() throws Exception {
- WebsiteUser user = new WebsiteUser();
- user.setName("John Doe");
- user.setEmail("");
- mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user)))
- .andExpect(status().isNotAcceptable())
- .andExpect(redirectedUrl(null));
- }
-
-}
+package com.baeldung.validator;
+
+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.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 com.baeldung.SpringDataRestApplication;
+import com.baeldung.models.WebsiteUser;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = SpringDataRestApplication.class)
+@WebAppConfiguration
+public class SpringDataRestValidatorTest {
+ public static final String URL = "http://localhost";
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ protected WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ mockMvc = webAppContextSetup(wac).build();
+ }
+
+ @Test
+ public void whenStartingApplication_thenCorrectStatusCode() throws Exception {
+ mockMvc.perform(get("/users")).andExpect(status().is2xxSuccessful());
+ };
+
+ @Test
+ public void whenAddingNewCorrectUser_thenCorrectStatusCodeAndResponse() throws Exception {
+ WebsiteUser user = new WebsiteUser();
+ user.setEmail("john.doe@john.com");
+ user.setName("John Doe");
+
+ mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().is2xxSuccessful()).andExpect(redirectedUrl("http://localhost/users/1"));
+ }
+
+ @Test
+ public void whenAddingNewUserWithoutName_thenErrorStatusCodeAndResponse() throws Exception {
+ WebsiteUser user = new WebsiteUser();
+ user.setEmail("john.doe@john.com");
+
+ mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().isNotAcceptable()).andExpect(redirectedUrl(null));
+ }
+
+ @Test
+ public void whenAddingNewUserWithEmptyName_thenErrorStatusCodeAndResponse() throws Exception {
+ WebsiteUser user = new WebsiteUser();
+ user.setEmail("john.doe@john.com");
+ user.setName("");
+ mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().isNotAcceptable()).andExpect(redirectedUrl(null));
+ }
+
+ @Test
+ public void whenAddingNewUserWithoutEmail_thenErrorStatusCodeAndResponse() throws Exception {
+ WebsiteUser user = new WebsiteUser();
+ user.setName("John Doe");
+
+ mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().isNotAcceptable()).andExpect(redirectedUrl(null));
+ }
+
+ @Test
+ public void whenAddingNewUserWithEmptyEmail_thenErrorStatusCodeAndResponse() throws Exception {
+ WebsiteUser user = new WebsiteUser();
+ user.setName("John Doe");
+ user.setEmail("");
+ mockMvc.perform(post("/users", user).contentType(MediaType.APPLICATION_JSON).content(new ObjectMapper().writeValueAsString(user))).andExpect(status().isNotAcceptable()).andExpect(redirectedUrl(null));
+ }
+
+}
diff --git a/spring-hibernate4/.gitignore b/spring-hibernate4/.gitignore
index 83c05e60c8..d31cc4c619 100644
--- a/spring-hibernate4/.gitignore
+++ b/spring-hibernate4/.gitignore
@@ -10,4 +10,6 @@
# Packaged files #
*.jar
*.war
-*.ear
\ No newline at end of file
+*.ear
+/target/
+/target/
diff --git a/spring-hibernate4/README.md b/spring-hibernate4/README.md
index 7888e8b4ee..02888c4ad0 100644
--- a/spring-hibernate4/README.md
+++ b/spring-hibernate4/README.md
@@ -12,6 +12,7 @@
- [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)
### Quick Start
@@ -22,3 +23,4 @@ mvn install
mvn cargo:run
```
- **note**: starts on port `8082`
+
diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java b/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java
index ba54985853..e522dab48d 100644
--- a/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java
+++ b/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java
@@ -7,32 +7,31 @@ import org.hibernate.service.ServiceRegistry;
public class HibernateAnnotationUtil {
- private static SessionFactory sessionFactory;
-
- private static SessionFactory buildSessionFactory() {
+ private static SessionFactory sessionFactory;
+
+ private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate-annotation.cfg.xml
- Configuration configuration = new Configuration();
- configuration.configure("hibernate-annotation.cfg.xml");
- System.out.println("Hibernate Annotation Configuration loaded");
-
- ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
- System.out.println("Hibernate Annotation serviceRegistry created");
-
- SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
-
-
+ Configuration configuration = new Configuration();
+ configuration.configure("hibernate-annotation.cfg.xml");
+ System.out.println("Hibernate Annotation Configuration loaded");
+
+ ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
+ System.out.println("Hibernate Annotation serviceRegistry created");
+
+ SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
+
return sessionFactory;
- }
- catch (Throwable ex) {
+ } catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
-
- public static SessionFactory getSessionFactory() {
- if(sessionFactory == null) sessionFactory = buildSessionFactory();
+
+ public static SessionFactory getSessionFactory() {
+ if (sessionFactory == null)
+ sessionFactory = buildSessionFactory();
return sessionFactory;
}
}
diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java b/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java
index d5c41bcfab..2bc5e514f7 100644
--- a/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java
+++ b/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMain.java
@@ -13,48 +13,48 @@ import com.baeldung.hibernate.oneToMany.model.Items;
public class HibernateOneToManyAnnotationMain {
- public static void main(String[] args) {
+ public static void main(String[] args) {
- Cart cart = new Cart();
- cart.setName("MyCart");
-
- Items item1 = new Items("I10", 10, 1, cart);
- Items item2 = new Items("I20", 20, 2, cart);
- Set itemsSet = new HashSet();
- itemsSet.add(item1); itemsSet.add(item2);
-
- cart.setItems(itemsSet);
- cart.setTotal(10*1 + 20*2);
-
- SessionFactory sessionFactory = null;
- Session session = null;
- Transaction tx = null;
- try{
- //Get Session
- sessionFactory = HibernateAnnotationUtil.getSessionFactory();
- session = sessionFactory.getCurrentSession();
- System.out.println("Session created");
- //start transaction
- tx = session.beginTransaction();
- //Save the Model object
- session.save(cart);
- session.save(item1);
- session.save(item2);
- //Commit transaction
- tx.commit();
- System.out.println("Cart ID="+cart.getId());
- System.out.println("item1 ID="+item1.getId()+", Foreign Key Cart ID="+item1.getCart().getId());
- System.out.println("item2 ID="+item2.getId()+", Foreign Key Cart ID="+item1.getCart().getId());
-
- }catch(Exception e){
- System.out.println("Exception occured. "+e.getMessage());
- e.printStackTrace();
- }finally{
- if(!sessionFactory.isClosed()){
- System.out.println("Closing SessionFactory");
- sessionFactory.close();
- }
- }
- }
+ Cart cart = new Cart();
+
+ Items item1 = new Items(cart);
+ Items item2 = new Items(cart);
+ Set itemsSet = new HashSet();
+ itemsSet.add(item1);
+ itemsSet.add(item2);
+
+ cart.setItems(itemsSet);
+
+
+ SessionFactory sessionFactory = null;
+ Session session = null;
+ Transaction tx = null;
+ try {
+ // Get Session
+ sessionFactory = HibernateAnnotationUtil.getSessionFactory();
+ session = sessionFactory.getCurrentSession();
+ System.out.println("Session created");
+ // start transaction
+ tx = session.beginTransaction();
+ // Save the Model object
+ session.save(cart);
+ session.save(item1);
+ session.save(item2);
+ // Commit transaction
+ tx.commit();
+ System.out.println("Cart ID=" + cart.getId());
+ System.out.println("item1 ID=" + item1.getId() + ", Foreign Key Cart ID=" + item1.getCart().getId());
+ System.out.println("item2 ID=" + item2.getId() + ", Foreign Key Cart ID=" + item1.getCart().getId());
+
+ } catch (Exception e) {
+ System.out.println("Exception occured. " + e.getMessage());
+ e.printStackTrace();
+ } finally {
+ if (!sessionFactory.isClosed()) {
+ System.out.println("Closing SessionFactory");
+ sessionFactory.close();
+ }
+ }
+ }
}
diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java b/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java
index fdbfda2279..b8b991831e 100644
--- a/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java
+++ b/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Cart.java
@@ -11,46 +11,33 @@ import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
-@Table(name="CART")
+@Table(name = "CART")
public class Cart {
- @Id
- @GeneratedValue(strategy=GenerationType.IDENTITY)
- @Column(name="cart_id")
- private long id;
-
- @Column(name="total")
- private double total;
-
- @Column(name="name")
- private String name;
-
- @OneToMany(mappedBy="cart")
- private Set items;
-
- public long getId() {
- return id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public double getTotal() {
- return total;
- }
- public void setTotal(double total) {
- this.total = total;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Set getItems() {
- return items;
- }
- public void setItems(Set items) {
- this.items = items;
- }
-
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "cart_id")
+ private long id;
+
+
+ @OneToMany(mappedBy = "cart")
+ private Set items;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+
+ public Set getItems() {
+ return items;
+ }
+
+ public void setItems(Set items) {
+ this.items = items;
+ }
+
}
diff --git a/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java b/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java
index 630bf0a12e..f63a4855b5 100644
--- a/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java
+++ b/spring-hibernate4/src/main/java/com/baeldung/hibernate/oneToMany/model/Items.java
@@ -10,65 +10,41 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
-@Table(name="ITEMS")
+@Table(name = "ITEMS")
public class Items {
- @Id
- @GeneratedValue(strategy=GenerationType.IDENTITY)
- @Column(name="id")
- private long id;
-
- @Column(name="item_id")
- private String itemId;
-
- @Column(name="item_total")
- private double itemTotal;
-
- @Column(name="quantity")
- private int quantity;
-
- @ManyToOne
- @JoinColumn(name="cart_id", nullable=false)
- private Cart cart;
-
- //Hibernate requires no-args constructor
- public Items(){}
-
- public Items(String itemId, double total, int qty, Cart c){
- this.itemId=itemId;
- this.itemTotal=total;
- this.quantity=qty;
- this.cart=c;
- }
- public String getItemId() {
- return itemId;
- }
- public void setItemId(String itemId) {
- this.itemId = itemId;
- }
- public double getItemTotal() {
- return itemTotal;
- }
- public void setItemTotal(double itemTotal) {
- this.itemTotal = itemTotal;
- }
- public int getQuantity() {
- return quantity;
- }
- public void setQuantity(int quantity) {
- this.quantity = quantity;
- }
- public Cart getCart() {
- return cart;
- }
- public void setCart(Cart cart) {
- this.cart = cart;
- }
- public long getId() {
- return id;
- }
- public void setId(long id) {
- this.id = id;
- }
-
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+
+
+ @ManyToOne
+ @JoinColumn(name = "cart_id", nullable = false)
+ private Cart cart;
+
+ // Hibernate requires no-args constructor
+ public Items() {
+ }
+
+ public Items(Cart c) {
+ this.cart = c;
+ }
+
+ public Cart getCart() {
+ return cart;
+ }
+
+ public void setCart(Cart cart) {
+ this.cart = cart;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
}
diff --git a/spring-hibernate4/src/main/resources/one_to_many.sql b/spring-hibernate4/src/main/resources/one_to_many.sql
index 7887ff7d9c..2eb48fc262 100644
--- a/spring-hibernate4/src/main/resources/one_to_many.sql
+++ b/spring-hibernate4/src/main/resources/one_to_many.sql
@@ -1,16 +1,11 @@
CREATE TABLE `Cart` (
`cart_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `total` decimal(10,0) NOT NULL,
- `name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`cart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
CREATE TABLE `Items` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`cart_id` int(11) unsigned NOT NULL,
- `item_id` varchar(10) NOT NULL,
- `item_total` decimal(10,0) NOT NULL,
- `quantity` int(3) NOT NULL,
PRIMARY KEY (`id`),
KEY `cart_id` (`cart_id`),
CONSTRAINT `items_ibfk_1` FOREIGN KEY (`cart_id`) REFERENCES `Cart` (`cart_id`)
diff --git a/spring-hibernate4/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainTest.java b/spring-hibernate4/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainTest.java
index 742bb2b470..e2d2bf9143 100644
--- a/spring-hibernate4/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainTest.java
+++ b/spring-hibernate4/src/test/java/com/baeldung/hibernate/oneToMany/main/HibernateOneToManyAnnotationMainTest.java
@@ -1,102 +1,94 @@
-
package com.baeldung.hibernate.oneToMany.main;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
-import com.baeldung.hibernate.oneToMany.model.Cart;
-import com.baeldung.hibernate.oneToMany.model.Items;
import java.util.HashSet;
import java.util.Set;
-import static org.hamcrest.Matchers.hasSize;
+
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.service.ServiceRegistry;
+import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import static org.junit.Assert.*;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import com.baeldung.hibernate.oneToMany.model.Cart;
+import com.baeldung.hibernate.oneToMany.model.Items;
-//@RunWith(SpringJUnit4ClassRunner.class)
public class HibernateOneToManyAnnotationMainTest {
-
- private static SessionFactory sessionFactory;
- private Session session;
-
- public HibernateOneToManyAnnotationMainTest() {
- }
-
-
- @BeforeClass
- public static void beforeTests() {
- Configuration configuration = new Configuration().addAnnotatedClass(Cart.class).addAnnotatedClass(Items.class).setProperty("hibernate.dialect", HSQLDialect.class.getName()).setProperty("hibernate.connection.driver_class", org.hsqldb.jdbcDriver.class.getName())
- .setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:test").setProperty("hibernate.connection.username", "sa").setProperty("hibernate.connection.password", "").setProperty("hibernate.hbm2ddl.auto", "update");
- ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
- sessionFactory = configuration.buildSessionFactory(serviceRegistry);
- }
-
- @Before
- public void setUp() {
- session = sessionFactory.openSession();
- session.beginTransaction();
-
- }
-
- @Test
- public void givenSession_checkIfDatabaseIsEmpty(){
- Cart cart = (Cart) session.get(Cart.class, new Long(1));
- assertNull(cart);
-
- }
-
-
-
-
+ private static SessionFactory sessionFactory;
+
+ private Session session;
+
+ public HibernateOneToManyAnnotationMainTest() {
+ }
+
+ @BeforeClass
+ public static void beforeTests() {
+ Configuration configuration = new Configuration().addAnnotatedClass(Cart.class).addAnnotatedClass(Items.class)
+ .setProperty("hibernate.dialect", HSQLDialect.class.getName())
+ .setProperty("hibernate.connection.driver_class", org.hsqldb.jdbcDriver.class.getName())
+ .setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:test")
+ .setProperty("hibernate.connection.username", "sa").setProperty("hibernate.connection.password", "")
+ .setProperty("hibernate.hbm2ddl.auto", "update");
+ ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
+ .applySettings(configuration.getProperties()).build();
+ sessionFactory = configuration.buildSessionFactory(serviceRegistry);
+ }
+
+ @Before
+ public void setUp() {
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ }
+
+ @Test
+ public void givenSession_checkIfDatabaseIsEmpty() {
+ Cart cart = (Cart) session.get(Cart.class, new Long(1));
+ assertNull(cart);
+
+ }
+
+ @Test
+ public void givenSession_checkIfDatabaseIsPopulated_afterCommit() {
+ Cart cart = new Cart();
+ Set cartItems = new HashSet<>();
+ cartItems = cart.getItems();
+ Assert.assertNull(cartItems);
+ Items item1 = new Items();
+ item1.setCart(cart);
+ assertNotNull(item1);
+ Set itemsSet = new HashSet();
+ itemsSet.add(item1);
+ assertNotNull(itemsSet);
+ cart.setItems(itemsSet);
+ assertNotNull(cart);
+ session.persist(cart);
+ session.getTransaction().commit();
+ session.close();
+
+ session = sessionFactory.openSession();
+ session.beginTransaction();
+ cart = (Cart) session.get(Cart.class, new Long(1));
+ assertNotNull(cart);
+ }
+
+ @After
+ public void tearDown() {
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ @AfterClass
+ public static void afterTests() {
+ sessionFactory.close();
+ }
- @Test
- public void testAddItemsToCart() {
- Cart cart = new Cart();
- Set cartItems = new HashSet<>();
- cartItems = cart.getItems();
- Assert.assertNull(cartItems);
- Items item1 = new Items("I10", 10, 1, cart);
- assertNotNull(item1);
- Set itemsSet = new HashSet();
- cart.setItems(itemsSet);
- assertNotNull(cart);
- System.out.println("Items added to cart");
-
- }
-
- @Test
- public void givenSession_checkIfDatabaseIsPopulated_afterCommit(){
- Cart cart = new Cart();
- Set cartItems = new HashSet<>();
- cartItems = cart.getItems();
- Assert.assertNull(cartItems);
- Items item1 = new Items();
- item1.setItemId("I10");
- item1.setItemTotal(10);
- item1.setQuantity(1);
- item1.setCart(cart);
- assertNotNull(item1);
- Set itemsSet = new HashSet();
- itemsSet.add(item1);
- assertNotNull(itemsSet);
- cart.setItems(itemsSet);
- assertNotNull(cart);
- session.persist(cart);
- session.getTransaction().commit();
- cart = (Cart) session.get(Cart.class, new Long(1));
- assertNotNull(cart);
- session.close();
-
- }
-
-
}
diff --git a/spring-jersey/README.md b/spring-jersey/README.md
index 2767ceb9a7..8b2eecc0e1 100644
--- a/spring-jersey/README.md
+++ b/spring-jersey/README.md
@@ -1,3 +1,5 @@
=========
## 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)
diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml
index 293850d41e..41ebb9a6b5 100644
--- a/spring-jersey/pom.xml
+++ b/spring-jersey/pom.xml
@@ -9,7 +9,7 @@
war
- 2.25
+ 2.25.1
1.7.22
1.1.8
4.12
diff --git a/spring-jersey/src/main/java/com/baeldung/client/rest/RestClient.java b/spring-jersey/src/main/java/com/baeldung/client/rest/RestClient.java
index 0e45b68b14..34f7d45601 100644
--- a/spring-jersey/src/main/java/com/baeldung/client/rest/RestClient.java
+++ b/spring-jersey/src/main/java/com/baeldung/client/rest/RestClient.java
@@ -18,7 +18,7 @@ public class RestClient {
}
public Employee getJsonEmployee(int id) {
- return client.target(REST_URI).path(new Integer(id).toString()).request(MediaType.APPLICATION_JSON).get(Employee.class);
+ return client.target(REST_URI).path(String.valueOf(id)).request(MediaType.APPLICATION_JSON).get(Employee.class);
}
public Response createXmlEmployee(Employee emp) {
@@ -26,6 +26,6 @@ public class RestClient {
}
public Employee getXmlEmployee(int id) {
- return client.target(REST_URI).path(new Integer(id).toString()).request(MediaType.APPLICATION_XML).get(Employee.class);
+ return client.target(REST_URI).path(String.valueOf(id)).request(MediaType.APPLICATION_XML).get(Employee.class);
}
}
diff --git a/spring-jooq/pom.xml b/spring-jooq/pom.xml
index bf0dffd68c..195c0b8514 100644
--- a/spring-jooq/pom.xml
+++ b/spring-jooq/pom.xml
@@ -1,215 +1,215 @@
- 4.0.0
- com.baeldung
- jooq-spring
- 0.0.1-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
+ jooq-spring
+ 0.0.1-SNAPSHOT
-
-
-
-
- org.springframework.boot
- spring-boot-dependencies
- 1.4.2.RELEASE
- pom
- import
-
-
-
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 1.4.4.RELEASE
+ pom
+ import
+
+
+
-
-
-
- org.jooq
- jooq
-
+
+
+
+ org.jooq
+ jooq
+
-
-
- com.h2database
- h2
-
+
+
+ com.h2database
+ h2
+
-
-
- org.springframework
- spring-context
-
-
- org.springframework
- spring-jdbc
-
-
- org.springframework.boot
- spring-boot-starter-jooq
-
+
+
+ org.springframework
+ spring-context
+
+
+ org.springframework
+ spring-jdbc
+
+
+ org.springframework.boot
+ spring-boot-starter-jooq
+
-
-
- org.slf4j
- slf4j-api
- runtime
-
-
- ch.qos.logback
- logback-classic
- runtime
-
+
+
+ org.slf4j
+ slf4j-api
+ runtime
+
+
+ ch.qos.logback
+ logback-classic
+ runtime
+
-
-
- junit
- junit
- test
-
-
- org.springframework
- spring-test
- test
-
-
- org.springframework.boot
- spring-boot-starter-test
-
-
-
+
+
+ junit
+ junit
+ test
+
+
+ org.springframework
+ spring-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
-
-
-
- org.codehaus.mojo
- properties-maven-plugin
- ${properties-maven-plugin.version}
-
-
- initialize
-
- read-project-properties
-
-
-
- src/main/resources/intro_config.properties
-
-
-
-
-
+
-
- org.codehaus.mojo
- sql-maven-plugin
- ${sql-maven-plugin.version}
-
-
- initialize
-
- execute
-
-
- ${db.driver}
- ${db.url}
- ${db.username}
- ${db.password}
-
- src/main/resources/intro_schema.sql
-
-
-
-
-
-
- com.h2database
- h2
- ${com.h2database.version}
-
-
-
+
+
+
+ org.codehaus.mojo
+ properties-maven-plugin
+ ${properties-maven-plugin.version}
+
+
+ initialize
+
+ read-project-properties
+
+
+
+ src/main/resources/intro_config.properties
+
+
+
+
+
-
- org.jooq
- jooq-codegen-maven
- ${org.jooq.version}
-
-
- generate-sources
-
- generate
-
-
-
- ${db.driver}
- ${db.url}
- ${db.username}
- ${db.password}
-
-
-
- com.baeldung.jooq.introduction.db
- src/main/java
-
-
-
-
-
-
+
+ org.codehaus.mojo
+ sql-maven-plugin
+ ${sql-maven-plugin.version}
+
+
+ initialize
+
+ execute
+
+
+ ${db.driver}
+ ${db.url}
+ ${db.username}
+ ${db.password}
+
+ src/main/resources/intro_schema.sql
+
+
+
+
+
+
+ com.h2database
+ h2
+ ${com.h2database.version}
+
+
+
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- 1.8
- 1.8
-
-
+
+ org.jooq
+ jooq-codegen-maven
+ ${org.jooq.version}
+
+
+ generate-sources
+
+ generate
+
+
+
+ ${db.driver}
+ ${db.url}
+ ${db.username}
+ ${db.password}
+
+
+
+ com.baeldung.jooq.introduction.db
+ src/main/java
+
+
+
+
+
+
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- **/*IntegrationTest.java
- **/*LiveTest.java
-
-
-
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
-
-
-
-
-
- org.eclipse.m2e
- lifecycle-mapping
- ${lifecycle-mapping.version}
-
-
-
-
-
- org.jooq
-
- jooq-codegen-maven
-
-
- [3.7.3,)
-
-
- generate
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ **/*IntegrationTest.java
+ **/*LiveTest.java
+
+
+
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ ${lifecycle-mapping.version}
+
+
+
+
+
+ org.jooq
+
+ jooq-codegen-maven
+
+
+ [3.7.3,)
+
+
+ generate
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -245,21 +245,21 @@