diff --git a/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java
index 60171220cd..202912a1af 100644
--- a/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java
+++ b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java
@@ -14,7 +14,7 @@ public class KadaneAlgorithm {
int end = 0;
int maxSoFar = arr[0], maxEndingHere = arr[0];
- for (int i = 0; i < size; i++) {
+ for (int i = 1; i < size; i++) {
if (arr[i] > maxEndingHere + arr[i]) {
start = i;
diff --git a/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java
index 71531dcf59..8dcc81bc5b 100644
--- a/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java
+++ b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java
@@ -27,4 +27,16 @@ class KadaneAlgorithmUnitTest {
//then
assertEquals(-1, maxSum);
}
+
+ @Test
+ void givenArrayWithAllPosiitveNumbersWhenMaximumSubarrayThenReturnsExpectedResult() {
+ //given
+ int[] arr = new int[] {4, 1, 3, 2};
+ //when
+ KadaneAlgorithm algorithm = new KadaneAlgorithm();
+ int maxSum = algorithm.maxSubArraySum(arr);
+ //then
+ assertEquals(10, maxSum);
+ }
+
}
\ No newline at end of file
diff --git a/apache-cxf/README.md b/apache-cxf-modules/README.md
similarity index 100%
rename from apache-cxf/README.md
rename to apache-cxf-modules/README.md
diff --git a/apache-cxf/cxf-aegis/README.md b/apache-cxf-modules/cxf-aegis/README.md
similarity index 100%
rename from apache-cxf/cxf-aegis/README.md
rename to apache-cxf-modules/cxf-aegis/README.md
diff --git a/apache-cxf/cxf-aegis/pom.xml b/apache-cxf-modules/cxf-aegis/pom.xml
similarity index 91%
rename from apache-cxf/cxf-aegis/pom.xml
rename to apache-cxf-modules/cxf-aegis/pom.xml
index 996c6fc0cd..d013aabc65 100644
--- a/apache-cxf/cxf-aegis/pom.xml
+++ b/apache-cxf-modules/cxf-aegis/pom.xml
@@ -8,7 +8,7 @@
com.baeldung
- apache-cxf
+ apache-cxf-modules
0.0.1-SNAPSHOT
diff --git a/apache-cxf/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/Course.java b/apache-cxf-modules/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/Course.java
similarity index 100%
rename from apache-cxf/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/Course.java
rename to apache-cxf-modules/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/Course.java
diff --git a/apache-cxf/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/CourseRepo.java b/apache-cxf-modules/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/CourseRepo.java
similarity index 100%
rename from apache-cxf/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/CourseRepo.java
rename to apache-cxf-modules/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/CourseRepo.java
diff --git a/apache-cxf/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/CourseRepoImpl.java b/apache-cxf-modules/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/CourseRepoImpl.java
similarity index 100%
rename from apache-cxf/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/CourseRepoImpl.java
rename to apache-cxf-modules/cxf-aegis/src/main/java/com/baeldung/cxf/aegis/CourseRepoImpl.java
diff --git a/apache-cxf/cxf-aegis/src/main/resources/com/baeldung/cxf/aegis/Course.aegis.xml b/apache-cxf-modules/cxf-aegis/src/main/resources/com/baeldung/cxf/aegis/Course.aegis.xml
similarity index 100%
rename from apache-cxf/cxf-aegis/src/main/resources/com/baeldung/cxf/aegis/Course.aegis.xml
rename to apache-cxf-modules/cxf-aegis/src/main/resources/com/baeldung/cxf/aegis/Course.aegis.xml
diff --git a/apache-cxf/cxf-aegis/src/main/resources/com/baeldung/cxf/aegis/CourseRepo.aegis.xml b/apache-cxf-modules/cxf-aegis/src/main/resources/com/baeldung/cxf/aegis/CourseRepo.aegis.xml
similarity index 100%
rename from apache-cxf/cxf-aegis/src/main/resources/com/baeldung/cxf/aegis/CourseRepo.aegis.xml
rename to apache-cxf-modules/cxf-aegis/src/main/resources/com/baeldung/cxf/aegis/CourseRepo.aegis.xml
diff --git a/apache-cxf/cxf-aegis/src/main/resources/logback.xml b/apache-cxf-modules/cxf-aegis/src/main/resources/logback.xml
similarity index 100%
rename from apache-cxf/cxf-aegis/src/main/resources/logback.xml
rename to apache-cxf-modules/cxf-aegis/src/main/resources/logback.xml
diff --git a/apache-cxf/cxf-aegis/src/test/java/com/baeldung/cxf/aegis/BaeldungIntegrationTest.java b/apache-cxf-modules/cxf-aegis/src/test/java/com/baeldung/cxf/aegis/BaeldungIntegrationTest.java
similarity index 100%
rename from apache-cxf/cxf-aegis/src/test/java/com/baeldung/cxf/aegis/BaeldungIntegrationTest.java
rename to apache-cxf-modules/cxf-aegis/src/test/java/com/baeldung/cxf/aegis/BaeldungIntegrationTest.java
diff --git a/apache-cxf/cxf-introduction/README.md b/apache-cxf-modules/cxf-introduction/README.md
similarity index 100%
rename from apache-cxf/cxf-introduction/README.md
rename to apache-cxf-modules/cxf-introduction/README.md
diff --git a/apache-cxf/cxf-introduction/pom.xml b/apache-cxf-modules/cxf-introduction/pom.xml
similarity index 95%
rename from apache-cxf/cxf-introduction/pom.xml
rename to apache-cxf-modules/cxf-introduction/pom.xml
index 12529e55c1..fe7b917c6f 100644
--- a/apache-cxf/cxf-introduction/pom.xml
+++ b/apache-cxf-modules/cxf-introduction/pom.xml
@@ -8,7 +8,7 @@
com.baeldung
- apache-cxf
+ apache-cxf-modules
0.0.1-SNAPSHOT
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Baeldung.java b/apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Baeldung.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Baeldung.java
rename to apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Baeldung.java
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/BaeldungImpl.java b/apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/BaeldungImpl.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/BaeldungImpl.java
rename to apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/BaeldungImpl.java
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Server.java b/apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Server.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Server.java
rename to apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Server.java
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Student.java b/apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Student.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Student.java
rename to apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Student.java
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentAdapter.java b/apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentAdapter.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentAdapter.java
rename to apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentAdapter.java
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentImpl.java b/apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentImpl.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentImpl.java
rename to apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentImpl.java
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentMap.java b/apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentMap.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentMap.java
rename to apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentMap.java
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentMapAdapter.java b/apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentMapAdapter.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentMapAdapter.java
rename to apache-cxf-modules/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/StudentMapAdapter.java
diff --git a/apache-cxf/cxf-introduction/src/main/resources/logback.xml b/apache-cxf-modules/cxf-introduction/src/main/resources/logback.xml
similarity index 100%
rename from apache-cxf/cxf-introduction/src/main/resources/logback.xml
rename to apache-cxf-modules/cxf-introduction/src/main/resources/logback.xml
diff --git a/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentLiveTest.java b/apache-cxf-modules/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentLiveTest.java
similarity index 100%
rename from apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentLiveTest.java
rename to apache-cxf-modules/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentLiveTest.java
diff --git a/apache-cxf/cxf-jaxrs-implementation/README.md b/apache-cxf-modules/cxf-jaxrs-implementation/README.md
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/README.md
rename to apache-cxf-modules/cxf-jaxrs-implementation/README.md
diff --git a/apache-cxf/cxf-jaxrs-implementation/pom.xml b/apache-cxf-modules/cxf-jaxrs-implementation/pom.xml
similarity index 96%
rename from apache-cxf/cxf-jaxrs-implementation/pom.xml
rename to apache-cxf-modules/cxf-jaxrs-implementation/pom.xml
index 515f527a5b..cc5eba4025 100644
--- a/apache-cxf/cxf-jaxrs-implementation/pom.xml
+++ b/apache-cxf-modules/cxf-jaxrs-implementation/pom.xml
@@ -8,7 +8,7 @@
com.baeldung
- apache-cxf
+ apache-cxf-modules
0.0.1-SNAPSHOT
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/CourseRepository.java b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/CourseRepository.java
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/CourseRepository.java
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/CourseRepository.java
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/changed_course.xml b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/changed_course.xml
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/resources/changed_course.xml
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/changed_course.xml
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/conflict_student.xml b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/conflict_student.xml
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/resources/conflict_student.xml
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/conflict_student.xml
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/created_student.xml b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/created_student.xml
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/resources/created_student.xml
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/created_student.xml
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/logback.xml b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/logback.xml
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/resources/logback.xml
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/logback.xml
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/non_existent_course.xml b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/non_existent_course.xml
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/resources/non_existent_course.xml
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/non_existent_course.xml
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/unchanged_course.xml b/apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/unchanged_course.xml
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/main/resources/unchanged_course.xml
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/main/resources/unchanged_course.xml
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceLiveTest.java b/apache-cxf-modules/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceLiveTest.java
similarity index 100%
rename from apache-cxf/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceLiveTest.java
rename to apache-cxf-modules/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceLiveTest.java
diff --git a/apache-cxf/cxf-spring/.gitignore b/apache-cxf-modules/cxf-spring/.gitignore
similarity index 100%
rename from apache-cxf/cxf-spring/.gitignore
rename to apache-cxf-modules/cxf-spring/.gitignore
diff --git a/apache-cxf/cxf-spring/README.md b/apache-cxf-modules/cxf-spring/README.md
similarity index 100%
rename from apache-cxf/cxf-spring/README.md
rename to apache-cxf-modules/cxf-spring/README.md
diff --git a/apache-cxf/cxf-spring/pom.xml b/apache-cxf-modules/cxf-spring/pom.xml
similarity index 98%
rename from apache-cxf/cxf-spring/pom.xml
rename to apache-cxf-modules/cxf-spring/pom.xml
index 772ece81da..ebbebd7f3b 100644
--- a/apache-cxf/cxf-spring/pom.xml
+++ b/apache-cxf-modules/cxf-spring/pom.xml
@@ -9,7 +9,7 @@
com.baeldung
- apache-cxf
+ apache-cxf-modules
0.0.1-SNAPSHOT
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/AppInitializer.java b/apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/AppInitializer.java
similarity index 100%
rename from apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/AppInitializer.java
rename to apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/AppInitializer.java
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Baeldung.java b/apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/Baeldung.java
similarity index 100%
rename from apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Baeldung.java
rename to apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/Baeldung.java
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/BaeldungImpl.java b/apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/BaeldungImpl.java
similarity index 100%
rename from apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/BaeldungImpl.java
rename to apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/BaeldungImpl.java
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/ClientConfiguration.java b/apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/ClientConfiguration.java
similarity index 100%
rename from apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/ClientConfiguration.java
rename to apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/ClientConfiguration.java
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/ServiceConfiguration.java b/apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/ServiceConfiguration.java
similarity index 100%
rename from apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/ServiceConfiguration.java
rename to apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/ServiceConfiguration.java
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Student.java b/apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/Student.java
similarity index 100%
rename from apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Student.java
rename to apache-cxf-modules/cxf-spring/src/main/java/com/baeldung/cxf/spring/Student.java
diff --git a/apache-cxf/cxf-spring/src/main/resources/logback.xml b/apache-cxf-modules/cxf-spring/src/main/resources/logback.xml
similarity index 100%
rename from apache-cxf/cxf-spring/src/main/resources/logback.xml
rename to apache-cxf-modules/cxf-spring/src/main/resources/logback.xml
diff --git a/apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentLiveTest.java b/apache-cxf-modules/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentLiveTest.java
similarity index 100%
rename from apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentLiveTest.java
rename to apache-cxf-modules/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentLiveTest.java
diff --git a/apache-cxf/pom.xml b/apache-cxf-modules/pom.xml
similarity index 95%
rename from apache-cxf/pom.xml
rename to apache-cxf-modules/pom.xml
index 6b7e396b9e..fc1cf4fa0f 100644
--- a/apache-cxf/pom.xml
+++ b/apache-cxf-modules/pom.xml
@@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- apache-cxf
+ apache-cxf-modules
0.0.1-SNAPSHOT
apache-cxf
pom
diff --git a/apache-cxf/sse-jaxrs/README.md b/apache-cxf-modules/sse-jaxrs/README.md
similarity index 100%
rename from apache-cxf/sse-jaxrs/README.md
rename to apache-cxf-modules/sse-jaxrs/README.md
diff --git a/apache-cxf/sse-jaxrs/pom.xml b/apache-cxf-modules/sse-jaxrs/pom.xml
similarity index 90%
rename from apache-cxf/sse-jaxrs/pom.xml
rename to apache-cxf-modules/sse-jaxrs/pom.xml
index 1ac2948439..baa32a516a 100644
--- a/apache-cxf/sse-jaxrs/pom.xml
+++ b/apache-cxf-modules/sse-jaxrs/pom.xml
@@ -9,7 +9,7 @@
com.baeldung
- apache-cxf
+ apache-cxf-modules
0.0.1-SNAPSHOT
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-client/pom.xml b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/pom.xml
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-client/pom.xml
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/pom.xml
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientApp.java
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/src/main/java/com/baeldung/sse/jaxrs/client/SseClientBroadcastApp.java
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-client/src/main/resources/logback.xml
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/pom.xml b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/pom.xml
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/pom.xml
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/pom.xml
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/AppConfig.java
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/SseResource.java
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/Stock.java
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/java/com/baeldung/sse/jaxrs/StockService.java
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/liberty/config/server.xml
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/resources/META-INF/beans.xml
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/resources/logback.xml
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/webapp/WEB-INF/web.xml
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/webapp/index.html
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse-broadcast.html
diff --git a/apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html b/apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html
similarity index 100%
rename from apache-cxf/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html
rename to apache-cxf-modules/sse-jaxrs/sse-jaxrs-server/src/main/webapp/sse.html
diff --git a/core-groovy-2/README.md b/core-groovy-modules/core-groovy-2/README.md
similarity index 100%
rename from core-groovy-2/README.md
rename to core-groovy-modules/core-groovy-2/README.md
diff --git a/core-groovy-2/gmavenplus-pom.xml b/core-groovy-modules/core-groovy-2/gmavenplus-pom.xml
similarity index 99%
rename from core-groovy-2/gmavenplus-pom.xml
rename to core-groovy-modules/core-groovy-2/gmavenplus-pom.xml
index 4dbdfe7d42..43f089ac93 100644
--- a/core-groovy-2/gmavenplus-pom.xml
+++ b/core-groovy-modules/core-groovy-2/gmavenplus-pom.xml
@@ -9,7 +9,7 @@
com.baeldung
- parent-modules
+ core-groovy-modules
1.0.0-SNAPSHOT
diff --git a/core-groovy-2/pom.xml b/core-groovy-modules/core-groovy-2/pom.xml
similarity index 99%
rename from core-groovy-2/pom.xml
rename to core-groovy-modules/core-groovy-2/pom.xml
index 6b78e21080..cf4951b838 100644
--- a/core-groovy-2/pom.xml
+++ b/core-groovy-modules/core-groovy-2/pom.xml
@@ -10,7 +10,7 @@
com.baeldung
- parent-modules
+ core-groovy-modules
1.0.0-SNAPSHOT
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/CalcMath.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/CalcMath.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/CalcMath.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/CalcMath.groovy
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/category/BaeldungCategory.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/category/BaeldungCategory.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/category/BaeldungCategory.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/category/BaeldungCategory.groovy
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/category/NumberCategory.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/category/NumberCategory.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/category/NumberCategory.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/category/NumberCategory.groovy
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/concatenate/Wonder.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/concatenate/Wonder.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/concatenate/Wonder.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/concatenate/Wonder.groovy
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/determinedatatype/Person.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/determinedatatype/Person.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/determinedatatype/Person.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/determinedatatype/Person.groovy
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/Employee.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/Employee.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/Employee.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/Employee.groovy
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/BasicExtensions.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/BasicExtensions.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/BasicExtensions.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/BasicExtensions.groovy
diff --git a/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/StaticEmployeeExtension.groovy b/core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/StaticEmployeeExtension.groovy
similarity index 100%
rename from core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/StaticEmployeeExtension.groovy
rename to core-groovy-modules/core-groovy-2/src/main/groovy/com/baeldung/metaprogramming/extension/StaticEmployeeExtension.groovy
diff --git a/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java b/core-groovy-modules/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java
similarity index 100%
rename from core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java
rename to core-groovy-modules/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java
diff --git a/core-groovy-2/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule b/core-groovy-modules/core-groovy-2/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
similarity index 100%
rename from core-groovy-2/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
rename to core-groovy-modules/core-groovy-2/src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
diff --git a/core-groovy-2/src/main/resources/articleEmail.template b/core-groovy-modules/core-groovy-2/src/main/resources/articleEmail.template
similarity index 100%
rename from core-groovy-2/src/main/resources/articleEmail.template
rename to core-groovy-modules/core-groovy-2/src/main/resources/articleEmail.template
diff --git a/core-groovy-2/src/main/resources/email.template b/core-groovy-modules/core-groovy-2/src/main/resources/email.template
similarity index 100%
rename from core-groovy-2/src/main/resources/email.template
rename to core-groovy-modules/core-groovy-2/src/main/resources/email.template
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/category/CategoryUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/category/CategoryUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/category/CategoryUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/category/CategoryUnitTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/concatenate/WonderUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/concatenate/WonderUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/concatenate/WonderUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/concatenate/WonderUnitTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/defkeyword/DefUnitTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/determinedatatype/PersonTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/determinedatatype/PersonTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/determinedatatype/PersonTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/determinedatatype/PersonTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/metaprogramming/MetaprogrammingUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/metaprogramming/MetaprogrammingUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/metaprogramming/MetaprogrammingUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/metaprogramming/MetaprogrammingUnitTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/templateengine/TemplateEnginesUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/templateengine/TemplateEnginesUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/templateengine/TemplateEnginesUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/templateengine/TemplateEnginesUnitTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/webservice/WebserviceUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/webservice/WebserviceUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/webservice/WebserviceUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/webservice/WebserviceUnitTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy
diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy b/core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy
similarity index 100%
rename from core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy
rename to core-groovy-modules/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy
diff --git a/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml b/core-groovy-modules/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml
similarity index 100%
rename from core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml
rename to core-groovy-modules/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml
diff --git a/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml b/core-groovy-modules/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml
similarity index 100%
rename from core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml
rename to core-groovy-modules/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml
diff --git a/core-groovy-collections/README.md b/core-groovy-modules/core-groovy-collections/README.md
similarity index 100%
rename from core-groovy-collections/README.md
rename to core-groovy-modules/core-groovy-collections/README.md
diff --git a/core-groovy-collections/pom.xml b/core-groovy-modules/core-groovy-collections/pom.xml
similarity index 98%
rename from core-groovy-collections/pom.xml
rename to core-groovy-modules/core-groovy-collections/pom.xml
index d589fc74e5..74cde808f5 100644
--- a/core-groovy-collections/pom.xml
+++ b/core-groovy-modules/core-groovy-collections/pom.xml
@@ -10,7 +10,7 @@
com.baeldung
- parent-modules
+ core-groovy-modules
1.0.0-SNAPSHOT
diff --git a/core-groovy-collections/src/test/groovy/com/baeldung/find/ListFindUnitTest.groovy b/core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/find/ListFindUnitTest.groovy
similarity index 100%
rename from core-groovy-collections/src/test/groovy/com/baeldung/find/ListFindUnitTest.groovy
rename to core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/find/ListFindUnitTest.groovy
diff --git a/core-groovy-collections/src/test/groovy/com/baeldung/find/MapFindUnitTest.groovy b/core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/find/MapFindUnitTest.groovy
similarity index 100%
rename from core-groovy-collections/src/test/groovy/com/baeldung/find/MapFindUnitTest.groovy
rename to core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/find/MapFindUnitTest.groovy
diff --git a/core-groovy-collections/src/test/groovy/com/baeldung/find/Person.groovy b/core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/find/Person.groovy
similarity index 100%
rename from core-groovy-collections/src/test/groovy/com/baeldung/find/Person.groovy
rename to core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/find/Person.groovy
diff --git a/core-groovy-collections/src/test/groovy/com/baeldung/find/SetFindUnitTest.groovy b/core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/find/SetFindUnitTest.groovy
similarity index 100%
rename from core-groovy-collections/src/test/groovy/com/baeldung/find/SetFindUnitTest.groovy
rename to core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/find/SetFindUnitTest.groovy
diff --git a/core-groovy-collections/src/test/groovy/com/baeldung/iteratemap/IterateMapUnitTest.groovy b/core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/iteratemap/IterateMapUnitTest.groovy
similarity index 100%
rename from core-groovy-collections/src/test/groovy/com/baeldung/iteratemap/IterateMapUnitTest.groovy
rename to core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/iteratemap/IterateMapUnitTest.groovy
diff --git a/core-groovy-collections/src/test/groovy/com/baeldung/lists/ListUnitTest.groovy b/core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/lists/ListUnitTest.groovy
similarity index 100%
rename from core-groovy-collections/src/test/groovy/com/baeldung/lists/ListUnitTest.groovy
rename to core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/lists/ListUnitTest.groovy
diff --git a/core-groovy-collections/src/test/groovy/com/baeldung/maps/MapTest.groovy b/core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/maps/MapTest.groovy
similarity index 100%
rename from core-groovy-collections/src/test/groovy/com/baeldung/maps/MapTest.groovy
rename to core-groovy-modules/core-groovy-collections/src/test/groovy/com/baeldung/maps/MapTest.groovy
diff --git a/core-groovy-strings/README.md b/core-groovy-modules/core-groovy-strings/README.md
similarity index 100%
rename from core-groovy-strings/README.md
rename to core-groovy-modules/core-groovy-strings/README.md
diff --git a/core-groovy-strings/pom.xml b/core-groovy-modules/core-groovy-strings/pom.xml
similarity index 98%
rename from core-groovy-strings/pom.xml
rename to core-groovy-modules/core-groovy-strings/pom.xml
index 333b15cdbe..f6ad4d33cf 100644
--- a/core-groovy-strings/pom.xml
+++ b/core-groovy-modules/core-groovy-strings/pom.xml
@@ -10,7 +10,7 @@
com.baeldung
- parent-modules
+ core-groovy-modules
1.0.0-SNAPSHOT
diff --git a/core-groovy-strings/src/test/groovy/com/baeldung/removeprefix/RemovePrefixTest.groovy b/core-groovy-modules/core-groovy-strings/src/test/groovy/com/baeldung/removeprefix/RemovePrefixTest.groovy
similarity index 100%
rename from core-groovy-strings/src/test/groovy/com/baeldung/removeprefix/RemovePrefixTest.groovy
rename to core-groovy-modules/core-groovy-strings/src/test/groovy/com/baeldung/removeprefix/RemovePrefixTest.groovy
diff --git a/core-groovy/.gitignore b/core-groovy-modules/core-groovy/.gitignore
similarity index 100%
rename from core-groovy/.gitignore
rename to core-groovy-modules/core-groovy/.gitignore
diff --git a/core-groovy/README.md b/core-groovy-modules/core-groovy/README.md
similarity index 100%
rename from core-groovy/README.md
rename to core-groovy-modules/core-groovy/README.md
diff --git a/core-groovy/build.gradle b/core-groovy-modules/core-groovy/build.gradle
similarity index 100%
rename from core-groovy/build.gradle
rename to core-groovy-modules/core-groovy/build.gradle
diff --git a/core-groovy/pom.xml b/core-groovy-modules/core-groovy/pom.xml
similarity index 98%
rename from core-groovy/pom.xml
rename to core-groovy-modules/core-groovy/pom.xml
index c24982c6a2..0365a0d565 100644
--- a/core-groovy/pom.xml
+++ b/core-groovy-modules/core-groovy/pom.xml
@@ -10,7 +10,7 @@
com.baeldung
- parent-modules
+ core-groovy-modules
1.0.0-SNAPSHOT
diff --git a/core-groovy/src/main/groovy/com/baeldung/closures/Closures.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/closures/Closures.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/closures/Closures.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/closures/Closures.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/closures/Employee.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/closures/Employee.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/closures/Employee.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/closures/Employee.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/file/ReadFile.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/file/ReadFile.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/file/ReadFile.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/file/ReadFile.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/io/Task.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/io/Task.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/io/Task.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/io/Task.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/json/Account.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/scopes/Scopes.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/scopes/Scopes.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/scopes/Scopes.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/scopes/Scopes.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFail.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFail.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFail.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFail.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFailNoPrint.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFailNoPrint.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFailNoPrint.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFailNoPrint.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/strings/Concatenate.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/strings/Concatenate.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/strings/Concatenate.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/strings/Concatenate.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/AnimalTrait.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/AnimalTrait.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/AnimalTrait.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/AnimalTrait.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/Car.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/Car.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/Car.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/Car.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/Dog.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/Dog.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/Dog.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/Dog.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/Employee.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/Employee.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/Employee.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/Employee.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/Human.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/Human.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/Human.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/Human.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/SpeakingTrait.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/SpeakingTrait.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/SpeakingTrait.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/SpeakingTrait.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/UserTrait.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/VehicleTrait.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/VehicleTrait.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/VehicleTrait.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/VehicleTrait.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/WalkingTrait.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/WalkingTrait.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/WalkingTrait.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/WalkingTrait.groovy
diff --git a/core-groovy/src/main/groovy/com/baeldung/traits/WheelTrait.groovy b/core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/WheelTrait.groovy
similarity index 100%
rename from core-groovy/src/main/groovy/com/baeldung/traits/WheelTrait.groovy
rename to core-groovy-modules/core-groovy/src/main/groovy/com/baeldung/traits/WheelTrait.groovy
diff --git a/core-groovy/src/main/resources/binaryExample.jpg b/core-groovy-modules/core-groovy/src/main/resources/binaryExample.jpg
similarity index 100%
rename from core-groovy/src/main/resources/binaryExample.jpg
rename to core-groovy-modules/core-groovy/src/main/resources/binaryExample.jpg
diff --git a/core-groovy/src/main/resources/fileContent.txt b/core-groovy-modules/core-groovy/src/main/resources/fileContent.txt
similarity index 100%
rename from core-groovy/src/main/resources/fileContent.txt
rename to core-groovy-modules/core-groovy/src/main/resources/fileContent.txt
diff --git a/core-groovy/src/main/resources/ioData.txt b/core-groovy-modules/core-groovy/src/main/resources/ioData.txt
similarity index 100%
rename from core-groovy/src/main/resources/ioData.txt
rename to core-groovy-modules/core-groovy/src/main/resources/ioData.txt
diff --git a/core-groovy/src/main/resources/ioInput.txt b/core-groovy-modules/core-groovy/src/main/resources/ioInput.txt
similarity index 100%
rename from core-groovy/src/main/resources/ioInput.txt
rename to core-groovy-modules/core-groovy/src/main/resources/ioInput.txt
diff --git a/core-groovy/src/main/resources/ioOutput.txt b/core-groovy-modules/core-groovy/src/main/resources/ioOutput.txt
similarity index 100%
rename from core-groovy/src/main/resources/ioOutput.txt
rename to core-groovy-modules/core-groovy/src/main/resources/ioOutput.txt
diff --git a/core-groovy/src/main/resources/logback.xml b/core-groovy-modules/core-groovy/src/main/resources/logback.xml
similarity index 100%
rename from core-groovy/src/main/resources/logback.xml
rename to core-groovy-modules/core-groovy/src/main/resources/logback.xml
diff --git a/core-groovy/src/main/resources/sample.png b/core-groovy-modules/core-groovy/src/main/resources/sample.png
similarity index 100%
rename from core-groovy/src/main/resources/sample.png
rename to core-groovy-modules/core-groovy/src/main/resources/sample.png
diff --git a/core-groovy/src/main/resources/utf8Content.html b/core-groovy-modules/core-groovy/src/main/resources/utf8Content.html
similarity index 100%
rename from core-groovy/src/main/resources/utf8Content.html
rename to core-groovy-modules/core-groovy/src/main/resources/utf8Content.html
diff --git a/core-groovy/src/test/groovy/com/baeldung/closures/ClosuresUnitTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/closures/ClosuresUnitTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/closures/ClosuresUnitTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/closures/ClosuresUnitTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/date/DateTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/date/DateTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/date/DateTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/date/DateTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/file/ReadFileUnitTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/file/ReadFileUnitTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/file/ReadFileUnitTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/file/ReadFileUnitTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/groovy/sql/SqlTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/io/DataAndObjectsUnitTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/io/DataAndObjectsUnitTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/io/DataAndObjectsUnitTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/io/DataAndObjectsUnitTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/io/ReadExampleUnitTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/io/ReadExampleUnitTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/io/ReadExampleUnitTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/io/ReadExampleUnitTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/io/TraverseFileTreeUnitTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/io/TraverseFileTreeUnitTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/io/TraverseFileTreeUnitTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/io/TraverseFileTreeUnitTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/io/WriteExampleUnitTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/io/WriteExampleUnitTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/io/WriteExampleUnitTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/io/WriteExampleUnitTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/strings/ConcatenateTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/strings/ConcatenateTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/strings/ConcatenateTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/strings/ConcatenateTest.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/strings/StringMatchingSpec.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtoint/ConvertStringToInt.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtoint/ConvertStringToInt.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtoint/ConvertStringToInt.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtoint/ConvertStringToInt.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtypes/CharacterInGroovy.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/CharacterInGroovy.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtypes/CharacterInGroovy.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/CharacterInGroovy.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtypes/DollarSlashyString.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/DollarSlashyString.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtypes/DollarSlashyString.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/DollarSlashyString.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtypes/DoubleQuotedString.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/DoubleQuotedString.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtypes/DoubleQuotedString.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/DoubleQuotedString.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtypes/SingleQuotedString.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/SingleQuotedString.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtypes/SingleQuotedString.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/SingleQuotedString.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtypes/SlashyString.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/SlashyString.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtypes/SlashyString.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/SlashyString.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtypes/Strings.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/Strings.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtypes/Strings.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/Strings.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtypes/TripleDoubleQuotedString.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/TripleDoubleQuotedString.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtypes/TripleDoubleQuotedString.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/TripleDoubleQuotedString.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/stringtypes/TripleSingleQuotedString.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/TripleSingleQuotedString.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/stringtypes/TripleSingleQuotedString.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/stringtypes/TripleSingleQuotedString.groovy
diff --git a/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy b/core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy
similarity index 100%
rename from core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy
rename to core-groovy-modules/core-groovy/src/test/groovy/com/baeldung/traits/TraitsUnitTest.groovy
diff --git a/core-groovy-modules/pom.xml b/core-groovy-modules/pom.xml
new file mode 100644
index 0000000000..2fd4da17f9
--- /dev/null
+++ b/core-groovy-modules/pom.xml
@@ -0,0 +1,25 @@
+
+
+ 4.0.0
+ core-groovy-modules
+ core-groovy-modules
+ pom
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ core-groovy
+ core-groovy-2
+ core-groovy-collections
+ core-groovy-strings
+
+
+
+
+
diff --git a/data-structures/src/test/java/com/baeldung/circularbuffer/ProducerConsumerLiveTest.java b/data-structures/src/test/java/com/baeldung/circularbuffer/ProducerConsumerLiveTest.java
index 83ce27043b..ee1f5d91e2 100644
--- a/data-structures/src/test/java/com/baeldung/circularbuffer/ProducerConsumerLiveTest.java
+++ b/data-structures/src/test/java/com/baeldung/circularbuffer/ProducerConsumerLiveTest.java
@@ -2,6 +2,7 @@ package com.baeldung.circularbuffer;
import static org.junit.Assert.assertArrayEquals;
+import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -24,8 +25,9 @@ public class ProducerConsumerLiveTest {
executorService.submit(new Producer(buffer, shapes));
Future consumed = executorService.submit(new Consumer(buffer, shapes.length));
- String[] shapesConsumed = consumed.get(5L, TimeUnit.SECONDS);
- assertArrayEquals(shapes, shapesConsumed);
+ Object[] shapesConsumed = consumed.get(5L, TimeUnit.SECONDS);
+ String[] shapesConsumedStringArray = Arrays.stream(shapesConsumed).toArray(String[]::new);
+ assertArrayEquals(shapes, shapesConsumedStringArray);
}
static class Producer implements Runnable {
diff --git a/pom.xml b/pom.xml
index 9fa62d27ee..8fa7c1e2b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -337,7 +337,7 @@
annotations
antlr
- apache-cxf
+ apache-cxf-modules
apache-kafka
apache-libraries
apache-olingo
@@ -372,10 +372,7 @@
cloud-foundry-uaa
code-generation
- core-groovy
- core-groovy-2
- core-groovy-collections
- core-groovy-strings
+ core-groovy-modules
core-java-modules
@@ -795,11 +792,11 @@
akka-http
akka-streams
- algorithms-modules
+ algorithms-modules
annotations
antlr
- apache-cxf
+ apache-cxf-modules
apache-kafka
apache-libraries
apache-olingo
@@ -834,11 +831,8 @@
cloud-foundry-uaa
code-generation
- core-groovy
- core-groovy-2
- core-groovy-collections
- core-groovy-strings
-
+ core-groovy-modules
+
core-java-modules
couchbase
diff --git a/spring-boot-modules/spring-boot-springdoc/pom.xml b/spring-boot-modules/spring-boot-springdoc/pom.xml
index e7d4a35d97..88e616119d 100644
--- a/spring-boot-modules/spring-boot-springdoc/pom.xml
+++ b/spring-boot-modules/spring-boot-springdoc/pom.xml
@@ -32,6 +32,14 @@
com.h2database
h2
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-resource-server
+
org.springframework.boot
spring-boot-starter-test
@@ -48,6 +56,11 @@
springdoc-openapi-data-rest
${springdoc.version}
+
+ org.springdoc
+ springdoc-openapi-security
+ ${springdoc.version}
+
org.springframework.restdocs
@@ -131,7 +144,7 @@
org.springdoc
springdoc-openapi-maven-plugin
- 0.2
+ 1.4
integration-test
@@ -152,7 +165,7 @@
- 1.6.4
+ 1.6.8
1.5.6
${project.build.directory}/generated-snippets
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/AuthenticationApi.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/AuthenticationApi.java
new file mode 100644
index 0000000000..c53774129a
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/AuthenticationApi.java
@@ -0,0 +1,86 @@
+package com.baeldung.jwt;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.oauth2.jwt.JwtClaimsSet;
+import org.springframework.security.oauth2.jwt.JwtEncoder;
+import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.Instant;
+import java.util.stream.Collectors;
+
+/**
+ * REST APIs that contains all the operations that can be performed for authentication like login, registration etc
+ */
+@RequestMapping("/api/auth")
+@RestController
+@Tag(name = "Authentication", description = "The Authentication API. Contains operations like change password, forgot password, login, logout, etc.")
+public class AuthenticationApi {
+
+ private final UserDetailsService userDetailsService;
+ private final JwtEncoder encoder;
+
+ public AuthenticationApi(UserDetailsService userDetailsService, JwtEncoder encoder) {
+ this.userDetailsService = userDetailsService;
+ this.encoder = encoder;
+ }
+
+ /**
+ * API to Login
+ *
+ * @param user The login entity that contains username and password
+ * @return Returns the JWT token
+ * @see com.baeldung.jwt.User
+ */
+ @Operation(summary = "User Authentication", description = "Authenticate the user and return a JWT token if the user is valid.")
+ @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @io.swagger.v3.oas.annotations.media.Content(mediaType = "application/json", examples = @io.swagger.v3.oas.annotations.media.ExampleObject(value = "{\n" + " \"username\": \"jane\",\n"
+ + " \"password\": \"password\"\n" + "}", summary = "User Authentication Example")))
+ @PostMapping(value = "/login", produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity login(@RequestBody User user) {
+ UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername());
+ if (user.getPassword().equalsIgnoreCase(userDetails.getPassword())) {
+ String token = generateToken(userDetails);
+ HttpHeaders httpHeaders = new HttpHeaders();
+ httpHeaders.set("X-AUTH-TOKEN", token);
+ return ResponseEntity.ok().headers(httpHeaders).contentType(MediaType.APPLICATION_JSON).body("{\"token\":\"" + token + "\"}");
+ } else {
+ return ResponseEntity.status(HttpStatus.UNAUTHORIZED).contentType(MediaType.APPLICATION_JSON).body("Invalid username or password");
+ }
+ }
+
+ /**
+ * Generates the JWT token with claims
+ *
+ * @param userDetails The user details
+ * @return Returns the JWT token
+ */
+ private String generateToken(UserDetails userDetails) {
+ Instant now = Instant.now();
+ long expiry = 36000L;
+ // @formatter:off
+ String scope = userDetails.getAuthorities().stream()
+ .map(GrantedAuthority::getAuthority)
+ .collect(Collectors.joining(" "));
+ JwtClaimsSet claims = JwtClaimsSet.builder()
+ .issuer("self")
+ .issuedAt(now)
+ .expiresAt(now.plusSeconds(expiry))
+ .subject(userDetails.getUsername())
+ .claim("scope", scope)
+ .build();
+ // @formatter:on
+ return this.encoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/OpenAPI30Configuration.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/OpenAPI30Configuration.java
new file mode 100644
index 0000000000..53f0b735fe
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/OpenAPI30Configuration.java
@@ -0,0 +1,52 @@
+package com.baeldung.jwt;
+
+import io.swagger.v3.oas.annotations.OpenAPIDefinition;
+import io.swagger.v3.oas.annotations.info.Contact;
+import io.swagger.v3.oas.annotations.info.Info;
+import io.swagger.v3.oas.annotations.info.License;
+import io.swagger.v3.oas.annotations.servers.Server;
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.security.SecurityRequirement;
+import io.swagger.v3.oas.models.security.SecurityScheme;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+//@formatter:off
+@OpenAPIDefinition(
+ info = @Info(title = "User API", version = "${api.version}",
+ contact = @Contact(name = "Baeldung", email = "user-apis@baeldung.com", url = "https://www.baeldung.com"),
+ license = @License(name = "Apache 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0"), termsOfService = "${tos.uri}",
+ description = "${api.description}"),
+ servers = {
+ @Server(url = "http://localhost:8080", description = "Development"),
+ @Server(url = "${api.server.url}", description = "Production")})
+//@formatter:on
+public class OpenAPI30Configuration {
+
+ /**
+ * Configure the OpenAPI components.
+ *
+ * @return Returns fully configure OpenAPI object
+ * @see OpenAPI
+ */
+ @Bean
+ public OpenAPI customizeOpenAPI() {
+ //@formatter:off
+ final String securitySchemeName = "bearerAuth";
+ return new OpenAPI()
+ .addSecurityItem(new SecurityRequirement()
+ .addList(securitySchemeName))
+ .components(new Components()
+ .addSecuritySchemes(securitySchemeName, new SecurityScheme()
+ .name(securitySchemeName)
+ .type(SecurityScheme.Type.HTTP)
+ .scheme("bearer")
+ .description(
+ "Provide the JWT token. JWT token can be obtained from the Login API. For testing, use the credentials john/password")
+ .bearerFormat("JWT")));
+ //@formatter:on
+
+ }
+}
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/SecurityConfiguration.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/SecurityConfiguration.java
new file mode 100644
index 0000000000..6b42a8f1bb
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/SecurityConfiguration.java
@@ -0,0 +1,124 @@
+package com.baeldung.jwt;
+
+import com.nimbusds.jose.jwk.JWK;
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jose.jwk.RSAKey;
+import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.oauth2.jwt.JwtDecoder;
+import org.springframework.security.oauth2.jwt.JwtEncoder;
+import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
+import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
+import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
+import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
+
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+import org.springframework.security.core.userdetails.User;
+
+/**
+ * This class is inspired from
+ * https://github.com/spring-projects/spring-security-samples/blob/5.7.x/servlet/spring-boot/java/jwt/login/src/main/java/example/RestConfig.java
+ */
+@EnableWebSecurity
+@Configuration
+public class SecurityConfiguration {
+
+ @Value("${jwt.public.key}")
+ RSAPublicKey publicKey;
+
+ @Value("${jwt.private.key}")
+ RSAPrivateKey privateKey;
+
+ /**
+ * This bean is used to configure the JWT token. Configure the URLs that should not be protected by the JWT token.
+ *
+ * @param http the HttpSecurity object
+ * @return the HttpSecurity object
+ * @throws Exception if an error occurs
+ */
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ //@formatter:off
+ return http
+ .authorizeHttpRequests(authorizeRequests -> authorizeRequests
+ .antMatchers("/api/auth/**", "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**", "/webjars/**",
+ "/swagger-ui/index.html")
+ .permitAll()
+ .anyRequest()
+ .authenticated())
+ .cors().disable()
+ .csrf().disable()
+ .formLogin().disable()
+ .httpBasic().disable()
+ .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ .and()
+ .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
+ .exceptionHandling(exceptions -> exceptions
+ .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
+ .accessDeniedHandler(new BearerTokenAccessDeniedHandler())
+ .and())
+ .build();
+ //@formatter:on
+ }
+
+ /**
+ * For demonstration/example, we use the InMemoryUserDetailsManager.
+ *
+ * @return Returns the UserDetailsService with pre-configure credentials.
+ * @see InMemoryUserDetailsManager
+ */
+ @Bean
+ UserDetailsService allUsers() {
+ // @formatter:off
+ InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
+ manager
+ .createUser(User.builder()
+ .passwordEncoder(password -> password)
+ .username("john")
+ .password("password")
+ .authorities("USER")
+ .roles("USER").build());
+ manager
+ .createUser(User.builder()
+ .passwordEncoder(password -> password)
+ .username("jane")
+ .password("password")
+ .authorities("USER")
+ .roles("USER").build());
+ return manager;
+ // @formatter:on
+ }
+
+ /**
+ * This bean is used to decode the JWT token.
+ *
+ * @return Returns the JwtDecoder bean to decode JWT tokens.
+ */
+ @Bean
+ JwtDecoder jwtDecoder() {
+ return NimbusJwtDecoder.withPublicKey(this.publicKey).build();
+ }
+
+ /**
+ * This bean is used to encode the JWT token.
+ *
+ * @return Returns the JwtEncoder bean to encode JWT tokens.
+ */
+ @Bean
+ JwtEncoder jwtEncoder() {
+ JWK jwk = new RSAKey.Builder(this.publicKey).privateKey(this.privateKey).build();
+ return new NimbusJwtEncoder(new ImmutableJWKSet<>(new JWKSet(jwk)));
+ }
+}
+
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/SecurityTokenApplication.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/SecurityTokenApplication.java
new file mode 100644
index 0000000000..4c0c4f01d8
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/SecurityTokenApplication.java
@@ -0,0 +1,17 @@
+package com.baeldung.jwt;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SecurityTokenApplication {
+
+ /**
+ * The bootstrap method
+ * @param args
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(SecurityTokenApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/User.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/User.java
new file mode 100644
index 0000000000..43427c609f
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/User.java
@@ -0,0 +1,56 @@
+package com.baeldung.jwt;
+
+
+import java.io.Serializable;
+
+public class User implements Serializable {
+
+ private static final long serialVersionUID = 3317686311392412458L;
+ private String username;
+ private String password;
+ private String role;
+ private String email;
+
+ public User(String username, String password, String role) {
+ this.username = username;
+ this.password = password;
+ this.role = role;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ @Override
+ public String toString() {
+ return "User [username=" + username + ", password=" + password + ", role=" + role + "]";
+ }
+}
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/UserApi.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/UserApi.java
new file mode 100644
index 0000000000..d2d17978ba
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/jwt/UserApi.java
@@ -0,0 +1,50 @@
+package com.baeldung.jwt;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.text.MessageFormat;
+
+/**
+ * REST APIs that contain all the operations that can be performed on a User
+ */
+@RequestMapping("/api/user")
+@RestController
+@Tag(name = "User", description = "The User API. Contains all the operations that can be performed on a user.")
+public class UserApi {
+
+ private final UserDetailsService userDetailsService;
+
+ public UserApi(UserDetailsService userDetailsService) {
+ this.userDetailsService = userDetailsService;
+ }
+
+ /**
+ * API to get the current user. Returns the user details for the provided JWT token
+ * @param authentication The authentication object that contains the JWT token
+ * @return Returns the user details for the provided JWT token
+ */
+ @Operation(summary = "Get user details", description = "Get the user details. The operation returns the details of the user that is associated " + "with the provided JWT token.")
+ @GetMapping
+ public UserDetails getUser(Authentication authentication) {
+ return userDetailsService.loadUserByUsername(authentication.getName());
+ }
+
+ /**
+ * API to delete the current user.
+ * @param authentication The authentication object that contains the JWT token
+ * @return Returns a success message on deletion of the user
+ */
+ @Operation(summary = "Delete user details", description = "Delete user details. The operation deletes the details of the user that is " + "associated with the provided JWT token.")
+ @DeleteMapping
+ public String deleteUser(Authentication authentication) {
+ return MessageFormat.format("User {0} deleted successfully", authentication.getName());
+ }
+}
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/resources/app.key b/spring-boot-modules/spring-boot-springdoc/src/main/resources/app.key
new file mode 100644
index 0000000000..53510079ac
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/resources/app.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDcWWomvlNGyQhA
+iB0TcN3sP2VuhZ1xNRPxr58lHswC9Cbtdc2hiSbe/sxAvU1i0O8vaXwICdzRZ1JM
+g1TohG9zkqqjZDhyw1f1Ic6YR/OhE6NCpqERy97WMFeW6gJd1i5inHj/W19GAbqK
+LhSHGHqIjyo0wlBf58t+qFt9h/EFBVE/LAGQBsg/jHUQCxsLoVI2aSELGIw2oSDF
+oiljwLaQl0n9khX5ZbiegN3OkqodzCYHwWyu6aVVj8M1W9RIMiKmKr09s/gf31Nc
+3WjvjqhFo1rTuurWGgKAxJLL7zlJqAKjGWbIT4P6h/1Kwxjw6X23St3OmhsG6HIn
++jl1++MrAgMBAAECggEBAMf820wop3pyUOwI3aLcaH7YFx5VZMzvqJdNlvpg1jbE
+E2Sn66b1zPLNfOIxLcBG8x8r9Ody1Bi2Vsqc0/5o3KKfdgHvnxAB3Z3dPh2WCDek
+lCOVClEVoLzziTuuTdGO5/CWJXdWHcVzIjPxmK34eJXioiLaTYqN3XKqKMdpD0ZG
+mtNTGvGf+9fQ4i94t0WqIxpMpGt7NM4RHy3+Onggev0zLiDANC23mWrTsUgect/7
+62TYg8g1bKwLAb9wCBT+BiOuCc2wrArRLOJgUkj/F4/gtrR9ima34SvWUyoUaKA0
+bi4YBX9l8oJwFGHbU9uFGEMnH0T/V0KtIB7qetReywkCgYEA9cFyfBIQrYISV/OA
++Z0bo3vh2aL0QgKrSXZ924cLt7itQAHNZ2ya+e3JRlTczi5mnWfjPWZ6eJB/8MlH
+Gpn12o/POEkU+XjZZSPe1RWGt5g0S3lWqyx9toCS9ACXcN9tGbaqcFSVI73zVTRA
+8J9grR0fbGn7jaTlTX2tnlOTQ60CgYEA5YjYpEq4L8UUMFkuj+BsS3u0oEBnzuHd
+I9LEHmN+CMPosvabQu5wkJXLuqo2TxRnAznsA8R3pCLkdPGoWMCiWRAsCn979TdY
+QbqO2qvBAD2Q19GtY7lIu6C35/enQWzJUMQE3WW0OvjLzZ0l/9mA2FBRR+3F9A1d
+rBdnmv0c3TcCgYEAi2i+ggVZcqPbtgrLOk5WVGo9F1GqUBvlgNn30WWNTx4zIaEk
+HSxtyaOLTxtq2odV7Kr3LGiKxwPpn/T+Ief+oIp92YcTn+VfJVGw4Z3BezqbR8lA
+Uf/+HF5ZfpMrVXtZD4Igs3I33Duv4sCuqhEvLWTc44pHifVloozNxYfRfU0CgYBN
+HXa7a6cJ1Yp829l62QlJKtx6Ymj95oAnQu5Ez2ROiZMqXRO4nucOjGUP55Orac1a
+FiGm+mC/skFS0MWgW8evaHGDbWU180wheQ35hW6oKAb7myRHtr4q20ouEtQMdQIF
+snV39G1iyqeeAsf7dxWElydXpRi2b68i3BIgzhzebQKBgQCdUQuTsqV9y/JFpu6H
+c5TVvhG/ubfBspI5DhQqIGijnVBzFT//UfIYMSKJo75qqBEyP2EJSmCsunWsAFsM
+TszuiGTkrKcZy9G0wJqPztZZl2F2+bJgnA6nBEV7g5PA4Af+QSmaIhRwqGDAuROR
+47jndeyIaMTNETEmOnms+as17g==
+-----END PRIVATE KEY-----
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/resources/app.pub b/spring-boot-modules/spring-boot-springdoc/src/main/resources/app.pub
new file mode 100644
index 0000000000..0b2ee7b336
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/resources/app.pub
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3FlqJr5TRskIQIgdE3Dd
+7D9lboWdcTUT8a+fJR7MAvQm7XXNoYkm3v7MQL1NYtDvL2l8CAnc0WdSTINU6IRv
+c5Kqo2Q4csNX9SHOmEfzoROjQqahEcve1jBXluoCXdYuYpx4/1tfRgG6ii4Uhxh6
+iI8qNMJQX+fLfqhbfYfxBQVRPywBkAbIP4x1EAsbC6FSNmkhCxiMNqEgxaIpY8C2
+kJdJ/ZIV+WW4noDdzpKqHcwmB8FsrumlVY/DNVvUSDIipiq9PbP4H99TXN1o746o
+RaNa07rq1hoCgMSSy+85SagCoxlmyE+D+of9SsMY8Ol9t0rdzpobBuhyJ/o5dfvj
+KwIDAQAB
+-----END PUBLIC KEY-----
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/resources/application.properties b/spring-boot-modules/spring-boot-springdoc/src/main/resources/application.properties
index 733e716e76..a668601a7d 100644
--- a/spring-boot-modules/spring-boot-springdoc/src/main/resources/application.properties
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/resources/application.properties
@@ -1,6 +1,5 @@
# custom path for swagger-ui
springdoc.swagger-ui.path=/swagger-ui-custom.html
-springdoc.swagger-ui.operationsSorter=method
# custom path for api docs
springdoc.api-docs.path=/api-docs
@@ -10,4 +9,16 @@ spring.datasource.url=jdbc:h2:mem:springdoc
## for com.baeldung.restdocopenapi ##
springdoc.version=@springdoc.version@
-spring.jpa.hibernate.ddl-auto=none
\ No newline at end of file
+spring.jpa.hibernate.ddl-auto=none
+
+## for com.baeldung.jwt ##
+jwt.private.key=classpath:app.key
+jwt.public.key=classpath:app.pub
+
+
+api.version=1.0-SNAPSHOT
+tos.uri=terms-of-service
+api.server.url=https://www.baeldung.com
+api.description=The User API is used to create, update, and delete users. Users can be created with or without an associated account. If an account is created, the user will be granted the ROLE_USER role. If an account is not created, the user will be granted the ROLE_USER role.
+springdoc.swagger-ui.operationsSorter=alpha
+springdoc.swagger-ui.tagsSorter=alpha
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/jwt/OpenApiJwtIntegrationTest.java b/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/jwt/OpenApiJwtIntegrationTest.java
new file mode 100644
index 0000000000..1ea88d14fa
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/test/java/com/baeldung/jwt/OpenApiJwtIntegrationTest.java
@@ -0,0 +1,89 @@
+package com.baeldung.jwt;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@DisplayName("OpenAPI JWT Live Tests")
+class OpenApiJwtIntegrationTest
+{
+ @LocalServerPort
+ private int port;
+ @Autowired
+ private AuthenticationApi authenticationApi;
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @Test
+ @DisplayName("LiveTest - Render Swagger UI")
+ void whenInvokeSwagger_thenRenderIndexPage()
+ {
+ assertNotNull(authenticationApi);
+
+ String response = this.restTemplate.getForObject("http://localhost:" + port + "/swagger-ui.html", String.class);
+
+ assertNotNull(response);
+ assertTrue(response.contains("Swagger UI"));
+ assertTrue(response.contains(""));
+ }
+
+ @Test
+ @DisplayName("LiveTest - Check Headers")
+ void whenInvokeOpenApi_thenCheckHeaders()
+ {
+ assertNotNull(authenticationApi);
+
+ ResponseEntity response = this.restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs",
+ String.class);
+
+ assertNotNull(response);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertNotNull(response.getHeaders().get("Content-Type"));
+ assertEquals(1, response.getHeaders().get("Content-Type").size());
+ assertEquals("application/json", response.getHeaders().get("Content-Type").get(0));
+ }
+
+ @Test
+ @DisplayName("LiveTest - Verify OpenAPI Document")
+ void whenInvokeOpenApi_thenVerifyOpenApiDoc()
+ {
+ assertNotNull(authenticationApi);
+
+ ResponseEntity response = this.restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs",
+ String.class);
+
+ assertNotNull(response);
+ assertNotNull(response.getBody());
+ assertTrue(response.getBody().contains("\"openapi\":"));
+ assertTrue(response.getBody().contains("User API"));
+ assertTrue(response.getBody().contains("\"post\""));
+ }
+
+ @Test
+ @DisplayName("LiveTest - Verify OpenAPI Security Section")
+ void whenInvokeOpenApi_thenCheckSecurityConfig()
+ {
+ assertNotNull(authenticationApi);
+
+ ResponseEntity response = this.restTemplate.getForEntity("http://localhost:" + port + "/v3/api-docs",
+ String.class);
+
+ assertNotNull(response);
+ assertNotNull(response.getBody());
+ assertTrue(response.getBody().contains("\"securitySchemes\""));
+ assertTrue(response.getBody().contains("\"bearerFormat\":\"JWT\""));
+ assertTrue(response.getBody().contains("\"scheme\":\"bearer\""));
+ }
+
+}
+
diff --git a/spring-cloud/spring-cloud-docker/docker-compose-restart-policy-swarm-mode.yml b/spring-cloud-modules/spring-cloud-docker/docker-compose-restart-policy-swarm-mode.yml
similarity index 100%
rename from spring-cloud/spring-cloud-docker/docker-compose-restart-policy-swarm-mode.yml
rename to spring-cloud-modules/spring-cloud-docker/docker-compose-restart-policy-swarm-mode.yml
diff --git a/spring-cloud/spring-cloud-docker/docker-compose-restart-policy.yml b/spring-cloud-modules/spring-cloud-docker/docker-compose-restart-policy.yml
similarity index 100%
rename from spring-cloud/spring-cloud-docker/docker-compose-restart-policy.yml
rename to spring-cloud-modules/spring-cloud-docker/docker-compose-restart-policy.yml
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/README.md b/spring-cloud-modules/spring-cloud-netflix-sidecar/README.md
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/README.md
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/README.md
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/echo-demo/pom.xml b/spring-cloud-modules/spring-cloud-netflix-sidecar/echo-demo/pom.xml
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/echo-demo/pom.xml
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/echo-demo/pom.xml
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/echo-demo/src/main/java/com/baeldung/cloud/echo/EchoApplication.java b/spring-cloud-modules/spring-cloud-netflix-sidecar/echo-demo/src/main/java/com/baeldung/cloud/echo/EchoApplication.java
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/echo-demo/src/main/java/com/baeldung/cloud/echo/EchoApplication.java
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/echo-demo/src/main/java/com/baeldung/cloud/echo/EchoApplication.java
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/echo-demo/src/main/resources/application.yml b/spring-cloud-modules/spring-cloud-netflix-sidecar/echo-demo/src/main/resources/application.yml
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/echo-demo/src/main/resources/application.yml
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/echo-demo/src/main/resources/application.yml
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/echo-demo/src/test/java/com/baeldung/cloud/echo/SpringContextTest.java b/spring-cloud-modules/spring-cloud-netflix-sidecar/echo-demo/src/test/java/com/baeldung/cloud/echo/SpringContextTest.java
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/echo-demo/src/test/java/com/baeldung/cloud/echo/SpringContextTest.java
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/echo-demo/src/test/java/com/baeldung/cloud/echo/SpringContextTest.java
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/pom.xml b/spring-cloud-modules/spring-cloud-netflix-sidecar/pom.xml
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/pom.xml
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/pom.xml
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/nodejs/hello.js b/spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/nodejs/hello.js
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/nodejs/hello.js
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/nodejs/hello.js
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/pom.xml b/spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/pom.xml
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/pom.xml
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/pom.xml
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/src/main/java/com/baeldung/cloud/sidecar/SidecarApplication.java b/spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/src/main/java/com/baeldung/cloud/sidecar/SidecarApplication.java
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/src/main/java/com/baeldung/cloud/sidecar/SidecarApplication.java
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/src/main/java/com/baeldung/cloud/sidecar/SidecarApplication.java
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/src/main/resources/application.yml b/spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/src/main/resources/application.yml
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/src/main/resources/application.yml
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/src/main/resources/application.yml
diff --git a/spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/src/test/java/com/baeldung/cloud/sidecar/SpringContextTest.java b/spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/src/test/java/com/baeldung/cloud/sidecar/SpringContextTest.java
similarity index 100%
rename from spring-cloud/spring-cloud-netflix-sidecar/sidecar-demo/src/test/java/com/baeldung/cloud/sidecar/SpringContextTest.java
rename to spring-cloud-modules/spring-cloud-netflix-sidecar/sidecar-demo/src/test/java/com/baeldung/cloud/sidecar/SpringContextTest.java
diff --git a/spring-cloud-modules/spring-cloud-openfeign/README.md b/spring-cloud-modules/spring-cloud-openfeign/README.md
index c1bd5ad43e..a369da96da 100644
--- a/spring-cloud-modules/spring-cloud-openfeign/README.md
+++ b/spring-cloud-modules/spring-cloud-openfeign/README.md
@@ -6,3 +6,4 @@
- [Feign Logging Configuration](https://www.baeldung.com/java-feign-logging)
- [Provide an OAuth2 Token to a Feign Client](https://www.baeldung.com/spring-cloud-feign-oauth-token)
- [Retrieve Original Message From Feign ErrorDecoder](https://www.baeldung.com/feign-retrieve-original-message)
+- [RequestLine with Feign Client](https://www.baeldung.com/feign-requestline)
diff --git a/spring-cloud/spring-cloud-openfeign/README.md b/spring-cloud/spring-cloud-openfeign/README.md
deleted file mode 100644
index 3aa8c20b24..0000000000
--- a/spring-cloud/spring-cloud-openfeign/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-
-### Relevant Articles:
-- [RequestLine with Feign Client](https://www.baeldung.com/feign-requestline)
diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java
index 8b5c7233d6..e6f8ba35c2 100644
--- a/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java
+++ b/spring-reactive/src/main/java/com/baeldung/reactive/webflux/functional/EmployeeFunctionalConfig.java
@@ -25,49 +25,39 @@ public class EmployeeFunctionalConfig {
@Bean
RouterFunction getAllEmployeesRoute() {
- return route(GET("/employees"),
- req -> ok().body(
- employeeRepository().findAllEmployees(), Employee.class));
+ return route(GET("/employees"), req -> ok().body(employeeRepository().findAllEmployees(), Employee.class));
}
@Bean
RouterFunction getEmployeeByIdRoute() {
- return route(GET("/employees/{id}"),
- req -> ok().body(
- employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class));
+ return route(GET("/employees/{id}"), req -> ok().body(employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class));
}
@Bean
RouterFunction updateEmployeeRoute() {
- return route(POST("/employees/update"),
- req -> req.body(toMono(Employee.class))
+ return route(POST("/employees/update"), req -> req.body(toMono(Employee.class))
.doOnNext(employeeRepository()::updateEmployee)
.then(ok().build()));
}
@Bean
RouterFunction composedRoutes() {
- return
- route(GET("/employees"),
- req -> ok().body(
- employeeRepository().findAllEmployees(), Employee.class))
+ return route(GET("/employees"), req -> ok().body(employeeRepository().findAllEmployees(), Employee.class))
- .and(route(GET("/employees/{id}"),
- req -> ok().body(
- employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)))
+ .and(route(GET("/employees/{id}"), req -> ok().body(employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)))
- .and(route(POST("/employees/update"),
- req -> req.body(toMono(Employee.class))
+ .and(route(POST("/employees/update"), req -> req.body(toMono(Employee.class))
.doOnNext(employeeRepository()::updateEmployee)
.then(ok().build())));
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
- http
- .csrf().disable()
- .authorizeExchange()
- .anyExchange().permitAll();
+ http.csrf()
+ .disable()
+ .authorizeExchange()
+ .anyExchange()
+ .permitAll();
return http.build();
}
-}
+}
\ No newline at end of file
diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/webflux/functional/EmployeeSpringFunctionalIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/webflux/functional/EmployeeSpringFunctionalIntegrationTest.java
index 198ec0d081..5a54820e23 100644
--- a/spring-reactive/src/test/java/com/baeldung/reactive/webflux/functional/EmployeeSpringFunctionalIntegrationTest.java
+++ b/spring-reactive/src/test/java/com/baeldung/reactive/webflux/functional/EmployeeSpringFunctionalIntegrationTest.java
@@ -31,55 +31,54 @@ public class EmployeeSpringFunctionalIntegrationTest {
@Test
public void givenEmployeeId_whenGetEmployeeById_thenCorrectEmployee() {
- WebTestClient client = WebTestClient
- .bindToRouterFunction(config.getEmployeeByIdRoute())
- .build();
+ WebTestClient client = WebTestClient.bindToRouterFunction(config.getEmployeeByIdRoute())
+ .build();
Employee employee = new Employee("1", "Employee 1");
given(employeeRepository.findEmployeeById("1")).willReturn(Mono.just(employee));
client.get()
- .uri("/employees/1")
- .exchange()
- .expectStatus().isOk()
- .expectBody(Employee.class).isEqualTo(employee);
+ .uri("/employees/1")
+ .exchange()
+ .expectStatus()
+ .isOk()
+ .expectBody(Employee.class)
+ .isEqualTo(employee);
}
@Test
public void whenGetAllEmployees_thenCorrectEmployees() {
- WebTestClient client = WebTestClient
- .bindToRouterFunction(config.getAllEmployeesRoute())
- .build();
+ WebTestClient client = WebTestClient.bindToRouterFunction(config.getAllEmployeesRoute())
+ .build();
- List employees = Arrays.asList(
- new Employee("1", "Employee 1"),
- new Employee("2", "Employee 2")
- );
+ List employees = Arrays.asList(new Employee("1", "Employee 1"), new Employee("2", "Employee 2"));
Flux employeeFlux = Flux.fromIterable(employees);
given(employeeRepository.findAllEmployees()).willReturn(employeeFlux);
client.get()
- .uri("/employees")
- .exchange()
- .expectStatus().isOk()
- .expectBodyList(Employee.class).isEqualTo(employees);
+ .uri("/employees")
+ .exchange()
+ .expectStatus()
+ .isOk()
+ .expectBodyList(Employee.class)
+ .isEqualTo(employees);
}
@Test
public void whenUpdateEmployee_thenEmployeeUpdated() {
- WebTestClient client = WebTestClient
- .bindToRouterFunction(config.updateEmployeeRoute())
- .build();
+ WebTestClient client = WebTestClient.bindToRouterFunction(config.updateEmployeeRoute())
+ .build();
Employee employee = new Employee("1", "Employee 1 Updated");
client.post()
- .uri("/employees/update")
- .body(Mono.just(employee), Employee.class)
- .exchange()
- .expectStatus().isOk();
+ .uri("/employees/update")
+ .body(Mono.just(employee), Employee.class)
+ .exchange()
+ .expectStatus()
+ .isOk();
verify(employeeRepository).updateEmployee(employee);
}