diff --git a/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java b/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountManualTest.java
similarity index 99%
rename from core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java
rename to core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountManualTest.java
index 3e188d682e..013352cce9 100644
--- a/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountUnitTest.java
+++ b/core-java-modules/core-java-concurrency-advanced-3/src/test/java/com/baeldung/abaproblem/AccountManualTest.java
@@ -12,7 +12,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-public class AccountUnitTest {
+public class AccountManualTest {
private Account account;
diff --git a/core-java-modules/core-java-function/pom.xml b/core-java-modules/core-java-function/pom.xml
index a3add5a686..c05f9585b2 100644
--- a/core-java-modules/core-java-function/pom.xml
+++ b/core-java-modules/core-java-function/pom.xml
@@ -14,6 +14,26 @@
0.0.1-SNAPSHOT
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ org.mockito
+ mockito-inline
+ ${mockito-inline.version}
+ test
+
+
+
core-java-function
@@ -24,4 +44,10 @@
+
+ 3.8.0
+ 3.22.0
+ 3.12.0
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-function/src/main/java/com/baeldung/staticmethods/CustomStringUtils.java b/core-java-modules/core-java-function/src/main/java/com/baeldung/staticmethods/CustomStringUtils.java
new file mode 100644
index 0000000000..5561123e54
--- /dev/null
+++ b/core-java-modules/core-java-function/src/main/java/com/baeldung/staticmethods/CustomStringUtils.java
@@ -0,0 +1,9 @@
+package com.baeldung.staticmethods;
+
+public final class CustomStringUtils {
+
+ private CustomStringUtils() {}
+
+ public static boolean isEmpty(CharSequence cs) { return cs == null || cs.length() == 0; }
+
+}
diff --git a/core-java-modules/core-java-function/src/main/java/com/baeldung/staticmethods/StaticCounter.java b/core-java-modules/core-java-function/src/main/java/com/baeldung/staticmethods/StaticCounter.java
new file mode 100644
index 0000000000..9abf97e8df
--- /dev/null
+++ b/core-java-modules/core-java-function/src/main/java/com/baeldung/staticmethods/StaticCounter.java
@@ -0,0 +1,15 @@
+package com.baeldung.staticmethods;
+
+public class StaticCounter {
+
+ private static int counter = 0;
+
+ public static int incrementCounter() {
+ return ++counter;
+ }
+
+ public static int getCounterValue() {
+ return counter;
+ }
+
+}
diff --git a/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/CollectionUtilsUnitTest.java b/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/CollectionUtilsUnitTest.java
new file mode 100644
index 0000000000..74aac8deb7
--- /dev/null
+++ b/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/CollectionUtilsUnitTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.staticmethods;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class CollectionUtilsUnitTest {
+
+ @Test
+ void givenListOfNumbers_whenReverseStaticMethodIsCalled_thenNumbersInReversedOrderAreReturned() {
+ List list = Arrays.asList("1", "2", "3");
+ Collections.reverse(list);
+ assertThat(list).containsExactly("3", "2", "1");
+ }
+
+}
diff --git a/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/CustomStringUtilsUnitTest.java b/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/CustomStringUtilsUnitTest.java
new file mode 100644
index 0000000000..d01b97d938
--- /dev/null
+++ b/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/CustomStringUtilsUnitTest.java
@@ -0,0 +1,21 @@
+package com.baeldung.staticmethods;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class CustomStringUtilsUnitTest {
+
+ @Test
+ void givenNonEmptyString_whenIsEmptyMethodIsCalled_thenFalseIsReturned() {
+ boolean empty = CustomStringUtils.isEmpty("baeldung");
+ assertThat(empty).isFalse();
+ }
+
+ @Test
+ void givenEmptyString_whenIsEmptyMethodIsCalled_thenTrueIsReturned() {
+ boolean empty = CustomStringUtils.isEmpty("");
+ assertThat(empty).isTrue();
+ }
+
+}
diff --git a/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/StaticCounterUnitTest.java b/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/StaticCounterUnitTest.java
new file mode 100644
index 0000000000..f8605883ba
--- /dev/null
+++ b/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/StaticCounterUnitTest.java
@@ -0,0 +1,16 @@
+package com.baeldung.staticmethods;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class StaticCounterUnitTest {
+
+ @Test
+ void givenStaticCounter_whenIncrementCounterIsCalled_thenValueIsIncresedByOne() {
+ int oldValue = StaticCounter.getCounterValue();
+ int newValue = StaticCounter.incrementCounter();
+ assertThat(newValue).isEqualTo(oldValue + 1);
+ }
+
+}
diff --git a/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/StringUtilsUnitTest.java b/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/StringUtilsUnitTest.java
new file mode 100644
index 0000000000..d7a379a246
--- /dev/null
+++ b/core-java-modules/core-java-function/src/test/java/com/baeldung/staticmethods/StringUtilsUnitTest.java
@@ -0,0 +1,16 @@
+package com.baeldung.staticmethods;
+
+import org.apache.commons.lang3.StringUtils;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class StringUtilsUnitTest {
+
+ @Test
+ void givenSimpleString_whenCapitalizeStaticMethodIsCalled_thenCapitalizedStringIsReturned() {
+ String str = StringUtils.capitalize("baeldung");
+ assertThat(str).isEqualTo("Baeldung");
+ }
+
+}
diff --git a/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/parallel/FileSearchCost.java b/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/parallel/FileSearchCost.java
new file mode 100644
index 0000000000..a3d850dd66
--- /dev/null
+++ b/core-java-modules/core-java-streams-3/src/main/java/com/baeldung/streams/parallel/FileSearchCost.java
@@ -0,0 +1,60 @@
+package com.baeldung.streams.parallel;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import org.apache.commons.io.FileUtils;
+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.TearDown;
+
+@State(Scope.Benchmark)
+public class FileSearchCost {
+
+ private final static String FILE_NAME = "src/main/resources/Test";
+
+ @Setup(Level.Trial)
+ public void setup() throws IOException {
+ for (int i = 0; i < 1500; i++) {
+ File targetFile = new File(FILE_NAME + i);
+ FileUtils.writeStringToFile(targetFile, "Test", "UTF8");
+ }
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() {
+ for (int i = 0; i < 1500; i++) {
+ File fileToDelete = new File(FILE_NAME + i);
+ fileToDelete.delete();
+ }
+ }
+
+ @Benchmark
+ @BenchmarkMode(Mode.AverageTime)
+ @OutputTimeUnit(TimeUnit.NANOSECONDS)
+ public static void textFileSearchSequential() throws IOException {
+ Files.walk(Paths.get("src/main/resources/")).map(Path::normalize).filter(Files::isRegularFile)
+ .filter(path -> path.getFileName().toString().endsWith(".txt")).collect(Collectors.toList());
+ }
+
+ @Benchmark
+ @BenchmarkMode(Mode.AverageTime)
+ @OutputTimeUnit(TimeUnit.NANOSECONDS)
+ public static void textFileSearchParallel() throws IOException {
+ Files.walk(Paths.get("src/main/resources/")).parallel().map(Path::normalize).filter(Files::isRegularFile)
+ .filter(path -> path.getFileName().toString().endsWith(".txt")).collect(Collectors.toList());
+ }
+
+}
+
diff --git a/docker-modules/docker-environment-variables/Dockerfile b/docker-modules/docker-environment-variables/Dockerfile
new file mode 100644
index 0000000000..dcf69ec2cd
--- /dev/null
+++ b/docker-modules/docker-environment-variables/Dockerfile
@@ -0,0 +1,10 @@
+FROM alpine:latest
+
+ARG name
+ENV env_name $name
+
+COPY greetings.sh .
+
+RUN chmod +x /greetings.sh
+
+CMD ["/greetings.sh"]
\ No newline at end of file
diff --git a/docker-modules/docker-environment-variables/greetings.sh b/docker-modules/docker-environment-variables/greetings.sh
new file mode 100644
index 0000000000..6b9cd61105
--- /dev/null
+++ b/docker-modules/docker-environment-variables/greetings.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo Hello $env_name
\ No newline at end of file
diff --git a/kubernetes/k8s-admission-controller/README.md b/kubernetes/k8s-admission-controller/README.md
index 9c824d76b3..fd41c3b4e6 100644
--- a/kubernetes/k8s-admission-controller/README.md
+++ b/kubernetes/k8s-admission-controller/README.md
@@ -1,4 +1,4 @@
## Relevant Articles:
-- [Creating a Kubertes Admission Controller in Java](https://www.baeldung.com/java-kubernetes-admission-controller)
+- [Creating a Kubernetes Admission Controller in Java](https://www.baeldung.com/java-kubernetes-admission-controller)
- [Access Control Models](https://www.baeldung.com/java-access-control-models)
diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/event/UuidIdentifiedEntityEventListener.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/event/UuidIdentifiedEntityEventListener.java
new file mode 100644
index 0000000000..ce45d1e7bb
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/event/UuidIdentifiedEntityEventListener.java
@@ -0,0 +1,23 @@
+package com.baeldung.uuid.event;
+
+import java.util.UUID;
+
+import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
+import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
+
+import com.baeldung.uuid.model.UuidIdentifiedEntity;
+
+
+public class UuidIdentifiedEntityEventListener extends AbstractMongoEventListener {
+
+ @Override
+ public void onBeforeConvert(BeforeConvertEvent event) {
+
+ super.onBeforeConvert(event);
+ UuidIdentifiedEntity entity = event.getSource();
+
+ if(entity.getId() == null) {
+ entity.setId(UUID.randomUUID());
+ }
+ }
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/model/Book.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/model/Book.java
new file mode 100644
index 0000000000..f6aa1c615e
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/model/Book.java
@@ -0,0 +1,26 @@
+package com.baeldung.uuid.model;
+
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document
+public class Book extends UuidIdentifiedEntity {
+
+ private String title;
+ private String author;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/model/UuidIdentifiedEntity.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/model/UuidIdentifiedEntity.java
new file mode 100644
index 0000000000..aee0368b46
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/model/UuidIdentifiedEntity.java
@@ -0,0 +1,25 @@
+package com.baeldung.uuid.model;
+
+import java.util.UUID;
+
+import org.springframework.data.annotation.Id;
+
+public abstract class UuidIdentifiedEntity {
+
+ @Id
+ protected UUID id;
+
+ public UUID getId() {
+ return id;
+ }
+
+ public void setId(UUID id) {
+
+ if(this.id != null) {
+
+ throw new UnsupportedOperationException("ID is already defined");
+ }
+
+ this.id = id;
+ }
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/BookRepository.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/BookRepository.java
new file mode 100644
index 0000000000..0d6eb790aa
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/BookRepository.java
@@ -0,0 +1,11 @@
+package com.baeldung.uuid.repository;
+
+import java.util.UUID;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+
+import com.baeldung.uuid.model.Book;
+
+public interface BookRepository extends MongoRepository {
+
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/CustomMongoRepository.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/CustomMongoRepository.java
new file mode 100644
index 0000000000..599bc9ef61
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/CustomMongoRepository.java
@@ -0,0 +1,14 @@
+package com.baeldung.uuid.repository;
+
+import java.util.UUID;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.repository.NoRepositoryBean;
+
+import com.baeldung.uuid.model.UuidIdentifiedEntity;
+
+
+@NoRepositoryBean
+public interface CustomMongoRepository extends MongoRepository {
+
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/impl/CustomMongoRepositoryImpl.java b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/impl/CustomMongoRepositoryImpl.java
new file mode 100644
index 0000000000..9764d0b06e
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/main/java/com/baeldung/uuid/repository/impl/CustomMongoRepositoryImpl.java
@@ -0,0 +1,52 @@
+package com.baeldung.uuid.repository.impl;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
+import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
+
+import com.baeldung.uuid.model.UuidIdentifiedEntity;
+import com.baeldung.uuid.repository.CustomMongoRepository;
+
+
+public class CustomMongoRepositoryImpl extends SimpleMongoRepository implements CustomMongoRepository {
+
+ public CustomMongoRepositoryImpl(MongoEntityInformation metadata, MongoOperations mongoOperations) {
+
+ super(metadata, mongoOperations);
+ }
+
+ @Override
+ public S save(S entity) {
+ generateId(entity);
+ return super.save(entity);
+ }
+
+ @Override
+ public List saveAll(Iterable entities) {
+ entities.forEach(entity -> generateId(entity));
+ return super.saveAll(entities);
+ }
+
+ @Override
+ public S insert(S entity) {
+ generateId(entity);
+ return super.insert(entity);
+ }
+
+ @Override
+ public List insert(Iterable entities) {
+ entities.forEach(entity -> generateId(entity));
+ return super.insert(entities);
+ }
+
+ protected void generateId(S entity) {
+
+ if(entity != null && entity.getId() == null) {
+ entity.setId(UUID.randomUUID());
+ }
+ }
+
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/CustomRepositoryLiveTest.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/CustomRepositoryLiveTest.java
new file mode 100644
index 0000000000..0fc3fddfd7
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/CustomRepositoryLiveTest.java
@@ -0,0 +1,59 @@
+package com.baeldung.uuid;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.uuid.config.CustomRepositoryMongoConfig;
+import com.baeldung.uuid.model.Book;
+import com.baeldung.uuid.repository.BookRepository;
+
+/**
+ *
+ * This test requires:
+ * * mongodb instance running on the environment
+ *
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = CustomRepositoryMongoConfig.class)
+public class CustomRepositoryLiveTest {
+
+ @Autowired
+ private BookRepository bookRepository;
+
+ @Autowired
+ private MongoOperations mongoOps;
+
+ @Before
+ public void testSetup() {
+ if (!mongoOps.collectionExists(Book.class)) {
+ mongoOps.createCollection(Book.class);
+ }
+ }
+
+ @After
+ public void tearDown() {
+ mongoOps.dropCollection(Book.class);
+ }
+
+ @Test
+ public void whenInsertingBook_thenBookIsInserted() {
+ final Book book = new Book();
+ book.setTitle("The Lord of the Rings");
+ book.setAuthor("JRR Tolkien");
+ Book savedBook = bookRepository.save(book);
+
+ Book result = mongoOps.findOne(Query.query(Criteria.where("_id").is(savedBook.getId())), Book.class);
+
+ assertEquals(result.getTitle(), "The Lord of the Rings");
+ }
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/EntityCallbackLiveTest.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/EntityCallbackLiveTest.java
new file mode 100644
index 0000000000..737c2d8adb
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/EntityCallbackLiveTest.java
@@ -0,0 +1,64 @@
+package com.baeldung.uuid;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.uuid.config.EntityCallbackMongoConfig;
+import com.baeldung.uuid.model.Book;
+import com.baeldung.uuid.repository.BookRepository;
+
+/**
+ *
+ * This test requires:
+ * * mongodb instance running on the environment
+ *
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = EntityCallbackMongoConfig.class)
+public class EntityCallbackLiveTest {
+
+ @Autowired
+ private BookRepository bookRepository;
+
+ @Autowired
+ private MongoOperations mongoOps;
+
+ @Before
+ public void testSetup() {
+ if (!mongoOps.collectionExists(Book.class)) {
+ mongoOps.createCollection(Book.class);
+ }
+ }
+
+ @After
+ public void tearDown() {
+ mongoOps.dropCollection(Book.class);
+ }
+
+ @Test
+ public void whenSavingArticle_thenArticleIsInserted() {
+ final Book book = new Book();
+ book.setTitle("The Lord of the Rings");
+ book.setAuthor("JRR Tolkien");
+
+ Book savedArticle = bookRepository.save(book);
+
+ Book result = mongoOps.findOne(Query.query(Criteria.where("_id").is(savedArticle.getId())), Book.class);
+
+ assertNotNull(result);
+ assertEquals(result.getTitle(), "The Lord of the Rings");
+ }
+
+
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/EventLiveTest.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/EventLiveTest.java
new file mode 100644
index 0000000000..2c6bc72da6
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/EventLiveTest.java
@@ -0,0 +1,64 @@
+package com.baeldung.uuid;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.baeldung.uuid.config.EventMongoConfig;
+import com.baeldung.uuid.model.Book;
+import com.baeldung.uuid.repository.BookRepository;
+
+/**
+ *
+ * This test requires:
+ * * mongodb instance running on the environment
+ *
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = EventMongoConfig.class)
+public class EventLiveTest {
+
+ @Autowired
+ private BookRepository bookRepository;
+
+ @Autowired
+ private MongoOperations mongoOps;
+
+ @Before
+ public void testSetup() {
+ if (!mongoOps.collectionExists(Book.class)) {
+ mongoOps.createCollection(Book.class);
+ }
+ }
+
+ @After
+ public void tearDown() {
+ mongoOps.dropCollection(Book.class);
+ }
+
+ @Test
+ public void whenSavingArticle_thenArticleIsInserted() {
+ final Book book = new Book();
+ book.setTitle("The Lord of the Rings");
+ book.setAuthor("JRR Tolkien");
+
+ Book savedArticle = bookRepository.save(book);
+
+ Book result = mongoOps.findOne(Query.query(Criteria.where("_id").is(savedArticle.getId())), Book.class);
+
+ assertNotNull(result);
+ assertEquals(result.getTitle(), "The Lord of the Rings");
+ }
+
+
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/CustomRepositoryMongoConfig.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/CustomRepositoryMongoConfig.java
new file mode 100644
index 0000000000..833a407ae2
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/CustomRepositoryMongoConfig.java
@@ -0,0 +1,32 @@
+package com.baeldung.uuid.config;
+
+import org.bson.UuidRepresentation;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+import com.baeldung.uuid.repository.impl.CustomMongoRepositoryImpl;
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+@Configuration
+@EnableMongoRepositories(basePackages = "com.baeldung.uuid.repository", repositoryBaseClass = CustomMongoRepositoryImpl.class)
+public class CustomRepositoryMongoConfig {
+
+ @Bean
+ public MongoClient mongo() throws Exception {
+ final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
+ final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
+ .uuidRepresentation(UuidRepresentation.STANDARD)
+ .applyConnectionString(connectionString).build();
+ return MongoClients.create(mongoClientSettings);
+ }
+
+ @Bean
+ public MongoTemplate mongoTemplate() throws Exception {
+ return new MongoTemplate(mongo(), "test");
+ }
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/EntityCallbackMongoConfig.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/EntityCallbackMongoConfig.java
new file mode 100644
index 0000000000..baf69dd5e8
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/EntityCallbackMongoConfig.java
@@ -0,0 +1,48 @@
+package com.baeldung.uuid.config;
+
+import java.util.UUID;
+
+import org.bson.UuidRepresentation;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+import com.baeldung.uuid.model.UuidIdentifiedEntity;
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+@Configuration
+@EnableMongoRepositories(basePackages = "com.baeldung.uuid.repository")
+public class EntityCallbackMongoConfig {
+
+ @Bean
+ public MongoClient mongo() throws Exception {
+ final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
+ final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
+ .uuidRepresentation(UuidRepresentation.STANDARD)
+ .applyConnectionString(connectionString).build();
+ return MongoClients.create(mongoClientSettings);
+ }
+
+ @Bean
+ public MongoTemplate mongoTemplate() throws Exception {
+ return new MongoTemplate(mongo(), "test");
+ }
+
+ @Bean
+ public BeforeConvertCallback beforeSaveCallback() {
+
+ return (entity, collection) -> {
+
+ if(entity.getId() == null) {
+ entity.setId(UUID.randomUUID());
+ }
+ return entity;
+ };
+ }
+
+}
diff --git a/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/EventMongoConfig.java b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/EventMongoConfig.java
new file mode 100644
index 0000000000..d26281dd4a
--- /dev/null
+++ b/persistence-modules/spring-data-mongodb-2/src/test/java/com/baeldung/uuid/config/EventMongoConfig.java
@@ -0,0 +1,38 @@
+package com.baeldung.uuid.config;
+
+import org.bson.UuidRepresentation;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+import com.baeldung.uuid.event.UuidIdentifiedEntityEventListener;
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+@Configuration
+@EnableMongoRepositories(basePackages = "com.baeldung.uuid.repository")
+public class EventMongoConfig {
+
+ @Bean
+ public MongoClient mongo() throws Exception {
+ final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
+ final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
+ .uuidRepresentation(UuidRepresentation.STANDARD)
+ .applyConnectionString(connectionString).build();
+ return MongoClients.create(mongoClientSettings);
+ }
+
+ @Bean
+ public MongoTemplate mongoTemplate() throws Exception {
+ return new MongoTemplate(mongo(), "test");
+ }
+
+ @Bean
+ public UuidIdentifiedEntityEventListener uuidIdentifiedEntityEventListener() {
+
+ return new UuidIdentifiedEntityEventListener();
+ }
+}
diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml
index d0a35859b4..bf3f79e5e5 100644
--- a/spring-boot-modules/pom.xml
+++ b/spring-boot-modules/pom.xml
@@ -45,6 +45,7 @@
spring-boot-jasypt
spring-boot-keycloak
+ spring-boot-keycloak-2
spring-boot-libraries
spring-boot-libraries-2
spring-boot-libraries-comparison
@@ -99,4 +100,4 @@
-
\ No newline at end of file
+
diff --git a/spring-boot-modules/spring-boot-keycloak-2/README.md b/spring-boot-modules/spring-boot-keycloak-2/README.md
new file mode 100644
index 0000000000..d372132a6a
--- /dev/null
+++ b/spring-boot-modules/spring-boot-keycloak-2/README.md
@@ -0,0 +1,6 @@
+## Spring Boot Keycloak
+
+This module contains articles about Keycloak in Spring Boot projects.
+
+## Relevant articles:
+- [Disabling Keycloak Security in Spring Boot](https://www.baeldung.com/spring-keycloak-security-disable)
diff --git a/spring-boot-modules/spring-boot-keycloak-2/pom.xml b/spring-boot-modules/spring-boot-keycloak-2/pom.xml
new file mode 100644
index 0000000000..3f83c99613
--- /dev/null
+++ b/spring-boot-modules/spring-boot-keycloak-2/pom.xml
@@ -0,0 +1,65 @@
+
+
+ 4.0.0
+ com.baeldung.keycloak
+ spring-boot-keycloak-2
+ 0.0.1
+ spring-boot-keycloak-2
+ jar
+ This is a simple application demonstrating integration between Keycloak and Spring Boot.
+
+
+ com.baeldung
+ parent-boot-2
+ 0.0.1-SNAPSHOT
+ ../../parent-boot-2
+
+
+
+ 15.0.2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.keycloak
+ keycloak-spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.keycloak.bom
+ keycloak-adapter-bom
+ ${keycloak-adapter-bom.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/App.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/App.java
similarity index 100%
rename from spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/App.java
rename to spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/App.java
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/DisableSecurityConfiguration.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/DisableSecurityConfiguration.java
similarity index 100%
rename from spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/DisableSecurityConfiguration.java
rename to spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/DisableSecurityConfiguration.java
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/KeycloakConfiguration.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/KeycloakConfiguration.java
similarity index 100%
rename from spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/KeycloakConfiguration.java
rename to spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/KeycloakConfiguration.java
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/KeycloakSecurityConfig.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/KeycloakSecurityConfig.java
similarity index 100%
rename from spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/KeycloakSecurityConfig.java
rename to spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/KeycloakSecurityConfig.java
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/User.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/User.java
similarity index 100%
rename from spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/User.java
rename to spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/User.java
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/UserController.java b/spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/UserController.java
similarity index 100%
rename from spring-boot-modules/spring-boot-keycloak/src/main/java/com/baeldung/disablingkeycloak/UserController.java
rename to spring-boot-modules/spring-boot-keycloak-2/src/main/java/com/baeldung/disablingkeycloak/UserController.java
diff --git a/spring-boot-modules/spring-boot-keycloak/src/main/resources/application-disabling-keycloak.properties b/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/application-disabling-keycloak.properties
similarity index 100%
rename from spring-boot-modules/spring-boot-keycloak/src/main/resources/application-disabling-keycloak.properties
rename to spring-boot-modules/spring-boot-keycloak-2/src/main/resources/application-disabling-keycloak.properties
diff --git a/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/logback.xml b/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/spring-boot-modules/spring-boot-keycloak-2/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/disablingkeycloak/DisablingKeycloakIntegrationTest.java b/spring-boot-modules/spring-boot-keycloak-2/src/test/java/com/baeldung/disablingkeycloak/DisablingKeycloakIntegrationTest.java
similarity index 69%
rename from spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/disablingkeycloak/DisablingKeycloakIntegrationTest.java
rename to spring-boot-modules/spring-boot-keycloak-2/src/test/java/com/baeldung/disablingkeycloak/DisablingKeycloakIntegrationTest.java
index cf70f7e7c3..2f9979baf7 100644
--- a/spring-boot-modules/spring-boot-keycloak/src/test/java/com/baeldung/disablingkeycloak/DisablingKeycloakIntegrationTest.java
+++ b/spring-boot-modules/spring-boot-keycloak-2/src/test/java/com/baeldung/disablingkeycloak/DisablingKeycloakIntegrationTest.java
@@ -1,28 +1,25 @@
package com.baeldung.disablingkeycloak;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.apache.http.HttpStatus;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = App.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-@RunWith(SpringRunner.class)
@ActiveProfiles("disablingkeycloak")
-public class DisablingKeycloakIntegrationTest {
+class DisablingKeycloakIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
- public void givenUnauthenticated_whenGettingUser_shouldReturnUser() {
+ void givenUnauthenticated_whenGettingUser_shouldReturnUser() {
ResponseEntity responseEntity = restTemplate.getForEntity("/users/1", User.class);
assertEquals(HttpStatus.SC_OK, responseEntity.getStatusCodeValue());
diff --git a/spring-boot-modules/spring-boot-keycloak/src/test/resources/application-disablingkeycloak.properties b/spring-boot-modules/spring-boot-keycloak-2/src/test/resources/application-disablingkeycloak.properties
similarity index 100%
rename from spring-boot-modules/spring-boot-keycloak/src/test/resources/application-disablingkeycloak.properties
rename to spring-boot-modules/spring-boot-keycloak-2/src/test/resources/application-disablingkeycloak.properties
diff --git a/spring-boot-modules/spring-boot-keycloak/README.md b/spring-boot-modules/spring-boot-keycloak/README.md
index 97a336c25c..cde11df0fa 100644
--- a/spring-boot-modules/spring-boot-keycloak/README.md
+++ b/spring-boot-modules/spring-boot-keycloak/README.md
@@ -10,4 +10,3 @@ This module contains articles about Keycloak in Spring Boot projects.
- [Customizing Themes for Keycloak](https://www.baeldung.com/spring-keycloak-custom-themes)
- [Securing SOAP Web Services With Keycloak](https://www.baeldung.com/soap-keycloak)
- [Get Keycloak User ID in Spring](https://www.baeldung.com/spring-keycloak-get-user-id)
-- [Disabling Keycloak Security in Spring Boot](https://www.baeldung.com/spring-keycloak-security-disable)