diff --git a/activejdbc/pom.xml b/activejdbc/pom.xml
new file mode 100644
index 0000000000..7a49d37411
--- /dev/null
+++ b/activejdbc/pom.xml
@@ -0,0 +1,129 @@
+
+ 4.0.0
+ com.baeldung
+ activejdbc
+ 1.0-SNAPSHOT
+ jar
+ activejdbc
+ http://maven.apache.org
+
+ UTF-8
+ 1.4.13
+ development.test,development
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.0
+
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+ org.javalite
+ activejdbc-instrumentation
+ ${activejdbc.version}
+
+
+ process-classes
+
+ instrument
+
+
+
+
+
+ org.javalite
+ db-migrator-maven-plugin
+ ${activejdbc.version}
+
+ ${project.basedir}/src/main/resources/database.properties
+ ${environments}
+
+
+
+ mysql
+ mysql-connector-java
+ 5.1.34
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.18.1
+
+ brief
+ true
+ false
+
+ **/*Spec*.java
+ **/*Test*.java
+
+
+ **/helpers/*
+ **/*$*
+
+
+
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.javalite
+ activejdbc
+ ${activejdbc.version}
+
+
+ opensymphony
+ oscache
+
+
+
+
+ mysql
+ mysql-connector-java
+ 5.1.34
+
+
+ org.slf4j
+ slf4j-simple
+ 1.7.9
+
+
+
+
+ snapshots1
+ JavaLite Snapshots1
+ http://repo.javalite.io/
+
+ true
+ always
+ warn
+
+
+
+
+
+ snapshots2
+ JavaLite Snapshots2
+ http://repo.javalite.io/
+
+ true
+ always
+ warn
+
+
+
+
diff --git a/activejdbc/src/main/java/com/baeldung/ActiveJDBCApp.java b/activejdbc/src/main/java/com/baeldung/ActiveJDBCApp.java
new file mode 100644
index 0000000000..8906d3e759
--- /dev/null
+++ b/activejdbc/src/main/java/com/baeldung/ActiveJDBCApp.java
@@ -0,0 +1,61 @@
+package com.baeldung;
+
+
+import com.baeldung.model.Employee;
+import com.baeldung.model.Role;
+import org.javalite.activejdbc.Base;
+import org.javalite.activejdbc.LazyList;
+import org.javalite.activejdbc.Model;
+
+public class ActiveJDBCApp
+{
+ public static void main( String[] args )
+ {
+ try {
+ Base.open();
+ ActiveJDBCApp app = new ActiveJDBCApp();
+ app.create();
+ app.update();
+ app.delete();
+ app.deleteCascade();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ Base.close();
+ }
+ }
+
+ protected void create() {
+ Employee employee = new Employee("Hugo","C","M","BN");
+ employee.saveIt();
+ employee.add(new Role("Java Developer","BN"));
+ LazyList all = Employee.findAll();
+ System.out.println(all.size());
+ }
+
+ protected void update() {
+ Employee employee = Employee.findFirst("first_name = ?","Hugo");
+ employee.set("last_namea","Choi").saveIt();
+ employee = Employee.findFirst("last_name = ?","Choi");
+ System.out.println(employee.getString("first_name") + " " + employee.getString("last_name"));
+ }
+
+ protected void delete() {
+ Employee employee = Employee.findFirst("first_name = ?","Hugo");
+ employee.delete();
+ employee = Employee.findFirst("last_name = ?","Choi");
+ if(null == employee){
+ System.out.println("No such Employee found!");
+ }
+ }
+
+ protected void deleteCascade() {
+ create();
+ Employee employee = Employee.findFirst("first_name = ?","Hugo");
+ employee.deleteCascade();
+ employee = Employee.findFirst("last_name = ?","C");
+ if(null == employee){
+ System.out.println("No such Employee found!");
+ }
+ }
+}
diff --git a/activejdbc/src/main/java/com/baeldung/model/Employee.java b/activejdbc/src/main/java/com/baeldung/model/Employee.java
new file mode 100644
index 0000000000..b7fa8aaf1f
--- /dev/null
+++ b/activejdbc/src/main/java/com/baeldung/model/Employee.java
@@ -0,0 +1,19 @@
+package com.baeldung.model;
+
+
+import org.javalite.activejdbc.Model;
+
+public class Employee extends Model {
+
+ public Employee(){
+
+ }
+
+ public Employee(String firstName, String lastName, String gender, String createdBy) {
+ set("first_name1",firstName);
+ set("last_name",lastName);
+ set("gender",gender);
+ set("created_by",createdBy);
+ }
+
+}
diff --git a/activejdbc/src/main/java/com/baeldung/model/Role.java b/activejdbc/src/main/java/com/baeldung/model/Role.java
new file mode 100644
index 0000000000..3f425dbe6b
--- /dev/null
+++ b/activejdbc/src/main/java/com/baeldung/model/Role.java
@@ -0,0 +1,18 @@
+package com.baeldung.model;
+
+
+import org.javalite.activejdbc.Model;
+import org.javalite.activejdbc.annotations.Table;
+
+@Table("EMP_ROLES")
+public class Role extends Model {
+
+ public Role(){
+
+ }
+
+ public Role(String role,String createdBy){
+ set("role_name",role);
+ set("created_by",createdBy);
+ }
+}
diff --git a/activejdbc/src/main/migration/_create_tables.sql b/activejdbc/src/main/migration/_create_tables.sql
new file mode 100644
index 0000000000..19fc1e72d7
--- /dev/null
+++ b/activejdbc/src/main/migration/_create_tables.sql
@@ -0,0 +1,25 @@
+# noinspection SqlNoDataSourceInspectionForFile
+
+create table organisation.employees
+(
+ id int not null auto_increment
+ primary key,
+ first_name varchar(100) not null,
+ last_name varchar(100) not null,
+ gender varchar(1) not null,
+ created_at datetime not null,
+ updated_at datetime null,
+ created_by varchar(100) not null,
+ updated_by varchar(100) null
+)ENGINE = InnoDB DEFAULT CHARSET = utf8;
+
+create table organisation.emp_roles
+(
+ id int not null auto_increment primary key,
+ employee_id int not null,
+ role_name varchar(100) not null,
+ created_at datetime not null,
+ updated_at datetime null,
+ created_by varchar(100) not null,
+ updated_by varchar(100) null
+)ENGINE = InnoDB DEFAULT CHARSET = utf8;
diff --git a/activejdbc/src/main/resources/database.properties b/activejdbc/src/main/resources/database.properties
new file mode 100644
index 0000000000..7e665fe8a1
--- /dev/null
+++ b/activejdbc/src/main/resources/database.properties
@@ -0,0 +1,10 @@
+development.driver=com.mysql.jdbc.Driver
+development.username=root
+development.password=123456
+development.url=jdbc:mysql://localhost/organisation
+
+
+development.test.driver=com.mysql.jdbc.Driver
+development.test.username=root
+development.test.password=123456
+development.test.url=jdbc:mysql://localhost/organisation_test
\ No newline at end of file
diff --git a/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java b/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java
new file mode 100644
index 0000000000..316dc34712
--- /dev/null
+++ b/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java
@@ -0,0 +1,51 @@
+package com.baeldung;
+
+import com.baeldung.model.Employee;
+import com.baeldung.model.Role;
+import org.javalite.activejdbc.test.DBSpec;
+import org.junit.Test;
+
+import java.util.List;
+
+public class ActiveJDBCAppTest extends DBSpec
+{
+ @Test
+ public void ifEmployeeCreated_thenIsValid() {
+ Employee employee = new Employee("B", "N", "M", "BN");
+ the(employee).shouldBe("valid");
+ }
+
+ @Test
+ public void ifEmployeeCreatedWithRoles_thenShouldPersist() {
+ Employee employee = new Employee("B", "N", "M", "BN");
+ employee.saveIt();
+ employee.add(new Role("Java Developer","BN"));
+ employee.add(new Role("Lead Java Developer","BN"));
+ a(Role.count()).shouldBeEqual(2);
+ List roles = employee.getAll(Role.class).orderBy("created_at");
+ the(roles.get(0).getRoleName()).shouldBeEqual("Java Developer");
+ the(roles.get(1).getRoleName()).shouldBeEqual("Lead Java Developer");
+ }
+
+ @Test
+ public void ifEmployeeCreatedWithRoles_whenNameUpdated_thenShouldShowNewName() {
+ Employee employee = new Employee("Binesh", "N", "M", "BN");
+ employee.saveIt();
+ employee.add(new Role("Java Developer","BN"));
+ employee.add(new Role("Lead Java Developer","BN"));
+ employee = Employee.findFirst("first_name = ?", "Binesh");
+ employee.set("last_name","Narayanan").saveIt();
+ Employee updated = Employee.findFirst("first_name = ?", "Binesh");
+ the(updated.getLastName()).shouldBeEqual("Narayanan");
+ }
+
+ @Test
+ public void ifEmployeeCreatedWithRoles_whenDeleted_thenShouldNotBeFound() {
+ Employee employee = new Employee("Binesh", "N", "M", "BN");
+ employee.saveIt();
+ employee.add(new Role("Java Developer","BN"));
+ employee.delete();
+ employee = Employee.findFirst("first_name = ?", "Binesh");
+ the(employee).shouldBeNull();
+ }
+}
diff --git a/core-java-8/src/main/java/com/baeldung/spliteratorAPI/Executor.java b/core-java-8/src/main/java/com/baeldung/spliteratorAPI/Executor.java
index b906acfad9..024d5dabdb 100644
--- a/core-java-8/src/main/java/com/baeldung/spliteratorAPI/Executor.java
+++ b/core-java-8/src/main/java/com/baeldung/spliteratorAPI/Executor.java
@@ -1,45 +1,19 @@
package com.baeldung.spliteratorAPI;
-import java.util.Arrays;
import java.util.List;
-import java.util.Spliterator;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.stream.Collectors;
-import java.util.stream.IntStream;
import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
public class Executor {
- public void executeCustomSpliterator() {
- Article article = new Article(Arrays.asList(new Author("Ahmad", 0), new Author("Eugen", 0), new Author("Alice", 1), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1),
- new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0),
- new Author("Alice", 1), new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0);
- Stream stream = IntStream.range(0, article.getListOfAuthors()
- .size())
- .mapToObj(article.getListOfAuthors()::get);
- System.out.println("count= " + countAutors(stream.parallel()));
- Spliterator spliterator = new RelatedAuthorSpliterator(article.getListOfAuthors());
- Stream stream2 = StreamSupport.stream(spliterator, true);
- System.out.println("count= " + countAutors(stream2.parallel()));
- }
- public void executeSpliterator() {
- Spliterator split1 = generateElements().spliterator();
- Spliterator split2 = split1.trySplit();
- ExecutorService service = Executors.newCachedThreadPool();
- service.execute(new Task(split1));
- service.execute(new Task(split2));
- }
+ public static int countAutors(Stream stream) {
+ RelatedAuthorCounter wordCounter = stream.reduce(new RelatedAuthorCounter(0, true),
+ RelatedAuthorCounter::accumulate, RelatedAuthorCounter::combine);
+ return wordCounter.getCounter();
+ }
- private static int countAutors(Stream stream) {
- RelatedAuthorCounter wordCounter = stream.reduce(new RelatedAuthorCounter(0, true), RelatedAuthorCounter::accumulate, RelatedAuthorCounter::combine);
- return wordCounter.getCounter();
- }
+ public static List generateElements() {
+ return Stream.generate(() -> new Article("Java")).limit(35000).collect(Collectors.toList());
+ }
- private List generateElements() {
- return Stream.generate(() -> new Article("Java"))
- .limit(35000)
- .collect(Collectors.toList());
- }
-}
+}
\ No newline at end of file
diff --git a/core-java-8/src/main/java/com/baeldung/spliteratorAPI/Task.java b/core-java-8/src/main/java/com/baeldung/spliteratorAPI/Task.java
index 108fdc52aa..70435d1c75 100644
--- a/core-java-8/src/main/java/com/baeldung/spliteratorAPI/Task.java
+++ b/core-java-8/src/main/java/com/baeldung/spliteratorAPI/Task.java
@@ -1,8 +1,9 @@
package com.baeldung.spliteratorAPI;
import java.util.Spliterator;
+import java.util.concurrent.Callable;
-public class Task implements Runnable {
+public class Task implements Callable {
private Spliterator spliterator;
private final static String SUFFIX = "- published by Baeldung";
@@ -11,7 +12,7 @@ public class Task implements Runnable {
}
@Override
- public void run() {
+ public String call() {
int current = 0;
while (spliterator.tryAdvance(article -> {
article.setName(article.getName()
@@ -20,7 +21,7 @@ public class Task implements Runnable {
current++;
}
;
- System.out.println(Thread.currentThread()
- .getName() + ":" + current);
+ return Thread.currentThread()
+ .getName() + ":" + current;
}
}
diff --git a/core-java-8/src/test/java/com/baeldung/spliteratorAPI/ExecutorTest.java b/core-java-8/src/test/java/com/baeldung/spliteratorAPI/ExecutorTest.java
new file mode 100644
index 0000000000..64dd65cf5e
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/spliteratorAPI/ExecutorTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.spliteratorAPI;
+
+import java.util.Arrays;
+import java.util.Spliterator;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import static org.assertj.core.api.Assertions.*;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ExecutorTest {
+ Article article;
+ Stream stream;
+ Spliterator spliterator;
+ Spliterator split1;
+ Spliterator split2;
+
+ @Before
+ public void init() {
+ article = new Article(Arrays.asList(new Author("Ahmad", 0), new Author("Eugen", 0), new Author("Alice", 1),
+ new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0),
+ new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0),
+ new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1),
+ new Author("Mike", 0), new Author("Alice", 1), new Author("Mike", 0), new Author("Alice", 1),
+ new Author("Mike", 0), new Author("Michał", 0), new Author("Loredana", 1)), 0);
+ stream = article.getListOfAuthors().stream();
+ split1 = Executor.generateElements().spliterator();
+ split2 = split1.trySplit();
+ spliterator = new RelatedAuthorSpliterator(article.getListOfAuthors());
+ }
+
+ @Test
+ public void givenAstreamOfAuthors_whenProcessedInParallelWithCustomSpliterator_coubtProducessRightOutput() {
+ Stream stream2 = StreamSupport.stream(spliterator, true);
+ assertThat(Executor.countAutors(stream2.parallel())).isEqualTo(9);
+ }
+
+ @Test
+ public void givenSpliterator_whenAppliedToAListOfArticle_thenSplittedInHalf() {
+ assertThat(new Task(split1).call()).containsSequence(Executor.generateElements().size() / 2 + "");
+ assertThat(new Task(split2).call()).containsSequence(Executor.generateElements().size() / 2 + "");
+ }
+}
diff --git a/core-java-concurrency/README.md b/core-java-concurrency/README.md
index dc048495e4..8122c71bcb 100644
--- a/core-java-concurrency/README.md
+++ b/core-java-concurrency/README.md
@@ -33,4 +33,4 @@
- [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread)
- [Implementing a Runnable vs Extending a Thread](http://www.baeldung.com/java-runnable-vs-extending-thread)
- [How to Kill a Java Thread](http://www.baeldung.com/java-thread-stop)
-- [How to Wait for Threads to Finish in the ExecutorService](http://www.baeldung.com/java-executor-wait-for-threads)
+- [ExecutorService - Waiting for Threads to Finish](http://www.baeldung.com/java-executor-wait-for-threads)
diff --git a/core-java/src/main/java/com/baeldung/finalize/CloseableResource.java b/core-java/src/main/java/com/baeldung/finalize/CloseableResource.java
new file mode 100644
index 0000000000..d286570fbc
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/finalize/CloseableResource.java
@@ -0,0 +1,30 @@
+package com.baeldung.finalize;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class CloseableResource implements AutoCloseable {
+ private BufferedReader reader;
+
+ public CloseableResource() {
+ InputStream input = this.getClass().getClassLoader().getResourceAsStream("file.txt");
+ reader = new BufferedReader(new InputStreamReader(input));
+ }
+
+ public String readFirstLine() throws IOException {
+ String firstLine = reader.readLine();
+ return firstLine;
+ }
+
+ @Override
+ public void close() {
+ try {
+ reader.close();
+ System.out.println("Closed BufferedReader in the close method");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/finalize/Finalizable.java b/core-java/src/main/java/com/baeldung/finalize/Finalizable.java
new file mode 100644
index 0000000000..cfc6616f5c
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/finalize/Finalizable.java
@@ -0,0 +1,30 @@
+package com.baeldung.finalize;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Finalizable {
+ private BufferedReader reader;
+
+ public Finalizable() {
+ InputStream input = this.getClass().getClassLoader().getResourceAsStream("file.txt");
+ reader = new BufferedReader(new InputStreamReader(input));
+ }
+
+ public String readFirstLine() throws IOException {
+ String firstLine = reader.readLine();
+ return firstLine;
+ }
+
+ @Override
+ public void finalize() {
+ try {
+ reader.close();
+ System.out.println("Closed BufferedReader in the finalizer");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/trie/Trie.java b/core-java/src/main/java/com/baeldung/trie/Trie.java
new file mode 100644
index 0000000000..dd51d97b2d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/trie/Trie.java
@@ -0,0 +1,62 @@
+package com.baeldung.trie;
+
+public class Trie {
+ private TrieNode root;
+
+ Trie() {
+ root = new TrieNode();
+ }
+
+ public void insert(String word) {
+ TrieNode current = root;
+
+ for (int i = 0; i < word.length(); i++) {
+ current = current.getChildren().computeIfAbsent(word.charAt(i), c -> new TrieNode());
+ }
+ current.setEndOfWord(true);
+ }
+
+ public boolean delete(String word) {
+ return delete(root, word, 0);
+ }
+
+ public boolean containsNode(String word) {
+ TrieNode current = root;
+
+ for (int i = 0; i < word.length(); i++) {
+ char ch = word.charAt(i);
+ TrieNode node = current.getChildren().get(ch);
+ if (node == null) {
+ return false;
+ }
+ current = node;
+ }
+ return current.isEndOfWord();
+ }
+
+ public boolean isEmpty() {
+ return root == null;
+ }
+
+ private boolean delete(TrieNode current, String word, int index) {
+ if (index == word.length()) {
+ if (!current.isEndOfWord()) {
+ return false;
+ }
+ current.setEndOfWord(false);
+ return current.getChildren().isEmpty();
+ }
+ char ch = word.charAt(index);
+ TrieNode node = current.getChildren().get(ch);
+ if (node == null) {
+ return false;
+ }
+ boolean shouldDeleteCurrentNode = delete(node, word, index + 1);
+
+ if (shouldDeleteCurrentNode) {
+ current.getChildren().remove(ch);
+ return current.getChildren().isEmpty();
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/trie/TrieNode.java b/core-java/src/main/java/com/baeldung/trie/TrieNode.java
new file mode 100644
index 0000000000..25dc753950
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/trie/TrieNode.java
@@ -0,0 +1,31 @@
+package com.baeldung.trie;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class TrieNode {
+ private Map children;
+ private boolean endOfWord;
+
+ public TrieNode() {
+ children = new HashMap<>();
+ endOfWord = false;
+ }
+
+ public Map getChildren() {
+ return children;
+ }
+
+ public void setChildren(Map children) {
+ this.children = children;
+ }
+
+ public boolean isEndOfWord() {
+ return endOfWord;
+ }
+
+ public void setEndOfWord(boolean endOfWord) {
+ this.endOfWord = endOfWord;
+ }
+
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/finalize/FinalizeUnitTest.java b/core-java/src/test/java/com/baeldung/finalize/FinalizeUnitTest.java
new file mode 100644
index 0000000000..57d409074b
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/finalize/FinalizeUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.finalize;
+
+import java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class FinalizeUnitTest {
+ @Test
+ public void whenGC_thenFinalizerExecuted() throws IOException {
+ String firstLine = new Finalizable().readFirstLine();
+ Assert.assertEquals("baeldung.com", firstLine);
+ System.gc();
+ }
+
+ @Test
+ public void whenTryWResourcesExits_thenResourceClosed() throws IOException {
+ try (CloseableResource resource = new CloseableResource()) {
+ String firstLine = resource.readFirstLine();
+ Assert.assertEquals("baeldung.com", firstLine);
+ }
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/trie/TrieTest.java b/core-java/src/test/java/com/baeldung/trie/TrieTest.java
new file mode 100644
index 0000000000..be7e5575d8
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/trie/TrieTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.trie;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TrieTest {
+
+ @Test
+ public void whenEmptyTrie_thenNoElements() {
+ Trie trie = new Trie();
+
+ assertFalse(trie.isEmpty());
+ }
+
+ @Test
+ public void givenATrie_whenAddingElements_thenTrieNotEmpty() {
+ Trie trie = createExampleTrie();
+
+ assertFalse(trie.isEmpty());
+ }
+
+ @Test
+ public void givenATrie_whenAddingElements_thenTrieHasThoseElements() {
+ Trie trie = createExampleTrie();
+
+ assertFalse(trie.containsNode("3"));
+ assertFalse(trie.containsNode("vida"));
+
+ assertTrue(trie.containsNode("Programming"));
+ assertTrue(trie.containsNode("is"));
+ assertTrue(trie.containsNode("a"));
+ assertTrue(trie.containsNode("way"));
+ assertTrue(trie.containsNode("of"));
+ assertTrue(trie.containsNode("life"));
+ }
+
+ @Test
+ public void givenATrie_whenLookingForNonExistingElement_thenReturnsFalse() {
+ Trie trie = createExampleTrie();
+
+ assertFalse(trie.containsNode("99"));
+ }
+
+ @Test
+ public void givenATrie_whenDeletingElements_thenTreeDoesNotContainThoseElements() {
+
+ Trie trie = createExampleTrie();
+
+ assertTrue(trie.containsNode("Programming"));
+ trie.delete("Programming");
+ assertFalse(trie.containsNode("Programming"));
+ }
+
+ private Trie createExampleTrie() {
+ Trie trie = new Trie();
+
+ trie.insert("Programming");
+ trie.insert("is");
+ trie.insert("a");
+ trie.insert("way");
+ trie.insert("of");
+ trie.insert("life");
+
+ return trie;
+ }
+}
diff --git a/libraries/src/main/java/com/baeldung/netty/ChannelHandlerA.java b/libraries/src/main/java/com/baeldung/netty/ChannelHandlerA.java
new file mode 100644
index 0000000000..c919bdb09c
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/netty/ChannelHandlerA.java
@@ -0,0 +1,22 @@
+package com.baeldung.netty;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+
+import java.util.logging.Logger;
+
+public class ChannelHandlerA extends ChannelInboundHandlerAdapter {
+
+ private Logger logger = Logger.getLogger(getClass().getName());
+
+ @Override
+ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+ throw new Exception("Ooops");
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ logger.info("Exception Occurred in ChannelHandler A");
+ ctx.fireExceptionCaught(cause);
+ }
+}
diff --git a/libraries/src/main/java/com/baeldung/netty/ChannelHandlerB.java b/libraries/src/main/java/com/baeldung/netty/ChannelHandlerB.java
new file mode 100644
index 0000000000..c5bdeb1013
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/netty/ChannelHandlerB.java
@@ -0,0 +1,20 @@
+package com.baeldung.netty;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+
+import java.util.logging.Logger;
+
+
+public class ChannelHandlerB extends ChannelInboundHandlerAdapter {
+
+ private Logger logger = Logger.getLogger(getClass().getName());
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+ logger.info("Exception Handled in ChannelHandler B");
+ logger.info(cause.getLocalizedMessage());
+ //do more exception handling
+ ctx.close();
+ }
+}
diff --git a/libraries/src/main/java/com/baeldung/netty/NettyServerB.java b/libraries/src/main/java/com/baeldung/netty/NettyServerB.java
new file mode 100644
index 0000000000..c8004623c2
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/netty/NettyServerB.java
@@ -0,0 +1,47 @@
+package com.baeldung.netty;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+
+public class NettyServerB {
+
+ private int port;
+
+ private NettyServerB(int port) {
+ this.port = port;
+ }
+
+ private void run() throws Exception {
+
+ EventLoopGroup bossGroup = new NioEventLoopGroup();
+ EventLoopGroup workerGroup = new NioEventLoopGroup();
+
+ try {
+ ServerBootstrap b = new ServerBootstrap();
+ b.group(bossGroup, workerGroup)
+ .channel(NioServerSocketChannel.class)
+ .childHandler(new ChannelInitializer() {
+ public void initChannel(SocketChannel ch) throws Exception {
+ ch.pipeline().addLast(new ChannelHandlerA(), new ChannelHandlerB());
+ }
+ })
+ .option(ChannelOption.SO_BACKLOG, 128)
+ .childOption(ChannelOption.SO_KEEPALIVE, true);
+ ChannelFuture f = b.bind(port).sync(); // (7)
+ f.channel().closeFuture().sync();
+ } finally {
+ workerGroup.shutdownGracefully();
+ bossGroup.shutdownGracefully();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new NettyServerB(8080).run();
+ }
+}
diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml
index 48608fbc80..46b8b80597 100644
--- a/logging-modules/log4j2/pom.xml
+++ b/logging-modules/log4j2/pom.xml
@@ -59,10 +59,10 @@
- 2.8.5
+ 2.9.3
1.4.193
2.1.1
- 2.7
+ 2.10.0
diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutTest.java
new file mode 100644
index 0000000000..9493c32094
--- /dev/null
+++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutTest.java
@@ -0,0 +1,45 @@
+package com.baeldung.logging.log4j2.tests;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class JSONLayoutTest {
+
+ private static Logger logger;
+ private ByteArrayOutputStream consoleOutput = new ByteArrayOutputStream();
+ private PrintStream ps = new PrintStream(consoleOutput);
+
+ @Before
+ public void setUp() {
+ // Redirect console output to our stream
+ System.setOut(ps);
+ logger = LogManager.getLogger("CONSOLE_JSON_APPENDER");
+ }
+
+ @Test
+ public void whenLogLayoutInJSON_thenOutputIsCorrectJSON() {
+ logger.debug("Debug message");
+ String currentLog = consoleOutput.toString();
+ assertTrue(!currentLog.isEmpty() && isValidJSON(currentLog));
+ }
+
+ public static boolean isValidJSON(String jsonInString) {
+ try {
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.readTree(jsonInString);
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/logging-modules/log4j2/src/test/resources/log4j2.xml b/logging-modules/log4j2/src/test/resources/log4j2.xml
index 21fd1da446..4dcb7cce5a 100644
--- a/logging-modules/log4j2/src/test/resources/log4j2.xml
+++ b/logging-modules/log4j2/src/test/resources/log4j2.xml
@@ -1,16 +1,25 @@
-
+
-
+
-
+
-
+
+
+
+
+
+
@@ -19,53 +28,58 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml
index 8169134442..cd0d3758cc 100644
--- a/logging-modules/logback/pom.xml
+++ b/logging-modules/logback/pom.xml
@@ -1,6 +1,6 @@
4.0.0
@@ -12,6 +12,8 @@
UTF-8
1.2.3
+ 0.1.5
+ 2.9.3
@@ -28,7 +30,21 @@
logback-classic
${logback.version}
-
+
+ ch.qos.logback.contrib
+ logback-json-classic
+ ${logback.contrib.version}
+
+
+ ch.qos.logback.contrib
+ logback-jackson
+ ${logback.contrib.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
diff --git a/logging-modules/logback/src/test/java/com/baeldung/logback/JSONLayoutTest.java b/logging-modules/logback/src/test/java/com/baeldung/logback/JSONLayoutTest.java
new file mode 100644
index 0000000000..ca3c4b3457
--- /dev/null
+++ b/logging-modules/logback/src/test/java/com/baeldung/logback/JSONLayoutTest.java
@@ -0,0 +1,45 @@
+package com.baeldung.logback;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class JSONLayoutTest {
+
+ private static Logger logger;
+ private ByteArrayOutputStream consoleOutput = new ByteArrayOutputStream();
+ private PrintStream ps = new PrintStream(consoleOutput);
+
+ @Before
+ public void setUp() {
+ // Redirect console output to our stream
+ System.setOut(ps);
+ logger = LoggerFactory.getLogger("jsonLogger");
+ }
+
+ @Test
+ public void whenLogLayoutInJSON_thenOutputIsCorrectJSON() {
+ logger.debug("Debug message");
+ String currentLog = consoleOutput.toString();
+ assertTrue(!currentLog.isEmpty() && isValidJSON(currentLog));
+ }
+
+ public static boolean isValidJSON(String jsonInString) {
+ try {
+ final ObjectMapper mapper = new ObjectMapper();
+ mapper.readTree(jsonInString);
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+}
diff --git a/logging-modules/logback/src/test/resources/logback-test.xml b/logging-modules/logback/src/test/resources/logback-test.xml
index 8254e6ac80..df81f18cc2 100644
--- a/logging-modules/logback/src/test/resources/logback-test.xml
+++ b/logging-modules/logback/src/test/resources/logback-test.xml
@@ -1,14 +1,31 @@
-
+
+
+
test
-
+
+
+ # JSON appender
+
+
+
+ true
+
+ yyyy-MM-dd' 'HH:mm:ss.SSS
+
+
+
+
+
+
-
-
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9bf12725c0..6321b0333e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -113,7 +113,9 @@
lombok
mapstruct
+
mesos-marathon
testing-modules/mockito
testing-modules/mockito-2
diff --git a/spring-5-reactive/pom.xml b/spring-5-reactive/pom.xml
index 36eaaa1530..5065457c4b 100644
--- a/spring-5-reactive/pom.xml
+++ b/spring-5-reactive/pom.xml
@@ -60,7 +60,13 @@
-
+
+
+ org.projectlombok
+ lombok
+ compile
+
+
org.apache.geronimo.specs
geronimo-json_1.1_spec
diff --git a/spring-reactive-websocket/src/main/java/com/baeldung/Event.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/Event.java
similarity index 79%
rename from spring-reactive-websocket/src/main/java/com/baeldung/Event.java
rename to spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/Event.java
index 20d678c214..90f83a566f 100644
--- a/spring-reactive-websocket/src/main/java/com/baeldung/Event.java
+++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/Event.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.reactive.websocket;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveJavaClientWebSocket.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveJavaClientWebSocket.java
new file mode 100644
index 0000000000..74e2d7daca
--- /dev/null
+++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveJavaClientWebSocket.java
@@ -0,0 +1,23 @@
+package com.baeldung.reactive.websocket;
+
+import java.net.URI;
+import java.time.Duration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.web.reactive.socket.WebSocketMessage;
+import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
+import org.springframework.web.reactive.socket.client.WebSocketClient;
+
+import reactor.core.publisher.Mono;
+
+@SpringBootApplication
+public class ReactiveJavaClientWebSocket {
+ public static void main(String[] args) throws InterruptedException {
+ WebSocketClient client = new ReactorNettyWebSocketClient();
+ client.execute(URI.create("ws://localhost:8080/event-emitter"), session -> session.send(Mono.just(session.textMessage("event-me-from-spring-reactive-client")))
+ .thenMany(session.receive()
+ .map(WebSocketMessage::getPayloadAsText)
+ .log())
+ .then())
+ .block(Duration.ofSeconds(10L));
+ }
+}
diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketApplication.java
new file mode 100644
index 0000000000..43b5e50387
--- /dev/null
+++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketApplication.java
@@ -0,0 +1,11 @@
+package com.baeldung.reactive.websocket;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ReactiveWebSocketApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(ReactiveWebSocketApplication.class, args);
+ }
+}
diff --git a/spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketConfiguration.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketConfiguration.java
similarity index 96%
rename from spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketConfiguration.java
rename to spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketConfiguration.java
index 6729e09273..974def5a91 100644
--- a/spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketConfiguration.java
+++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketConfiguration.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.reactive.websocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
diff --git a/spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketHandler.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketHandler.java
similarity index 98%
rename from spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketHandler.java
rename to spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketHandler.java
index 4a548322b3..7f74e714f6 100644
--- a/spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketHandler.java
+++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/websocket/ReactiveWebSocketHandler.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.reactive.websocket;
import org.springframework.web.reactive.socket.WebSocketSession;
diff --git a/spring-reactive-websocket/src/main/resources/static/client-websocket.html b/spring-5-reactive/src/main/resources/static/client-websocket.html
similarity index 100%
rename from spring-reactive-websocket/src/main/resources/static/client-websocket.html
rename to spring-5-reactive/src/main/resources/static/client-websocket.html
diff --git a/spring-boot/src/main/java/com/baeldung/kong/QueryController.java b/spring-boot/src/main/java/com/baeldung/kong/QueryController.java
new file mode 100644
index 0000000000..af63a7e8a1
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/kong/QueryController.java
@@ -0,0 +1,32 @@
+package com.baeldung.kong;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author aiet
+ */
+@RestController
+@RequestMapping("/stock")
+public class QueryController {
+
+ private static int REQUEST_COUNTER = 0;
+
+ @GetMapping("/reqcount")
+ public int getReqCount(){
+ return REQUEST_COUNTER;
+ }
+
+ @GetMapping("/{code}")
+ public String getStockPrice(@PathVariable String code){
+ REQUEST_COUNTER++;
+ if("BTC".equalsIgnoreCase(code))
+ return "10000";
+ else return "N/A";
+ }
+
+
+
+}
diff --git a/spring-boot/src/main/java/com/baeldung/kong/StockApp.java b/spring-boot/src/main/java/com/baeldung/kong/StockApp.java
new file mode 100644
index 0000000000..f901592938
--- /dev/null
+++ b/spring-boot/src/main/java/com/baeldung/kong/StockApp.java
@@ -0,0 +1,13 @@
+package com.baeldung.kong;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class StockApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(StockApp.class, args);
+ }
+
+}
diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties
index 458b4e0d46..059a6c96be 100644
--- a/spring-boot/src/main/resources/application.properties
+++ b/spring-boot/src/main/resources/application.properties
@@ -1,4 +1,4 @@
-server.port=8080
+server.port=9090
server.contextPath=/springbootapp
management.port=8081
management.address=127.0.0.1
diff --git a/spring-boot/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java b/spring-boot/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java
new file mode 100644
index 0000000000..f399806a65
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/kong/KongAdminAPILiveTest.java
@@ -0,0 +1,165 @@
+package com.baeldung.kong;
+
+import com.baeldung.kong.domain.APIObject;
+import com.baeldung.kong.domain.ConsumerObject;
+import com.baeldung.kong.domain.KeyAuthObject;
+import com.baeldung.kong.domain.PluginObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.*;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.net.URI;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
+
+/**
+ * @author aiet
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = DEFINED_PORT, classes = StockApp.class)
+public class KongAdminAPILiveTest {
+
+ private String getStockPrice(String code) {
+ try {
+ return restTemplate.getForObject(new URI("http://localhost:8080/stock/" + code), String.class);
+ } catch (Exception ignored) {
+ }
+ return null;
+ }
+
+ @Before
+ public void init() {
+ System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
+ }
+
+ @Autowired TestRestTemplate restTemplate;
+
+ @Test
+ public void givenEndpoint_whenQueryStockPrice_thenPriceCorrect() {
+ String response = getStockPrice("btc");
+ assertEquals("10000", response);
+
+ response = getStockPrice("eth");
+ assertEquals("N/A", response);
+ }
+
+ @Test
+ public void givenKongAdminAPI_whenAddAPI_thenAPIAccessibleViaKong() throws Exception {
+ restTemplate.delete("http://localhost:8001/apis/stock-api");
+
+ APIObject stockAPI = new APIObject("stock-api", "stock.api", "http://localhost:8080", "/");
+ HttpEntity apiEntity = new HttpEntity<>(stockAPI);
+ ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001/apis", apiEntity, String.class);
+
+ assertEquals(HttpStatus.CREATED, addAPIResp.getStatusCode());
+
+ addAPIResp = restTemplate.postForEntity("http://localhost:8001/apis", apiEntity, String.class);
+ assertEquals(HttpStatus.CONFLICT, addAPIResp.getStatusCode());
+ String apiListResp = restTemplate.getForObject("http://localhost:8001/apis/", String.class);
+
+ assertTrue(apiListResp.contains("stock-api"));
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.set("Host", "stock.api");
+ RequestEntity requestEntity = new RequestEntity<>(headers, HttpMethod.GET, new URI("http://localhost:8000/stock/btc"));
+ ResponseEntity stockPriceResp = restTemplate.exchange(requestEntity, String.class);
+
+ assertEquals("10000", stockPriceResp.getBody());
+ }
+
+ @Test
+ public void givenKongAdminAPI_whenAddAPIConsumer_thenAdded() {
+ restTemplate.delete("http://localhost:8001/consumers/eugenp");
+
+ ConsumerObject consumer = new ConsumerObject("eugenp");
+ HttpEntity addConsumerEntity = new HttpEntity<>(consumer);
+ ResponseEntity addConsumerResp = restTemplate.postForEntity("http://localhost:8001/consumers/", addConsumerEntity, String.class);
+
+ assertEquals(HttpStatus.CREATED, addConsumerResp.getStatusCode());
+
+ addConsumerResp = restTemplate.postForEntity("http://localhost:8001/consumers", addConsumerEntity, String.class);
+ assertEquals(HttpStatus.CONFLICT, addConsumerResp.getStatusCode());
+
+ String consumerListResp = restTemplate.getForObject("http://localhost:8001/consumers/", String.class);
+ assertTrue(consumerListResp.contains("eugenp"));
+ }
+
+ @Test
+ public void givenAPI_whenEnableAuth_thenAnonymousDenied() throws Exception {
+ String apiListResp = restTemplate.getForObject("http://localhost:8001/apis/", String.class);
+ if (!apiListResp.contains("stock-api")) {
+ givenKongAdminAPI_whenAddAPI_thenAPIAccessibleViaKong();
+ }
+
+ PluginObject authPlugin = new PluginObject("key-auth");
+ ResponseEntity enableAuthResp = restTemplate.postForEntity("http://localhost:8001/apis/stock-api/plugins", new HttpEntity<>(authPlugin), String.class);
+
+ assertTrue(HttpStatus.CREATED == enableAuthResp.getStatusCode() || HttpStatus.CONFLICT == enableAuthResp.getStatusCode());
+
+ String pluginsResp = restTemplate.getForObject("http://localhost:8001/apis/stock-api/plugins", String.class);
+ assertTrue(pluginsResp.contains("key-auth"));
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.set("Host", "stock.api");
+ RequestEntity requestEntity = new RequestEntity<>(headers, HttpMethod.GET, new URI("http://localhost:8000/stock/btc"));
+ ResponseEntity stockPriceResp = restTemplate.exchange(requestEntity, String.class);
+ assertEquals(HttpStatus.UNAUTHORIZED, stockPriceResp.getStatusCode());
+ }
+
+ @Test
+ public void givenAPIAuthEnabled_whenAddKey_thenAccessAllowed() throws Exception {
+ String apiListResp = restTemplate.getForObject("http://localhost:8001/apis/", String.class);
+ if (!apiListResp.contains("stock-api")) {
+ givenKongAdminAPI_whenAddAPI_thenAPIAccessibleViaKong();
+ }
+
+ String consumerListResp = restTemplate.getForObject("http://localhost:8001/consumers/", String.class);
+ if (!consumerListResp.contains("eugenp")) {
+ givenKongAdminAPI_whenAddAPIConsumer_thenAdded();
+ }
+
+ final String consumerKey = "eugenp.pass";
+ KeyAuthObject keyAuth = new KeyAuthObject(consumerKey);
+ ResponseEntity keyAuthResp = restTemplate.postForEntity("http://localhost:8001/consumers/eugenp/key-auth", new HttpEntity<>(keyAuth), String.class);
+
+ assertTrue(HttpStatus.CREATED == keyAuthResp.getStatusCode() || HttpStatus.CONFLICT == keyAuthResp.getStatusCode());
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.set("Host", "stock.api");
+ headers.set("apikey", consumerKey);
+ RequestEntity requestEntity = new RequestEntity<>(headers, HttpMethod.GET, new URI("http://localhost:8000/stock/btc"));
+ ResponseEntity stockPriceResp = restTemplate.exchange(requestEntity, String.class);
+
+ assertEquals("10000", stockPriceResp.getBody());
+
+ headers.set("apikey", "wrongpass");
+ requestEntity = new RequestEntity<>(headers, HttpMethod.GET, new URI("http://localhost:8000/stock/btc"));
+ stockPriceResp = restTemplate.exchange(requestEntity, String.class);
+ assertEquals(HttpStatus.FORBIDDEN, stockPriceResp.getStatusCode());
+ }
+
+ @Test
+ public void givenAdminAPIProxy_whenAddAPIViaProxy_thenAPIAdded() throws Exception {
+ APIObject adminAPI = new APIObject("admin-api", "admin.api", "http://localhost:8001", "/admin-api");
+ HttpEntity apiEntity = new HttpEntity<>(adminAPI);
+ ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001/apis", apiEntity, String.class);
+
+ assertTrue(HttpStatus.CREATED == addAPIResp.getStatusCode() || HttpStatus.CONFLICT == addAPIResp.getStatusCode());
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.set("Host", "admin.api");
+ APIObject baeldungAPI = new APIObject("baeldung-api", "baeldung.com", "http://ww.baeldung.com", "/");
+ RequestEntity requestEntity = new RequestEntity<>(baeldungAPI, headers, HttpMethod.POST, new URI("http://localhost:8000/admin-api/apis"));
+ addAPIResp = restTemplate.exchange(requestEntity, String.class);
+
+ assertTrue(HttpStatus.CREATED == addAPIResp.getStatusCode() || HttpStatus.CONFLICT == addAPIResp.getStatusCode());
+ }
+
+}
diff --git a/spring-boot/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java b/spring-boot/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java
new file mode 100644
index 0000000000..f8090e4c86
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/kong/KongLoadBalanceLiveTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.kong;
+
+import com.baeldung.kong.domain.APIObject;
+import com.baeldung.kong.domain.TargetObject;
+import com.baeldung.kong.domain.UpstreamObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.*;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.net.URI;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
+
+/**
+ * @author aiet
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = DEFINED_PORT, classes = StockApp.class)
+public class KongLoadBalanceLiveTest {
+
+ @Before
+ public void init() {
+ System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
+ }
+
+ @Autowired TestRestTemplate restTemplate;
+
+ @Test
+ public void givenKongAdminAPI_whenAddAPI_thenAPIAccessibleViaKong() throws Exception {
+ UpstreamObject upstream = new UpstreamObject("stock.api.service");
+ ResponseEntity addUpstreamResp = restTemplate.postForEntity("http://localhost:8001/upstreams", new HttpEntity<>(upstream), String.class);
+ assertTrue(HttpStatus.CREATED == addUpstreamResp.getStatusCode() || HttpStatus.CONFLICT == addUpstreamResp.getStatusCode());
+
+ TargetObject testTarget = new TargetObject("localhost:8080", 10);
+ ResponseEntity addTargetResp = restTemplate.postForEntity("http://localhost:8001/upstreams/stock.api.service/targets", new HttpEntity<>(testTarget), String.class);
+ assertTrue(HttpStatus.CREATED == addTargetResp.getStatusCode() || HttpStatus.CONFLICT == addTargetResp.getStatusCode());
+
+ TargetObject releaseTarget = new TargetObject("localhost:9090", 40);
+ addTargetResp = restTemplate.postForEntity("http://localhost:8001/upstreams/stock.api.service/targets", new HttpEntity<>(releaseTarget), String.class);
+ assertTrue(HttpStatus.CREATED == addTargetResp.getStatusCode() || HttpStatus.CONFLICT == addTargetResp.getStatusCode());
+
+ APIObject stockAPI = new APIObject("balanced-stock-api", "balanced.stock.api", "http://stock.api.service", "/");
+ HttpEntity apiEntity = new HttpEntity<>(stockAPI);
+ ResponseEntity addAPIResp = restTemplate.postForEntity("http://localhost:8001/apis", apiEntity, String.class);
+ assertTrue(HttpStatus.CREATED == addAPIResp.getStatusCode() || HttpStatus.CONFLICT == addAPIResp.getStatusCode());
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.set("Host", "balanced.stock.api");
+ for (int i = 0; i < 1000; i++) {
+ RequestEntity requestEntity = new RequestEntity<>(headers, HttpMethod.GET, new URI("http://localhost:8000/stock/btc"));
+ ResponseEntity stockPriceResp = restTemplate.exchange(requestEntity, String.class);
+ assertEquals("10000", stockPriceResp.getBody());
+ }
+
+ int releaseCount = restTemplate.getForObject("http://localhost:9090/stock/reqcount", Integer.class);
+ int testCount = restTemplate.getForObject("http://localhost:8080/stock/reqcount", Integer.class);
+
+ assertTrue(Math.round(releaseCount * 1.0 / testCount) == 4);
+ }
+
+}
diff --git a/spring-boot/src/test/java/com/baeldung/kong/domain/APIObject.java b/spring-boot/src/test/java/com/baeldung/kong/domain/APIObject.java
new file mode 100644
index 0000000000..f386712444
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/kong/domain/APIObject.java
@@ -0,0 +1,54 @@
+package com.baeldung.kong.domain;
+
+/**
+ * @author aiet
+ */
+public class APIObject {
+
+ public APIObject() {
+ }
+
+ public APIObject(String name, String hosts, String upstream_url, String uris) {
+ this.name = name;
+ this.hosts = hosts;
+ this.upstream_url = upstream_url;
+ this.uris = uris;
+ }
+
+ private String name;
+ private String hosts;
+ private String upstream_url;
+ private String uris;
+
+ public String getUris() {
+ return uris;
+ }
+
+ public void setUris(String uris) {
+ this.uris = uris;
+ }
+
+ public String getUpstream_url() {
+ return upstream_url;
+ }
+
+ public void setUpstream_url(String upstream_url) {
+ this.upstream_url = upstream_url;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getHosts() {
+ return hosts;
+ }
+
+ public void setHosts(String hosts) {
+ this.hosts = hosts;
+ }
+}
diff --git a/spring-boot/src/test/java/com/baeldung/kong/domain/ConsumerObject.java b/spring-boot/src/test/java/com/baeldung/kong/domain/ConsumerObject.java
new file mode 100644
index 0000000000..74bef8f2d1
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/kong/domain/ConsumerObject.java
@@ -0,0 +1,35 @@
+package com.baeldung.kong.domain;
+
+/**
+ * @author aiet
+ */
+public class ConsumerObject {
+
+ private String username;
+ private String custom_id;
+
+ public ConsumerObject(String username) {
+ this.username = username;
+ }
+
+ public ConsumerObject(String username, String custom_id) {
+ this.username = username;
+ this.custom_id = custom_id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getCustom_id() {
+ return custom_id;
+ }
+
+ public void setCustom_id(String custom_id) {
+ this.custom_id = custom_id;
+ }
+}
diff --git a/spring-boot/src/test/java/com/baeldung/kong/domain/KeyAuthObject.java b/spring-boot/src/test/java/com/baeldung/kong/domain/KeyAuthObject.java
new file mode 100644
index 0000000000..80de6bfcd9
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/kong/domain/KeyAuthObject.java
@@ -0,0 +1,21 @@
+package com.baeldung.kong.domain;
+
+/**
+ * @author aiet
+ */
+public class KeyAuthObject {
+
+ public KeyAuthObject(String key) {
+ this.key = key;
+ }
+
+ private String key;
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+}
diff --git a/spring-boot/src/test/java/com/baeldung/kong/domain/PluginObject.java b/spring-boot/src/test/java/com/baeldung/kong/domain/PluginObject.java
new file mode 100644
index 0000000000..c161fc9b54
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/kong/domain/PluginObject.java
@@ -0,0 +1,30 @@
+package com.baeldung.kong.domain;
+
+/**
+ * @author aiet
+ */
+public class PluginObject {
+
+ private String name;
+ private String consumer_id;
+
+ public PluginObject(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getConsumer_id() {
+ return consumer_id;
+ }
+
+ public void setConsumer_id(String consumer_id) {
+ this.consumer_id = consumer_id;
+ }
+}
diff --git a/spring-boot/src/test/java/com/baeldung/kong/domain/TargetObject.java b/spring-boot/src/test/java/com/baeldung/kong/domain/TargetObject.java
new file mode 100644
index 0000000000..79653e2846
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/kong/domain/TargetObject.java
@@ -0,0 +1,31 @@
+package com.baeldung.kong.domain;
+
+/**
+ * @author aiet
+ */
+public class TargetObject {
+
+ public TargetObject(String target, int weight) {
+ this.target = target;
+ this.weight = weight;
+ }
+
+ private String target;
+ private int weight;
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public int getWeight() {
+ return weight;
+ }
+
+ public void setWeight(int weight) {
+ this.weight = weight;
+ }
+}
diff --git a/spring-boot/src/test/java/com/baeldung/kong/domain/UpstreamObject.java b/spring-boot/src/test/java/com/baeldung/kong/domain/UpstreamObject.java
new file mode 100644
index 0000000000..6461381ac5
--- /dev/null
+++ b/spring-boot/src/test/java/com/baeldung/kong/domain/UpstreamObject.java
@@ -0,0 +1,21 @@
+package com.baeldung.kong.domain;
+
+/**
+ * @author aiet
+ */
+public class UpstreamObject {
+
+ public UpstreamObject(String name) {
+ this.name = name;
+ }
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/spring-cloud/spring-cloud-security/personresource/pom.xml b/spring-cloud/spring-cloud-security/personresource/pom.xml
index 783fd41e66..ca1ff82515 100644
--- a/spring-cloud/spring-cloud-security/personresource/pom.xml
+++ b/spring-cloud/spring-cloud-security/personresource/pom.xml
@@ -43,10 +43,6 @@
org.springframework.security
spring-security-jwt
-
- com.google.code.gson
- gson
-
diff --git a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java
index 15ffc557fc..9e5420da5a 100644
--- a/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java
+++ b/spring-cloud/spring-cloud-security/personresource/src/main/java/com/baeldung/controller/PersonInfoController.java
@@ -6,16 +6,13 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.model.Person;
-import com.google.gson.Gson;
@RestController
public class PersonInfoController {
@GetMapping("/personResource")
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
- public @ResponseBody String personInfo() {
- Gson gson = new Gson();
- String person = gson.toJson(new Person("abir", "Dhaka", "Bangladesh", 29, "Male"));
- return person;
+ public @ResponseBody Person personInfo() {
+ return new Person("abir", "Dhaka", "Bangladesh", 29, "Male");
}
}
\ No newline at end of file
diff --git a/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Person.java b/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Person.java
index b8ad59e2e2..09b971fdc2 100644
--- a/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Person.java
+++ b/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Person.java
@@ -11,10 +11,9 @@ public class Person {
private Date dateOfBirth;
public Person() {
-
}
- public Person(int age, String fullName, Date dateOfBirth) {
+ Person(int age, String fullName, Date dateOfBirth) {
super();
this.age = age;
this.fullName = fullName;
diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java
index 1fb1ae76f7..285c164869 100644
--- a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java
+++ b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java
@@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
+import java.util.stream.Collectors;
import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
import static org.junit.Assert.assertEquals;
@@ -78,12 +79,9 @@ public class ElasticSearchManualTest {
SearchHit[] searchHits = response
.getHits()
.getHits();
- List results = new ArrayList<>();
- for (SearchHit hit : searchHits) {
- String sourceAsString = hit.getSourceAsString();
- Person person = JSON.parseObject(sourceAsString, Person.class);
- results.add(person);
- }
+ List results = Arrays.stream(searchHits)
+ .map(hit -> JSON.parseObject(hit.getSourceAsString(), Person.class))
+ .collect(Collectors.toList());
}
@Test
@@ -125,11 +123,10 @@ public class ElasticSearchManualTest {
.actionGet();
response2.getHits();
response3.getHits();
- List searchHits = Arrays.asList(response
- .getHits()
- .getHits());
- final List results = new ArrayList<>();
- searchHits.forEach(hit -> results.add(JSON.parseObject(hit.getSourceAsString(), Person.class)));
+
+ final List results = Arrays.stream(response.getHits().getHits())
+ .map(hit -> JSON.parseObject(hit.getSourceAsString(), Person.class))
+ .collect(Collectors.toList());
}
@Test
diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesTest.java
index 19514ce4c2..aa20913637 100644
--- a/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesTest.java
+++ b/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesTest.java
@@ -1,11 +1,6 @@
package com.baeldung.elasticsearch;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
+import com.baeldung.spring.data.es.config.Config;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
@@ -15,6 +10,7 @@ import org.elasticsearch.common.geo.builders.ShapeBuilder;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.search.SearchHit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -24,14 +20,19 @@ import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import com.baeldung.spring.data.es.config.Config;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertTrue;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class)
public class GeoQueriesTest {
- public static final String WONDERS_OF_WORLD = "wonders-of-world";
- public static final String WONDERS = "Wonders";
+ private static final String WONDERS_OF_WORLD = "wonders-of-world";
+ private static final String WONDERS = "Wonders";
+
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@@ -44,39 +45,37 @@ public class GeoQueriesTest {
CreateIndexRequest req = new CreateIndexRequest(WONDERS_OF_WORLD);
req.mapping(WONDERS, jsonObject);
client.admin()
- .indices()
- .create(req)
- .actionGet();
+ .indices()
+ .create(req)
+ .actionGet();
}
@Test
public void givenGeoShapeData_whenExecutedGeoShapeQuery_thenResultNonEmpty() {
String jsonObject = "{\"name\":\"Agra\",\"region\":{\"type\":\"envelope\",\"coordinates\":[[75,25],[80.1,30.2]]}}";
IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS)
- .setSource(jsonObject)
- .get();
+ .setSource(jsonObject)
+ .get();
String tajMahalId = response.getId();
client.admin()
- .indices()
- .prepareRefresh(WONDERS_OF_WORLD)
- .get();
+ .indices()
+ .prepareRefresh(WONDERS_OF_WORLD)
+ .get();
QueryBuilder qb = QueryBuilders.geoShapeQuery("region", ShapeBuilder.newEnvelope()
- .topLeft(74.00, 24.0)
- .bottomRight(81.1, 31.2))
- .relation(ShapeRelation.WITHIN);
+ .topLeft(74.00, 24.0)
+ .bottomRight(81.1, 31.2))
+ .relation(ShapeRelation.WITHIN);
SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD)
- .setTypes(WONDERS)
- .setQuery(qb)
- .execute()
- .actionGet();
+ .setTypes(WONDERS)
+ .setQuery(qb)
+ .execute()
+ .actionGet();
List ids = Arrays.stream(searchResponse.getHits()
- .getHits())
- .map(hit -> {
- return hit.getId();
- })
- .collect(Collectors.toList());
+ .getHits())
+ .map(SearchHit::getId)
+ .collect(Collectors.toList());
assertTrue(ids.contains(tajMahalId));
}
@@ -84,29 +83,27 @@ public class GeoQueriesTest {
public void givenGeoPointData_whenExecutedGeoBoundingBoxQuery_thenResultNonEmpty() {
String jsonObject = "{\"name\":\"Pyramids of Giza\",\"location\":[31.131302,29.976480]}";
IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS)
- .setSource(jsonObject)
- .get();
+ .setSource(jsonObject)
+ .get();
String pyramidsOfGizaId = response.getId();
client.admin()
- .indices()
- .prepareRefresh(WONDERS_OF_WORLD)
- .get();
+ .indices()
+ .prepareRefresh(WONDERS_OF_WORLD)
+ .get();
QueryBuilder qb = QueryBuilders.geoBoundingBoxQuery("location")
- .bottomLeft(28, 30)
- .topRight(31, 32);
+ .bottomLeft(28, 30)
+ .topRight(31, 32);
SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD)
- .setTypes(WONDERS)
- .setQuery(qb)
- .execute()
- .actionGet();
+ .setTypes(WONDERS)
+ .setQuery(qb)
+ .execute()
+ .actionGet();
List ids = Arrays.stream(searchResponse.getHits()
- .getHits())
- .map(hit -> {
- return hit.getId();
- })
- .collect(Collectors.toList());
+ .getHits())
+ .map(SearchHit::getId)
+ .collect(Collectors.toList());
assertTrue(ids.contains(pyramidsOfGizaId));
}
@@ -114,29 +111,27 @@ public class GeoQueriesTest {
public void givenGeoPointData_whenExecutedGeoDistanceQuery_thenResultNonEmpty() {
String jsonObject = "{\"name\":\"Lighthouse of alexandria\",\"location\":[31.131302,29.976480]}";
IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS)
- .setSource(jsonObject)
- .get();
+ .setSource(jsonObject)
+ .get();
String lighthouseOfAlexandriaId = response.getId();
client.admin()
- .indices()
- .prepareRefresh(WONDERS_OF_WORLD)
- .get();
+ .indices()
+ .prepareRefresh(WONDERS_OF_WORLD)
+ .get();
QueryBuilder qb = QueryBuilders.geoDistanceQuery("location")
- .point(29.976, 31.131)
- .distance(10, DistanceUnit.MILES);
+ .point(29.976, 31.131)
+ .distance(10, DistanceUnit.MILES);
SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD)
- .setTypes(WONDERS)
- .setQuery(qb)
- .execute()
- .actionGet();
+ .setTypes(WONDERS)
+ .setQuery(qb)
+ .execute()
+ .actionGet();
List ids = Arrays.stream(searchResponse.getHits()
- .getHits())
- .map(hit -> {
- return hit.getId();
- })
- .collect(Collectors.toList());
+ .getHits())
+ .map(SearchHit::getId)
+ .collect(Collectors.toList());
assertTrue(ids.contains(lighthouseOfAlexandriaId));
}
@@ -144,30 +139,28 @@ public class GeoQueriesTest {
public void givenGeoPointData_whenExecutedGeoPolygonQuery_thenResultNonEmpty() {
String jsonObject = "{\"name\":\"The Great Rann of Kutch\",\"location\":[69.859741,23.733732]}";
IndexResponse response = client.prepareIndex(WONDERS_OF_WORLD, WONDERS)
- .setSource(jsonObject)
- .get();
+ .setSource(jsonObject)
+ .get();
String greatRannOfKutchid = response.getId();
client.admin()
- .indices()
- .prepareRefresh(WONDERS_OF_WORLD)
- .get();
+ .indices()
+ .prepareRefresh(WONDERS_OF_WORLD)
+ .get();
QueryBuilder qb = QueryBuilders.geoPolygonQuery("location")
- .addPoint(22.733, 68.859)
- .addPoint(24.733, 68.859)
- .addPoint(23, 70.859);
+ .addPoint(22.733, 68.859)
+ .addPoint(24.733, 68.859)
+ .addPoint(23, 70.859);
SearchResponse searchResponse = client.prepareSearch(WONDERS_OF_WORLD)
- .setTypes(WONDERS)
- .setQuery(qb)
- .execute()
- .actionGet();
+ .setTypes(WONDERS)
+ .setQuery(qb)
+ .execute()
+ .actionGet();
List ids = Arrays.stream(searchResponse.getHits()
- .getHits())
- .map(hit -> {
- return hit.getId();
- })
- .collect(Collectors.toList());
+ .getHits())
+ .map(SearchHit::getId)
+ .collect(Collectors.toList());
assertTrue(ids.contains(greatRannOfKutchid));
}
@@ -175,5 +168,4 @@ public class GeoQueriesTest {
public void destroy() {
elasticsearchTemplate.deleteIndex(WONDERS_OF_WORLD);
}
-
}
diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchIntegrationTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchIntegrationTest.java
index 1280c8e1de..be31de724d 100644
--- a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchIntegrationTest.java
+++ b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchIntegrationTest.java
@@ -1,15 +1,9 @@
package com.baeldung.spring.data.es;
-import static java.util.Arrays.asList;
-import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND;
-import static org.elasticsearch.index.query.QueryBuilders.fuzzyQuery;
-import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
-import static org.elasticsearch.index.query.QueryBuilders.regexpQuery;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.util.List;
-
+import com.baeldung.spring.data.es.config.Config;
+import com.baeldung.spring.data.es.model.Article;
+import com.baeldung.spring.data.es.model.Author;
+import com.baeldung.spring.data.es.service.ArticleService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -22,10 +16,15 @@ import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import com.baeldung.spring.data.es.config.Config;
-import com.baeldung.spring.data.es.model.Article;
-import com.baeldung.spring.data.es.model.Author;
-import com.baeldung.spring.data.es.service.ArticleService;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND;
+import static org.elasticsearch.index.query.QueryBuilders.fuzzyQuery;
+import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
+import static org.elasticsearch.index.query.QueryBuilders.regexpQuery;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class)
@@ -72,21 +71,24 @@ public class ElasticSearchIntegrationTest {
@Test
public void givenPersistedArticles_whenSearchByAuthorsName_thenRightFound() {
- final Page articleByAuthorName = articleService.findByAuthorName(johnSmith.getName(), new PageRequest(0, 10));
+ final Page articleByAuthorName = articleService
+ .findByAuthorName(johnSmith.getName(), new PageRequest(0, 10));
assertEquals(2L, articleByAuthorName.getTotalElements());
}
@Test
public void givenCustomQuery_whenSearchByAuthorsName_thenArticleIsFound() {
- final Page articleByAuthorName = articleService.findByAuthorNameUsingCustomQuery("John Smith", new PageRequest(0, 10));
+ final Page articleByAuthorName = articleService
+ .findByAuthorNameUsingCustomQuery("John Smith", new PageRequest(0, 10));
assertEquals(3L, articleByAuthorName.getTotalElements());
}
@Test
public void givenPersistedArticles_whenUseRegexQuery_thenRightArticlesFound() {
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withFilter(regexpQuery("title", ".*data.*")).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder().withFilter(regexpQuery("title", ".*data.*"))
+ .build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(1, articles.size());
@@ -112,7 +114,8 @@ public class ElasticSearchIntegrationTest {
final String articleTitle = "Spring Data Elasticsearch";
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%")).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%")).build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(1, articles.size());
final long count = articleService.count();
@@ -124,7 +127,8 @@ public class ElasticSearchIntegrationTest {
@Test
public void givenSavedDoc_whenOneTermMatches_thenFindByTitle() {
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Search engines").operator(AND)).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(matchQuery("title", "Search engines").operator(AND)).build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(1, articles.size());
}
diff --git a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryIntegrationTest.java b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryIntegrationTest.java
index cc4bce0c75..7a9ac2de06 100644
--- a/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryIntegrationTest.java
+++ b/spring-data-elasticsearch/src/test/java/com/baeldung/spring/data/es/ElasticSearchQueryIntegrationTest.java
@@ -1,20 +1,9 @@
package com.baeldung.spring.data.es;
-import static java.util.Arrays.asList;
-import static java.util.stream.Collectors.toList;
-import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND;
-import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
-import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
-import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
-import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery;
-import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
-import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
+import com.baeldung.spring.data.es.config.Config;
+import com.baeldung.spring.data.es.model.Article;
+import com.baeldung.spring.data.es.model.Author;
+import com.baeldung.spring.data.es.service.ArticleService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.Fuzziness;
@@ -22,6 +11,7 @@ import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
+import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
@@ -35,10 +25,20 @@ import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import com.baeldung.spring.data.es.config.Config;
-import com.baeldung.spring.data.es.model.Article;
-import com.baeldung.spring.data.es.model.Author;
-import com.baeldung.spring.data.es.service.ArticleService;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static java.util.Arrays.asList;
+import static java.util.stream.Collectors.toList;
+import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND;
+import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
+import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
+import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
+import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery;
+import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
+import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class)
@@ -86,14 +86,16 @@ public class ElasticSearchQueryIntegrationTest {
@Test
public void givenFullTitle_whenRunMatchQuery_thenDocIsFound() {
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Search engines").operator(AND)).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(matchQuery("title", "Search engines").operator(AND)).build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(1, articles.size());
}
@Test
public void givenOneTermFromTitle_whenRunMatchQuery_thenDocIsFound() {
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Engines Solutions")).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(matchQuery("title", "Engines Solutions")).build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(1, articles.size());
assertEquals("Search engines", articles.get(0).getTitle());
@@ -101,18 +103,21 @@ public class ElasticSearchQueryIntegrationTest {
@Test
public void givenPartTitle_whenRunMatchQuery_thenDocIsFound() {
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "elasticsearch data")).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(matchQuery("title", "elasticsearch data")).build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(3, articles.size());
}
@Test
public void givenFullTitle_whenRunMatchQueryOnVerbatimField_thenDocIsFound() {
- SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About Elasticsearch")).build();
+ SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(matchQuery("title.verbatim", "Second Article About Elasticsearch")).build();
List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(1, articles.size());
- searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About")).build();
+ searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About"))
+ .build();
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(0, articles.size());
}
@@ -130,38 +135,48 @@ public class ElasticSearchQueryIntegrationTest {
@Test
public void givenAnalyzedQuery_whenMakeAggregationOnTermCount_thenEachTokenCountsSeparately() {
final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("title");
- final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation).execute().actionGet();
+ final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation)
+ .execute().actionGet();
final Map results = response.getAggregations().asMap();
final StringTerms topTags = (StringTerms) results.get("top_tags");
- final List keys = topTags.getBuckets().stream().map(b -> b.getKeyAsString()).collect(toList());
- Collections.sort(keys);
+ final List keys = topTags.getBuckets().stream()
+ .map(MultiBucketsAggregation.Bucket::getKeyAsString)
+ .sorted()
+ .collect(toList());
assertEquals(asList("about", "article", "data", "elasticsearch", "engines", "search", "second", "spring", "tutorial"), keys);
}
@Test
public void givenNotAnalyzedQuery_whenMakeAggregationOnTermCount_thenEachTermCountsIndividually() {
- final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("tags").order(Terms.Order.aggregation("_count", false));
- final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation).execute().actionGet();
+ final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("tags")
+ .order(Terms.Order.aggregation("_count", false));
+ final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation)
+ .execute().actionGet();
final Map results = response.getAggregations().asMap();
final StringTerms topTags = (StringTerms) results.get("top_tags");
- final List keys = topTags.getBuckets().stream().map(b -> b.getKeyAsString()).collect(toList());
+ final List keys = topTags.getBuckets().stream()
+ .map(MultiBucketsAggregation.Bucket::getKeyAsString)
+ .collect(toList());
assertEquals(asList("elasticsearch", "spring data", "search engines", "tutorial"), keys);
}
@Test
public void givenNotExactPhrase_whenUseSlop_thenQueryMatches() {
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchPhraseQuery("title", "spring elasticsearch").slop(1)).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(matchPhraseQuery("title", "spring elasticsearch").slop(1)).build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(1, articles.size());
}
@Test
public void givenPhraseWithType_whenUseFuzziness_thenQueryMatches() {
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "spring date elasticserch").operator(AND).fuzziness(Fuzziness.ONE).prefixLength(3)).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(matchQuery("title", "spring date elasticserch").operator(AND).fuzziness(Fuzziness.ONE)
+ .prefixLength(3)).build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(1, articles.size());
@@ -169,7 +184,9 @@ public class ElasticSearchQueryIntegrationTest {
@Test
public void givenMultimatchQuery_whenDoSearch_thenAllProvidedFieldsMatch() {
- final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(multiMatchQuery("tutorial").field("title").field("tags").type(MultiMatchQueryBuilder.Type.BEST_FIELDS)).build();
+ final SearchQuery searchQuery = new NativeSearchQueryBuilder()
+ .withQuery(multiMatchQuery("tutorial").field("title").field("tags")
+ .type(MultiMatchQueryBuilder.Type.BEST_FIELDS)).build();
final List articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(2, articles.size());
diff --git a/spring-reactive-websocket/pom.xml b/spring-reactive-websocket/pom.xml
deleted file mode 100644
index 846cece177..0000000000
--- a/spring-reactive-websocket/pom.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
- 4.0.0
-
- spring-reactive-websocket
- 0.0.1-SNAPSHOT
- jar
-
- spring-reactive-websocket
- Reactive WebSockets with Spring 5
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
- UTF-8
- UTF-8
- 1.8
-
-
-
-
- org.springframework.boot
- spring-boot-starter-integration
- 2.0.0.M7
-
-
- org.springframework.boot
- spring-boot-starter-webflux
- 2.0.0.M7
-
-
- org.projectlombok
- lombok
- compile
- RELEASE
-
-
-
-
-
-
- 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
-
-
-
-
-
-
diff --git a/spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketApplication.java b/spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketApplication.java
deleted file mode 100644
index f8952d750d..0000000000
--- a/spring-reactive-websocket/src/main/java/com/baeldung/ReactiveWebSocketApplication.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.baeldung;
-
-import java.net.URI;
-import java.time.Duration;
-
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Bean;
-import org.springframework.web.reactive.socket.WebSocketMessage;
-import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
-import org.springframework.web.reactive.socket.client.WebSocketClient;
-
-import reactor.core.publisher.Mono;
-
-@SpringBootApplication
-public class ReactiveWebSocketApplication {
- public static void main(String[] args) {
- SpringApplication.run(ReactiveWebSocketApplication.class, args);
- }
-
- /**
- * Spring Reactive WebSocket Client
- * **/
- @Bean
- CommandLineRunner runner() {
- return run -> {
- WebSocketClient client = new ReactorNettyWebSocketClient();
- client.execute(URI.create("ws://localhost:8080/event-emitter"), session -> session.send(Mono.just(session.textMessage("event-me-from-spring-reactive-client")))
- .thenMany(session.receive()
- .map(WebSocketMessage::getPayloadAsText)
- .log())
- .then())
- .block();
-// .block(Duration.ofSeconds(10L));//force timeout after given duration
- };
- }
-}
diff --git a/spring-rest-embedded-tomcat/pom.xml b/spring-rest-embedded-tomcat/pom.xml
index cee9933c0d..3622e84101 100644
--- a/spring-rest-embedded-tomcat/pom.xml
+++ b/spring-rest-embedded-tomcat/pom.xml
@@ -84,14 +84,13 @@
**/JdbcTest.java
**/*LiveTest.java
-
- 5.0.1.RELEASE
+ 5.0.2.RELEASE
2.19.1
4.12
2.9.2