stream = valueList.stream();
return stream.skip(count - 1).findFirst().orElse(null);
}
diff --git a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java b/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java
index 73a10a57f4..5005cf7f47 100644
--- a/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java
+++ b/core-java-8/src/test/java/com/baeldung/java8/Java8StreamApiUnitTest.java
@@ -1,6 +1,6 @@
package com.baeldung.java8;
-import com.baeldung.streamApi.Product;
+import com.baeldung.stream.Product;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
diff --git a/core-java-8/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java b/core-java-8/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java
index c28d6300e0..2c88dc5ec7 100644
--- a/core-java-8/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java
+++ b/core-java-8/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java
@@ -6,6 +6,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
+import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -65,7 +66,9 @@ public class PrimitiveStreamsUnitTest {
@Test
public void givenAnArrayWhenSumIsCalledThenTheCorrectSumIsReturned() {
- int sum = Arrays.asList(33,45).stream().mapToInt(a -> a).sum();
+ int sum = Stream.of(33,45)
+ .mapToInt(i -> i)
+ .sum();
assertEquals(78, sum);
}
diff --git a/core-java/README.md b/core-java/README.md
index b965d25f88..94d203533e 100644
--- a/core-java/README.md
+++ b/core-java/README.md
@@ -131,4 +131,5 @@
- [How to Invert an Array in Java](http://www.baeldung.com/java-invert-array)
- [Guide to the Cipher Class](http://www.baeldung.com/java-cipher-class)
- [A Guide to Java Initialization](http://www.baeldung.com/java-initialization)
-
+- [Implementing a Binary Tree in Java](http://www.baeldung.com/java-binary-tree)
+- [A Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random)
diff --git a/core-java/pom.xml b/core-java/pom.xml
index f99e4d68cf..5c1e9fcad0 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -389,6 +389,16 @@
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.0.0-M1
+
+ 1.8
+ 1.8
+
+
diff --git a/core-java/src/main/java/com/baeldung/javadoc/Person.java b/core-java/src/main/java/com/baeldung/javadoc/Person.java
new file mode 100644
index 0000000000..5efb410de4
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/javadoc/Person.java
@@ -0,0 +1,22 @@
+package com.baeldung.javadoc;
+
+public class Person {
+ /**
+ * This is a first name
+ */
+ private String firstName;
+ private String lastName;
+
+ 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;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java b/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java
new file mode 100644
index 0000000000..029a779cdb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/javadoc/SuperHero.java
@@ -0,0 +1,64 @@
+package com.baeldung.javadoc;
+
+/**
+ * Hero is the main entity we will be using to . . .
+ * @author Captain America
+ *
+ */
+public class SuperHero extends Person {
+
+ /**
+ * The public name of a hero that is common knowledge
+ */
+ private String heroName;
+ private String uniquePower;
+ private int health;
+ private int defense;
+
+ /**
+ * This is a simple description of the method. . .
+ * Superman!
+ *
+ * @param incomingDamage the amount of incoming damage
+ * @return the amount of health hero has after attack
+ * @see HERO-402
+ * @since 1.0
+ */
+ public int successfullyAttacked(int incomingDamage, String damageType) {
+ // do things
+ return 0;
+ }
+
+ public String getHeroName() {
+ return heroName;
+ }
+
+ public void setHeroName(String heroName) {
+ this.heroName = heroName;
+ }
+
+ public String getUniquePower() {
+ return uniquePower;
+ }
+
+ public void setUniquePower(String uniquePower) {
+ this.uniquePower = uniquePower;
+ }
+
+ public int getHealth() {
+ return health;
+ }
+
+ public void setHealth(int health) {
+ this.health = health;
+ }
+
+ public int getDefense() {
+ return defense;
+ }
+
+ public void setDefense(int defense) {
+ this.defense = defense;
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/socket/EchoMultiServer.java b/core-java/src/main/java/com/baeldung/socket/EchoMultiServer.java
index a9f055f8f4..d2f9f0459c 100644
--- a/core-java/src/main/java/com/baeldung/socket/EchoMultiServer.java
+++ b/core-java/src/main/java/com/baeldung/socket/EchoMultiServer.java
@@ -16,7 +16,7 @@ public class EchoMultiServer {
try {
serverSocket = new ServerSocket(port);
while (true)
- new EchoClientHandler(serverSocket.accept()).run();
+ new EchoClientHandler(serverSocket.accept()).start();
} catch (IOException e) {
e.printStackTrace();
diff --git a/core-java/src/main/java/com/baeldung/threadlocalrandom/ThreadLocalRandomBenchMarkRunner.java b/core-java/src/main/java/com/baeldung/threadlocalrandom/ThreadLocalRandomBenchMarkRunner.java
new file mode 100644
index 0000000000..e9c8056ff5
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/threadlocalrandom/ThreadLocalRandomBenchMarkRunner.java
@@ -0,0 +1,22 @@
+package com.baeldung.threadlocalrandom;
+
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+public class ThreadLocalRandomBenchMarkRunner {
+
+ public static void main(String[] args) throws Exception {
+
+ Options options = new OptionsBuilder().include(ThreadLocalRandomBenchMarker.class.getSimpleName())
+ .threads(1)
+ .forks(1)
+ .shouldFailOnError(true)
+ .shouldDoGC(true)
+ .jvmArgs("-server")
+ .build();
+
+ new Runner(options).run();
+
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/threadlocalrandom/ThreadLocalRandomBenchMarker.java b/core-java/src/main/java/com/baeldung/threadlocalrandom/ThreadLocalRandomBenchMarker.java
new file mode 100644
index 0000000000..8a0e2d2826
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/threadlocalrandom/ThreadLocalRandomBenchMarker.java
@@ -0,0 +1,64 @@
+package com.baeldung.threadlocalrandom;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+@BenchmarkMode(Mode.AverageTime)
+@Warmup(iterations = 1)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Benchmark)
+public class ThreadLocalRandomBenchMarker {
+
+ List> randomCallables = new ArrayList<>();
+ List> threadLocalRandomCallables = new ArrayList<>();
+
+ @Setup(Level.Iteration)
+ public void init() {
+ Random random = new Random();
+ randomCallables = new ArrayList<>();
+ threadLocalRandomCallables = new ArrayList<>();
+ for (int i = 0; i < 1000; i++) {
+ randomCallables.add(() -> {
+ return random.nextInt();
+ });
+ }
+
+ for (int i = 0; i < 1000; i++) {
+ threadLocalRandomCallables.add(() -> {
+ return ThreadLocalRandom.current()
+ .nextInt();
+ });
+ }
+ }
+
+ @Benchmark
+ public void randomValuesUsingRandom() throws InterruptedException {
+ ExecutorService executor = Executors.newWorkStealingPool();
+ executor.invokeAll(randomCallables);
+ executor.shutdown();
+ }
+
+ @Benchmark
+ public void randomValuesUsingThreadLocalRandom() throws InterruptedException {
+ ExecutorService executor = Executors.newWorkStealingPool();
+ executor.invokeAll(threadLocalRandomCallables);
+ executor.shutdown();
+ }
+
+}
diff --git a/hibernate5/README.md b/hibernate5/README.md
index d480a7455c..1eb090f05d 100644
--- a/hibernate5/README.md
+++ b/hibernate5/README.md
@@ -4,3 +4,4 @@
- [An Overview of Identifiers in Hibernate](http://www.baeldung.com/hibernate-identifiers)
- [Hibernate – Mapping Date and Time](http://www.baeldung.com/hibernate-date-time)
- [Hibernate Inheritance Mapping](http://www.baeldung.com/hibernate-inheritance)
+- [A Guide to Multitenancy in Hibernate 5](http://www.baeldung.com/hibernate-5-multitenancy)
diff --git a/java-lite/README.md b/java-lite/README.md
new file mode 100644
index 0000000000..bcb84e186e
--- /dev/null
+++ b/java-lite/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [RESTFul CRUD application with JavaLite] ()
\ No newline at end of file
diff --git a/java-lite/pom.xml b/java-lite/pom.xml
new file mode 100644
index 0000000000..554819f6e4
--- /dev/null
+++ b/java-lite/pom.xml
@@ -0,0 +1,105 @@
+
+
+ 4.0.0
+
+ org.baeldung
+ java-lite
+ 1.0-SNAPSHOT
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ 9.3.4.RC1
+ 1.4.13
+ 1.15
+ 5.1.45
+ 1.7.0
+ 1.8.2
+ 4.11
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-maven-plugin
+ ${jetty.maven.plugin.version}
+
+
+
+ activejdbc.log
+
+
+
+ active_reload
+ true
+
+
+ activeweb.log.request
+ true
+
+
+
+
+
+
+ org.javalite
+ activejdbc-instrumentation
+ ${activejdbc.version}
+
+
+ process-classes
+
+ instrument
+
+
+
+
+
+
+
+
+
+ org.javalite
+ activeweb
+ ${activeweb.version}
+
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.connector.java.version}
+
+
+
+ com.sun
+ tools
+ ${sun.tools.version}
+ system
+ ${java.home}/../lib/tools.jar
+
+
+
+ org.codehaus.jackson
+ jackson-core-lgpl
+ ${jackson.version}
+
+
+ org.codehaus.jackson
+ jackson-mapper-lgpl
+ ${jackson.version}
+
+
+ junit
+ junit
+ ${junit.version}
+
+
+
+
\ No newline at end of file
diff --git a/java-lite/src/main/java/app/config/AppBootstrap.java b/java-lite/src/main/java/app/config/AppBootstrap.java
new file mode 100644
index 0000000000..7a87c2d0a7
--- /dev/null
+++ b/java-lite/src/main/java/app/config/AppBootstrap.java
@@ -0,0 +1,9 @@
+package app.config;
+
+import org.javalite.activeweb.AppContext;
+import org.javalite.activeweb.Bootstrap;
+
+public class AppBootstrap extends Bootstrap {
+ public void init(AppContext context) {
+ }
+}
diff --git a/java-lite/src/main/java/app/config/AppControllerConfig.java b/java-lite/src/main/java/app/config/AppControllerConfig.java
new file mode 100644
index 0000000000..42b7e728ec
--- /dev/null
+++ b/java-lite/src/main/java/app/config/AppControllerConfig.java
@@ -0,0 +1,15 @@
+package app.config;
+
+import app.controllers.ProductsController;
+import org.javalite.activeweb.AbstractControllerConfig;
+import org.javalite.activeweb.AppContext;
+import org.javalite.activeweb.controller_filters.DBConnectionFilter;
+import org.javalite.activeweb.controller_filters.TimingFilter;
+
+public class AppControllerConfig extends AbstractControllerConfig {
+ @Override
+ public void init(AppContext appContext) {
+ addGlobalFilters(new TimingFilter());
+ add(new DBConnectionFilter()).to(ProductsController.class);
+ }
+}
diff --git a/java-lite/src/main/java/app/config/DbConfig.java b/java-lite/src/main/java/app/config/DbConfig.java
new file mode 100644
index 0000000000..25ba378b22
--- /dev/null
+++ b/java-lite/src/main/java/app/config/DbConfig.java
@@ -0,0 +1,11 @@
+package app.config;
+
+import org.javalite.activeweb.AbstractDBConfig;
+import org.javalite.activeweb.AppContext;
+
+public class DbConfig extends AbstractDBConfig {
+ @Override
+ public void init(AppContext appContext) {
+ this.configFile("/database.properties");
+ }
+}
diff --git a/java-lite/src/main/java/app/controllers/ProductsController.java b/java-lite/src/main/java/app/controllers/ProductsController.java
new file mode 100644
index 0000000000..f68dd9a013
--- /dev/null
+++ b/java-lite/src/main/java/app/controllers/ProductsController.java
@@ -0,0 +1,101 @@
+package app.controllers;
+
+import app.models.Product;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.javalite.activeweb.AppController;
+import org.javalite.activeweb.annotations.RESTful;
+
+import java.util.Map;
+
+@RESTful
+public class ProductsController extends AppController {
+
+ public void index() {
+ try {
+ view("products", Product.findAll());
+ render().contentType("application/json");
+ } catch (Exception e) {
+ view("message", "There was an error.", "code", 200);
+ render("message");
+ }
+ }
+
+ public void create() {
+ try {
+ Map payload = new ObjectMapper().readValue(getRequestString(), Map.class);
+ Product p = new Product();
+ p.fromMap(payload);
+ p.saveIt();
+ view("message", "Successfully saved product id " + p.get("id"), "code", 200);
+ render("message");
+ } catch (Exception e) {
+ view("message", "There was an error.", "code", 200);
+ render("message");
+ }
+ }
+
+ public void update() {
+ try {
+ Map payload = new ObjectMapper().readValue(getRequestString(), Map.class);
+ String id = getId();
+ Product p = Product.findById(id);
+ if (p == null) {
+ view("message", "Product id " + id + " not found.", "code", 200);
+ render("message");
+ return;
+ }
+ p.fromMap(payload);
+ p.saveIt();
+ view("message", "Successfully updated product id " + id, "code", 200);
+ render("message");
+ } catch (Exception e) {
+ view("message", "There was an error.", "code", 200);
+ render("message");
+ }
+ }
+
+ public void show() {
+ try {
+ String id = getId();
+ Product p = Product.findById(id);
+ if (p == null) {
+ view("message", "Product id " + id + " not found.", "code", 200);
+ render("message");
+ return;
+ }
+ view("product", p);
+ render("_product");
+ } catch (Exception e) {
+ view("message", "There was an error.", "code", 200);
+ render("message");
+ }
+ }
+
+ public void destroy() {
+ try {
+ String id = getId();
+ Product p = Product.findById(id);
+ if (p == null) {
+ view("message", "Product id " + id + " not found.", "code", 200);
+ render("message");
+ return;
+ }
+ p.delete();
+ view("message", "Successfully deleted product id " + id, "code", 200);
+ render("message");
+ } catch (Exception e) {
+ view("message", "There was an error.", "code", 200);
+ render("message");
+ }
+ }
+
+ @Override
+ protected String getContentType() {
+ return "application/json";
+ }
+
+ @Override
+ protected String getLayout() {
+ return null;
+ }
+}
diff --git a/java-lite/src/main/java/app/models/Product.java b/java-lite/src/main/java/app/models/Product.java
new file mode 100644
index 0000000000..7fa32b75d9
--- /dev/null
+++ b/java-lite/src/main/java/app/models/Product.java
@@ -0,0 +1,7 @@
+package app.models;
+
+import org.javalite.activejdbc.Model;
+
+public class Product extends Model {
+
+}
diff --git a/java-lite/src/main/resources/database.properties b/java-lite/src/main/resources/database.properties
new file mode 100644
index 0000000000..55b3851d33
--- /dev/null
+++ b/java-lite/src/main/resources/database.properties
@@ -0,0 +1,4 @@
+development.driver=com.mysql.jdbc.Driver
+development.username=user
+development.password=password
+development.url=jdbc:mysql://localhost/dbname
\ No newline at end of file
diff --git a/java-lite/src/main/webapp/WEB-INF/views/products/_comma.ftl b/java-lite/src/main/webapp/WEB-INF/views/products/_comma.ftl
new file mode 100644
index 0000000000..41622b4720
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/views/products/_comma.ftl
@@ -0,0 +1 @@
+,
\ No newline at end of file
diff --git a/java-lite/src/main/webapp/WEB-INF/views/products/_product.ftl b/java-lite/src/main/webapp/WEB-INF/views/products/_product.ftl
new file mode 100644
index 0000000000..562af0499e
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/views/products/_product.ftl
@@ -0,0 +1,4 @@
+{
+"id" : ${product.id},
+"name" : "${product.name}"
+}
\ No newline at end of file
diff --git a/java-lite/src/main/webapp/WEB-INF/views/products/index.ftl b/java-lite/src/main/webapp/WEB-INF/views/products/index.ftl
new file mode 100644
index 0000000000..c343f20910
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/views/products/index.ftl
@@ -0,0 +1 @@
+[<@render partial="product" collection=products spacer="comma"/>]
\ No newline at end of file
diff --git a/java-lite/src/main/webapp/WEB-INF/views/products/message.ftl b/java-lite/src/main/webapp/WEB-INF/views/products/message.ftl
new file mode 100644
index 0000000000..3e7faf1459
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/views/products/message.ftl
@@ -0,0 +1,4 @@
+{
+"message" : "${message}",
+"code" : ${code}
+}
\ No newline at end of file
diff --git a/java-lite/src/main/webapp/WEB-INF/web.xml b/java-lite/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..c285876c86
--- /dev/null
+++ b/java-lite/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+ dispatcher
+ org.javalite.activeweb.RequestDispatcher
+
+ exclusions
+ css,images,js,ico
+
+
+ encoding
+ UTF-8
+
+
+
+
+
+ dispatcher
+ /*
+
+
+
diff --git a/java-lite/src/test/java/app/models/ProductTest.java b/java-lite/src/test/java/app/models/ProductTest.java
new file mode 100644
index 0000000000..f6ee0a3d0a
--- /dev/null
+++ b/java-lite/src/test/java/app/models/ProductTest.java
@@ -0,0 +1,25 @@
+package app.models;
+
+import org.javalite.activejdbc.Base;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ProductTest {
+
+ //@Test
+ public void givenSavedProduct_WhenFindFirst_ThenSavedProductIsReturned() {
+ //Open DB connection
+ Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/dbname", "user", "password");
+
+ //Create a product and save it
+ Product toSaveProduct = new Product();
+ toSaveProduct.set("name", "Bread");
+ toSaveProduct.saveIt();
+
+ //Find product
+ Product savedProduct = Product.findFirst("name = ?", "Bread");
+
+ Assert.assertEquals(toSaveProduct.get("name"), savedProduct.get("name"));
+ }
+
+}
\ No newline at end of file
diff --git a/persistence-modules/java-cockroachdb/README.md b/persistence-modules/java-cockroachdb/README.md
new file mode 100644
index 0000000000..0f0381212d
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Guide to CockroachDB in Java](http://www.baeldung.com/)
diff --git a/persistence-modules/java-cockroachdb/pom.xml b/persistence-modules/java-cockroachdb/pom.xml
new file mode 100644
index 0000000000..2b6f9651bc
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/pom.xml
@@ -0,0 +1,74 @@
+
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ ../../
+
+
+ 4.0.0
+
+ com.baeldung
+ java-cockroachdb
+ 1.0-SNAPSHOT
+
+
+ 42.1.4
+
+
+
+
+ org.postgresql
+ postgresql
+ ${postgresql.version}
+
+
+
+
+
+ integration
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ integration-test
+
+ test
+
+
+
+ **/*ManualTest.java
+
+
+ **/*IntegrationTest.java
+
+
+
+
+
+
+ json
+
+
+
+
+
+
+
+
+
+
+ Central
+ Central
+ http://repo1.maven.org/maven2/
+ default
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/domain/Article.java b/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/domain/Article.java
new file mode 100644
index 0000000000..dcc9dfb5b7
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/domain/Article.java
@@ -0,0 +1,43 @@
+package com.baeldung.cockroachdb.domain;
+
+import java.util.UUID;
+
+public class Article {
+
+ private UUID id;
+
+ private String title;
+
+ private String author;
+
+ public Article(UUID id, String title, String author) {
+ this.id = id;
+ this.title = title;
+ this.author = author;
+ }
+
+ public UUID getId() {
+ return id;
+ }
+
+ public void setId(UUID id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+}
diff --git a/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/repository/ArticleRepository.java b/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/repository/ArticleRepository.java
new file mode 100644
index 0000000000..a37c19e397
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/src/main/java/com/baeldung/cockroachdb/repository/ArticleRepository.java
@@ -0,0 +1,172 @@
+package com.baeldung.cockroachdb.repository;
+
+import com.baeldung.cockroachdb.domain.Article;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Repository for the articles table related operations
+ */
+public class ArticleRepository {
+
+ private static final String TABLE_NAME = "articles";
+ private Connection connection;
+
+ public ArticleRepository(Connection connection) {
+ this.connection = connection;
+ }
+
+ /**
+ * Creates the articles table.
+ */
+ public void createTable() throws SQLException {
+ StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(TABLE_NAME)
+ .append("(id uuid PRIMARY KEY, ")
+ .append("title string,")
+ .append("author string)");
+
+ final String query = sb.toString();
+ Statement stmt = connection.createStatement();
+ stmt.execute(query);
+ }
+
+ /**
+ * Alter the articles table adding a column
+ *
+ * @param columnName Column name of the additional column
+ * @param columnType Column type of the additional column
+ * @throws SQLException
+ */
+ public void alterTable(String columnName, String columnType) throws SQLException {
+ StringBuilder sb = new StringBuilder("ALTER TABLE ").append(TABLE_NAME)
+ .append(" ADD ")
+ .append(columnName)
+ .append(" ")
+ .append(columnType);
+
+ final String query = sb.toString();
+ Statement stmt = connection.createStatement();
+ stmt.execute(query);
+ }
+
+ /**
+ * Insert a new article in the articles table
+ *
+ * @param article New article to insert
+ * @throws SQLException
+ */
+ public void insertArticle(Article article) throws SQLException {
+ StringBuilder sb = new StringBuilder("INSERT INTO ").append(TABLE_NAME)
+ .append("(id, title, author) ")
+ .append("VALUES (?,?,?)");
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, article.getId().toString());
+ preparedStatement.setString(2, article.getTitle());
+ preparedStatement.setString(3, article.getAuthor());
+ preparedStatement.execute();
+ }
+
+ /**
+ * Select article by Title
+ *
+ * @param title title of the article to retrieve
+ * @return article with the given title
+ * @throws SQLException
+ */
+ public Article selectByTitle(String title) throws SQLException {
+ StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME)
+ .append(" WHERE title = ?");
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, title);
+
+ try (ResultSet rs = preparedStatement.executeQuery()) {
+
+ List articles = new ArrayList<>();
+
+ while (rs.next()) {
+ Article article = new Article(
+ UUID.fromString(rs.getString("id")),
+ rs.getString("title"),
+ rs.getString("author")
+ );
+ articles.add(article);
+ }
+ return articles.get(0);
+ }
+
+ }
+
+ /**
+ * Select all the articles
+ *
+ * @return list of all articles
+ * @throws SQLException
+ */
+ public List selectAll() throws SQLException {
+ StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME);
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ try (ResultSet rs = preparedStatement.executeQuery()) {
+
+ List articles = new ArrayList<>();
+
+ while (rs.next()) {
+ Article article = new Article(
+ UUID.fromString(rs.getString("id")),
+ rs.getString("title"),
+ rs.getString("author")
+ );
+ articles.add(article);
+ }
+ return articles;
+ }
+ }
+
+ /**
+ * Delete article by title
+ *
+ * @param title title of the article to delete
+ * @throws SQLException
+ */
+ public void deleteArticleByTitle(String title) throws SQLException {
+ StringBuilder sb = new StringBuilder("DELETE FROM ").append(TABLE_NAME)
+ .append(" WHERE title = ?");
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = connection.prepareStatement(query);
+ preparedStatement.setString(1, title);
+ preparedStatement.execute();
+ }
+
+ /**
+ * Delete all rows in the table
+ *
+ * @throws SQLException
+ */
+ public void truncateTable() throws SQLException {
+ StringBuilder sb = new StringBuilder("TRUNCATE TABLE ").append(TABLE_NAME);
+
+ final String query = sb.toString();
+ Statement stmt = connection.createStatement();
+ stmt.execute(query);
+ }
+
+ /**
+ * Delete table
+ */
+ public void deleteTable() throws SQLException {
+ StringBuilder sb = new StringBuilder("DROP TABLE IF EXISTS ").append(TABLE_NAME);
+
+ final String query = sb.toString();
+ Statement stmt = connection.createStatement();
+ stmt.execute(query);
+ }
+}
diff --git a/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java
new file mode 100644
index 0000000000..9eb00b3651
--- /dev/null
+++ b/persistence-modules/java-cockroachdb/src/test/java/com/baeldung/cockroachdb/ArticleRepositoryIntegrationTest.java
@@ -0,0 +1,208 @@
+package com.baeldung.cockroachdb;
+
+import com.baeldung.cockroachdb.domain.Article;
+import com.baeldung.cockroachdb.repository.ArticleRepository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.postgresql.util.PSQLException;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ArticleRepositoryIntegrationTest {
+
+ private static final String TABLE_NAME = "articles";
+
+ private Connection con;
+ private ArticleRepository articleRepository;
+
+ @Before
+ public void connect() throws Exception {
+ Class.forName("org.postgresql.Driver");
+ con = DriverManager.getConnection("jdbc:postgresql://localhost:26257/testdb", "user17", "qwerty");
+
+ articleRepository = new ArticleRepository(con);
+ }
+
+ @Test
+ public void whenCreatingTable_thenCreatedCorrectly() throws Exception {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ PreparedStatement preparedStatement = con.prepareStatement("SHOW TABLES");
+ ResultSet resultSet = preparedStatement.executeQuery();
+ List tables = new ArrayList<>();
+ while (resultSet.next()) {
+ tables.add(resultSet.getString("Table"));
+ }
+
+ assertTrue(tables.stream().anyMatch(t -> t.equals(TABLE_NAME)));
+ }
+
+ @Test
+ public void whenAlteringTheTable_thenColumnAddedCorrectly() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ String columnName = "creationdate";
+ articleRepository.alterTable(columnName, "DATE");
+
+ String query = "SHOW COLUMNS FROM " + TABLE_NAME;
+ PreparedStatement preparedStatement = con.prepareStatement(query);
+ ResultSet resultSet = preparedStatement.executeQuery();
+ List columns = new ArrayList<>();
+ while (resultSet.next()) {
+ columns.add(resultSet.getString("Field"));
+ }
+
+ assertTrue(columns.stream().anyMatch(c -> c.equals(columnName)));
+ }
+
+ @Test
+ public void whenInsertingNewArticle_thenArticleExists() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ String title = "Guide to CockroachDB in Java";
+ String author = "baeldung";
+ Article article = new Article(UUID.randomUUID(), title, author);
+ articleRepository.insertArticle(article);
+
+ Article savedArticle = articleRepository.selectByTitle(title);
+ assertEquals(article.getTitle(), savedArticle.getTitle());
+ }
+
+ @Test
+ public void whenSelectingAllArticles_thenAllArticlesAreReturned() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ List savedArticles = articleRepository.selectAll();
+
+ assertEquals(2, savedArticles.size());
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
+ }
+
+ @Test
+ public void whenDeletingArticleByTtile_thenArticleIsDeleted() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ articleRepository.deleteArticleByTitle("A Guide to MongoDB with Java");
+
+ List savedArticles = articleRepository.selectAll();
+ assertEquals(1, savedArticles.size());
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
+ assertFalse(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
+ }
+
+ @Test(expected = PSQLException.class)
+ public void whenDeletingATable_thenExceptionIfAccessed() throws SQLException {
+ articleRepository.createTable();
+ articleRepository.deleteTable();
+
+ StringBuilder sb = new StringBuilder("SELECT * FROM ").append(TABLE_NAME);
+
+ final String query = sb.toString();
+ PreparedStatement preparedStatement = con.prepareStatement(query);
+ preparedStatement.executeQuery();
+ }
+
+ @Test
+ public void whenTruncatingATable_thenEmptyTable() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ articleRepository.truncateTable();
+
+ List savedArticles = articleRepository.selectAll();
+ assertEquals(0, savedArticles.size());
+ }
+
+ @Test
+ public void whenInsertingTwoArticlesWithSamePrimaryKeyInASingleTransaction_thenRollback() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ try {
+ con.setAutoCommit(false);
+
+ UUID articleId = UUID.randomUUID();
+
+ Article article = new Article(articleId, "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(articleId, "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ con.commit();
+ } catch (Exception e) {
+ con.rollback();
+ } finally {
+ con.setAutoCommit(true);
+ }
+
+ List savedArticles = articleRepository.selectAll();
+ assertEquals(0, savedArticles.size());
+ }
+
+ @Test
+ public void whenInsertingTwoArticlesInASingleTransaction_thenInserted() throws SQLException {
+ articleRepository.deleteTable();
+ articleRepository.createTable();
+
+ try {
+ con.setAutoCommit(false);
+
+ Article article = new Article(UUID.randomUUID(), "Guide to CockroachDB in Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ article = new Article(UUID.randomUUID(), "A Guide to MongoDB with Java", "baeldung");
+ articleRepository.insertArticle(article);
+
+ con.commit();
+ } catch (Exception e) {
+ con.rollback();
+ } finally {
+ con.setAutoCommit(true);
+ }
+
+ List savedArticles = articleRepository.selectAll();
+ assertEquals(2, savedArticles.size());
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("Guide to CockroachDB in Java")));
+ assertTrue(savedArticles.stream().anyMatch(a -> a.getTitle().equals("A Guide to MongoDB with Java")));
+ }
+
+ @After
+ public void disconnect() throws SQLException {
+ articleRepository = null;
+ con.close();
+ con = null;
+ }
+}
diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml
index 88db38b2fc..86e952c0e4 100644
--- a/persistence-modules/spring-hibernate-5/pom.xml
+++ b/persistence-modules/spring-hibernate-5/pom.xml
@@ -179,7 +179,7 @@
- 4.3.10.RELEASE
+ 5.0.2.RELEASE
1.10.6.RELEASE
diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java
index 6f359054b6..5dace1f742 100644
--- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java
+++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java
@@ -10,8 +10,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
-import org.springframework.orm.hibernate4.HibernateTransactionManager;
-import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
+import org.springframework.orm.hibernate5.HibernateTransactionManager;
+import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
diff --git a/pom.xml b/pom.xml
index 38fa010f95..1050bb8ba2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,7 @@
jackson
vavr
+ java-lite
javax-servlets
javaxval
jaxb
@@ -268,6 +269,7 @@
deeplearning4j
lucene
vraptor
+ persistence-modules/java-cockroachdb
diff --git a/spring-custom-aop/spring-custom-aop/pom.xml b/spring-custom-aop/spring-custom-aop/pom.xml
index 7e9da03b54..0bab7a4057 100644
--- a/spring-custom-aop/spring-custom-aop/pom.xml
+++ b/spring-custom-aop/spring-custom-aop/pom.xml
@@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.baeldung
- spring-boot
+ spring-custom-aop
0.0.1-SNAPSHOT
war
spring-boot
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/EndpointDTO.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/EndpointDTO.java
new file mode 100644
index 0000000000..d12d6419e1
--- /dev/null
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/EndpointDTO.java
@@ -0,0 +1,39 @@
+package org.baeldung.endpoints;
+
+public class EndpointDTO {
+ private String id;
+ private boolean enabled;
+ private boolean sensitive;
+
+ public EndpointDTO(String id, boolean enabled, boolean sensitive) {
+ super();
+ this.id = id;
+ this.enabled = enabled;
+ this.sensitive = sensitive;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public boolean isSensitive() {
+ return sensitive;
+ }
+
+ public void setSensitive(boolean sensitive) {
+ this.sensitive = sensitive;
+ }
+
+}
diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java
index 0add741a1f..f434351a51 100644
--- a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java
+++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java
@@ -1,6 +1,7 @@
package org.baeldung.endpoints;
import java.util.List;
+import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
@@ -8,16 +9,16 @@ import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.stereotype.Component;
@Component
-public class ListEndpoints extends AbstractEndpoint> {
- private List endpoints;
+public class ListEndpoints extends AbstractEndpoint> {
+ private List endpointDTOs;
@Autowired
public ListEndpoints(List endpoints) {
super("listEndpoints");
- this.endpoints = endpoints;
+ this.endpointDTOs = endpoints.stream().map(endpoint -> new EndpointDTO(endpoint.getId(), endpoint.isEnabled(), endpoint.isSensitive())).collect(Collectors.toList());
}
- public List invoke() {
- return this.endpoints;
+ public List invoke() {
+ return this.endpointDTOs;
}
}
\ No newline at end of file
diff --git a/spring-jenkins-pipeline/README.md b/spring-jenkins-pipeline/README.md
index 7e562664e6..8c10e85da2 100644
--- a/spring-jenkins-pipeline/README.md
+++ b/spring-jenkins-pipeline/README.md
@@ -10,7 +10,6 @@ This is the code of a simple API for some CRUD operations build using Spring Boo
- MongoDB
### Running
-
To build and start the server simply type
```bash
@@ -20,4 +19,8 @@ $ mvn spring-boot:run -Dserver.port=8989
Now with default configurations it will be available at: [http://localhost:8080](http://localhost:8080)
-Enjoy it :)
\ No newline at end of file
+Enjoy it :)
+
+### Relevant articles
+
+- [Intro to Jenkins 2 and the Power of Pipelines](http://www.baeldung.com/jenkins-pipelines)
diff --git a/vavr/src/main/java/com/baeldung/vavr/future/Util.java b/vavr/src/main/java/com/baeldung/vavr/future/Util.java
deleted file mode 100644
index 790ef2bf88..0000000000
--- a/vavr/src/main/java/com/baeldung/vavr/future/Util.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.baeldung.vavr.future;
-
-public class Util {
-
- public static String appendData(String initial) {
- return initial + "Baeldung!";
- }
-
- public static int divideByZero(int num) {
- return num / 0;
- }
-
- public static String getSubstringMinusOne(String s) {
- return s.substring(-1);
- }
-
- public static String getSubstringMinusTwo(String s) {
- return s.substring(-2);
- }
-}
diff --git a/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java b/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java
index dd678bcad0..002919a937 100644
--- a/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java
+++ b/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java
@@ -1,119 +1,102 @@
package com.baeldung.vavr.future;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executors;
-
-import org.junit.Test;
-
import io.vavr.Tuple;
-import io.vavr.Tuple2;
import io.vavr.concurrent.Future;
import io.vavr.control.Option;
import io.vavr.control.Try;
+import org.junit.Test;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
public class FutureTest {
-
+
private static final String error = "Failed to get underlying value.";
+ private static final String HELLO = "Welcome to Baeldung!";
@Test
- public void whenChangeExecutorService_thenCorrect() throws InterruptedException {
- String initialValue = "Welcome to ";
- Future resultFuture = Future.of(
- Executors.newSingleThreadExecutor(),
- () -> Util.appendData(initialValue));
- Thread.sleep(20);
- String result = resultFuture.getOrElse(error);
+ public void whenChangeExecutorService_thenCorrect() {
+ String result = Future.of(newSingleThreadExecutor(), () -> HELLO)
+ .getOrElse(error);
- assertThat(result).isEqualTo("Welcome to Baeldung!");
+ assertThat(result)
+ .isEqualTo(HELLO);
}
@Test
- public void whenAppendData_thenCorrect1() throws InterruptedException {
- String initialValue = "Welcome to ";
- Future resultFuture = Future.of(() -> Util.appendData(initialValue));
- Thread.sleep(20);
- String result = resultFuture.getOrElse(new String(error));
+ public void whenAppendData_thenCorrect1() {
+ String result = Future.of(() -> HELLO)
+ .getOrElse(error);
- assertThat(result).isEqualTo("Welcome to Baeldung!");
+ assertThat(result)
+ .isEqualTo(HELLO);
}
@Test
- public void whenAppendData_thenCorrect2() throws InterruptedException {
- String initialValue = "Welcome to ";
- Future resultFuture = Future.of(() -> Util.appendData(initialValue));
- Thread.sleep(20);
- resultFuture.await();
+ public void whenAppendData_thenCorrect2() {
+ Future resultFuture = Future.of(() -> HELLO)
+ .await();
+
Option> futureOption = resultFuture.getValue();
- Try futureTry = futureOption.get();
- String result = futureTry.getOrElse(error);
+ String result = futureOption.get().getOrElse(error);
- assertThat(result).isEqualTo("Welcome to Baeldung!");
+ assertThat(result)
+ .isEqualTo(HELLO);
}
@Test
- public void whenAppendData_thenSuccess() throws InterruptedException {
- String initialValue = "Welcome to ";
- Future resultFuture = Future.of(() -> Util.appendData(initialValue))
+ public void whenAppendData_thenSuccess() {
+ String result = Future.of(() -> HELLO)
.onSuccess(finalResult -> System.out.println("Successfully Completed - Result: " + finalResult))
- .onFailure(finalResult -> System.out.println("Failed - Result: " + finalResult));
- Thread.sleep(20);
- String result = resultFuture.getOrElse(error);
+ .onFailure(finalResult -> System.out.println("Failed - Result: " + finalResult))
+ .getOrElse(error);
- assertThat(result).isEqualTo("Welcome to Baeldung!");
+ assertThat(result)
+ .isEqualTo(HELLO);
}
@Test
- public void whenChainingCallbacks_thenCorrect() throws InterruptedException {
- String initialValue = "Welcome to ";
- Future resultFuture = Future.of(() -> Util.appendData(initialValue))
- .andThen(finalResult -> System.out.println("Completed - 1: " + finalResult))
- .andThen(finalResult -> System.out.println("Completed - 2: " + finalResult));
- Thread.sleep(20);
- String result = resultFuture.getOrElse(error);
-
- assertThat(result).isEqualTo("Welcome to Baeldung!");
+ public void whenChainingCallbacks_thenCorrect() {
+ Future.of(() -> HELLO)
+ .andThen(r -> System.out.println("Completed - 1: " + r))
+ .andThen(r -> System.out.println("Completed - 2: " + r));
}
@Test
- public void whenCallAwait_thenCorrect() throws InterruptedException {
- String initialValue = "Welcome to ";
- Future resultFuture = Future.of(() -> Util.appendData(initialValue));
- Thread.sleep(20);
- resultFuture = resultFuture.await();
- String result = resultFuture.getOrElse(error);
+ public void whenCallAwait_thenCorrect() {
+ Future resultFuture = Future.of(() -> HELLO)
+ .await();
+ String result = resultFuture.getValue().get().getOrElse(error);
- assertThat(result).isEqualTo("Welcome to Baeldung!");
+ assertThat(result)
+ .isEqualTo(HELLO);
}
@Test
- public void whenDivideByZero_thenGetThrowable1() throws InterruptedException {
- Future resultFuture = Future.of(() -> Util.divideByZero(10));
- Thread.sleep(20);
- Future throwableFuture = resultFuture.failed();
- Throwable throwable = throwableFuture.getOrElse(new Throwable());
+ public void whenDivideByZero_thenGetThrowable1() {
+ Future resultFuture = Future.of(() -> 10 / 0);
- assertThat(throwable.getMessage()).isEqualTo("/ by zero");
+ assertThatThrownBy(resultFuture::get)
+ .isInstanceOf(ArithmeticException.class);
}
@Test
- public void whenDivideByZero_thenGetThrowable2() throws InterruptedException {
- Future resultFuture = Future.of(() -> Util.divideByZero(10));
- Thread.sleep(20);
- resultFuture.await();
- Option throwableOption = resultFuture.getCause();
- Throwable throwable = throwableOption.getOrElse(new Throwable());
+ public void whenDivideByZero_thenGetThrowable2() {
+ Future resultFuture = Future.of(() -> 10 / 0)
+ .await();
- assertThat(throwable.getMessage()).isEqualTo("/ by zero");
+ assertThat(resultFuture.getCause().get().getMessage())
+ .isEqualTo("/ by zero");
}
@Test
- public void whenDivideByZero_thenCorrect() throws InterruptedException {
- Future resultFuture = Future.of(() -> Util.divideByZero(10));
- Thread.sleep(20);
- resultFuture.await();
+ public void whenDivideByZero_thenCorrect() {
+ Future resultFuture = Future.of(() -> 10 / 0)
+ .await();
assertThat(resultFuture.isCompleted()).isTrue();
assertThat(resultFuture.isSuccess()).isFalse();
@@ -121,76 +104,70 @@ public class FutureTest {
}
@Test
- public void whenAppendData_thenFutureNotEmpty() throws InterruptedException {
- String initialValue = "Welcome to ";
- Future resultFuture = Future.of(() -> Util.appendData(initialValue));
- Thread.sleep(20);
- resultFuture.await();
+ public void whenAppendData_thenFutureNotEmpty() {
+ Future resultFuture = Future.of(() -> HELLO)
+ .await();
- assertThat(resultFuture.isEmpty()).isFalse();
+ assertThat(resultFuture.isEmpty())
+ .isFalse();
}
@Test
- public void whenCallZip_thenCorrect() throws InterruptedException {
- Future> future = Future.of(() -> "John")
- .zip(Future.of(() -> new Integer(5)));
- Thread.sleep(20);
- future.await();
+ public void whenCallZip_thenCorrect() {
+ Future f1 = Future.of(() -> "hello1");
+ Future f2 = Future.of(() -> "hello2");
- assertThat(future.getOrElse(new Tuple2(error, 0)))
- .isEqualTo(Tuple.of("John", new Integer(5)));
+ assertThat(f1.zip(f2).get())
+ .isEqualTo(Tuple.of("hello1", "hello2"));
}
@Test
public void whenConvertToCompletableFuture_thenCorrect() throws InterruptedException, ExecutionException {
- String initialValue = "Welcome to ";
- Future resultFuture = Future.of(() -> Util.appendData(initialValue));
- Thread.sleep(20);
- CompletableFuture convertedFuture = resultFuture.toCompletableFuture();
+ CompletableFuture convertedFuture = Future.of(() -> HELLO)
+ .toCompletableFuture();
- assertThat(convertedFuture.get()).isEqualTo("Welcome to Baeldung!");
+ assertThat(convertedFuture.get())
+ .isEqualTo(HELLO);
}
@Test
- public void whenCallMap_thenCorrect() throws InterruptedException {
- Future futureResult = Future.of(() -> new StringBuilder("from Baeldung"))
- .map(a -> "Hello " + a);
- Thread.sleep(20);
- futureResult.await();
+ public void whenCallMap_thenCorrect() {
+ Future futureResult = Future.of(() -> "from Baeldung")
+ .map(a -> "Hello " + a)
+ .await();
- assertThat(futureResult.getOrElse(error)).isEqualTo("Hello from Baeldung");
+ assertThat(futureResult.get())
+ .isEqualTo("Hello from Baeldung");
}
@Test
- public void whenFutureFails_thenGetErrorMessage() throws InterruptedException {
- Future resultFuture = Future.of(() -> Util.getSubstringMinusOne("Hello"));
- Thread.sleep(20);
- Future errorMessageFuture = resultFuture.recover(Throwable::getMessage);
- String errorMessage = errorMessageFuture.getOrElse(error);
+ public void whenFutureFails_thenGetErrorMessage() {
+ Future future = Future.of(() -> "Hello".substring(-1))
+ .recover(x -> "fallback value");
- assertThat(errorMessage).isEqualTo("String index out of range: -1");
+ assertThat(future.get())
+ .isEqualTo("fallback value");
}
@Test
- public void whenFutureFails_thenGetAnotherFuture() throws InterruptedException {
- Future resultFuture = Future.of(() -> Util.getSubstringMinusOne("Hello"));
- Thread.sleep(20);
- Future errorMessageFuture = resultFuture.recoverWith(a -> Future.of(a::getMessage));
- String errorMessage = errorMessageFuture.getOrElse(error);
+ public void whenFutureFails_thenGetAnotherFuture() {
+ Future future = Future.of(() -> "Hello".substring(-1))
+ .recoverWith(x -> Future.of(() -> "fallback value"));
- assertThat(errorMessage).isEqualTo("String index out of range: -1");
+ assertThat(future.get())
+ .isEqualTo("fallback value");
}
@Test
- public void whenBothFuturesFail_thenGetErrorMessage() throws InterruptedException {
- Future future1 = Future.of(() -> Util.getSubstringMinusOne("Hello"));
- Future future2 = Future.of(() -> Util.getSubstringMinusTwo("Hello"));
- Thread.sleep(20);
- Future errorMessageFuture = future1.fallbackTo(future2);
+ public void whenBothFuturesFail_thenGetErrorMessage() {
+ Future f1 = Future.of(() -> "Hello".substring(-1));
+ Future f2 = Future.of(() -> "Hello".substring(-2));
+
+ Future errorMessageFuture = f1.fallbackTo(f2);
Future errorMessage = errorMessageFuture.failed();
-
+
assertThat(
- errorMessage.getOrElse(new Throwable()).getMessage())
+ errorMessage.get().getMessage())
.isEqualTo("String index out of range: -1");
}
}