diff --git a/core-java/README.md b/core-java/README.md
index 0f0e4cc858..a251de1daa 100644
--- a/core-java/README.md
+++ b/core-java/README.md
@@ -106,3 +106,4 @@
- [Converting a List to String in Java](http://www.baeldung.com/java-list-to-string)
- [CharSequence vs. String in Java](http://www.baeldung.com/java-char-sequence-string)
- [Period and Duration in Java](http://www.baeldung.com/java-period-duration)
+- [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator)
\ No newline at end of file
diff --git a/kotlin/README.md b/core-kotlin/README.md
similarity index 100%
rename from kotlin/README.md
rename to core-kotlin/README.md
diff --git a/kotlin/pom.xml b/core-kotlin/pom.xml
similarity index 99%
rename from kotlin/pom.xml
rename to core-kotlin/pom.xml
index e88013ab69..856a37ded0 100644
--- a/kotlin/pom.xml
+++ b/core-kotlin/pom.xml
@@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- kotlin
+ core-kotlin
1.0-SNAPSHOT
diff --git a/kotlin/src/main/java/com/baeldung/dataclass/Movie.java b/core-kotlin/src/main/java/com/baeldung/dataclass/Movie.java
similarity index 100%
rename from kotlin/src/main/java/com/baeldung/dataclass/Movie.java
rename to core-kotlin/src/main/java/com/baeldung/dataclass/Movie.java
diff --git a/kotlin/src/main/java/com/baeldung/java/ArrayExample.java b/core-kotlin/src/main/java/com/baeldung/java/ArrayExample.java
similarity index 100%
rename from kotlin/src/main/java/com/baeldung/java/ArrayExample.java
rename to core-kotlin/src/main/java/com/baeldung/java/ArrayExample.java
diff --git a/kotlin/src/main/java/com/baeldung/java/Customer.java b/core-kotlin/src/main/java/com/baeldung/java/Customer.java
similarity index 100%
rename from kotlin/src/main/java/com/baeldung/java/Customer.java
rename to core-kotlin/src/main/java/com/baeldung/java/Customer.java
diff --git a/kotlin/src/main/java/com/baeldung/java/StringUtils.java b/core-kotlin/src/main/java/com/baeldung/java/StringUtils.java
similarity index 100%
rename from kotlin/src/main/java/com/baeldung/java/StringUtils.java
rename to core-kotlin/src/main/java/com/baeldung/java/StringUtils.java
diff --git a/kotlin/src/main/java/com/baeldung/lazy/ClassWithHeavyInitialization.java b/core-kotlin/src/main/java/com/baeldung/lazy/ClassWithHeavyInitialization.java
similarity index 100%
rename from kotlin/src/main/java/com/baeldung/lazy/ClassWithHeavyInitialization.java
rename to core-kotlin/src/main/java/com/baeldung/lazy/ClassWithHeavyInitialization.java
diff --git a/kotlin/src/main/kotlin/com/baeldung/dataclass/Movie.kt b/core-kotlin/src/main/kotlin/com/baeldung/dataclass/Movie.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/dataclass/Movie.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/dataclass/Movie.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/dataclass/Sandbox.kt b/core-kotlin/src/main/kotlin/com/baeldung/dataclass/Sandbox.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/dataclass/Sandbox.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/dataclass/Sandbox.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Person.kt b/core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Person.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Person.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Person.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Result.kt b/core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Result.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Result.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Result.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Sandbox.kt b/core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Sandbox.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Sandbox.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Sandbox.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/Example1.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/Example1.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/Example1.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/Example1.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/Item.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/Item.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/Item.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/Item.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/JvmSample.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/JvmSample.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/JvmSample.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/JvmSample.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/ListExtension.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/ListExtension.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/ListExtension.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/ListExtension.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/User.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/User.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/User.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/User.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/WhenBlockTypes.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/WhenBlockTypes.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/WhenBlockTypes.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/WhenBlockTypes.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/Database.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/Database.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/Database.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/Database.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegate.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegate.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegate.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegate.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/User.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/User.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/User.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/User.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt
similarity index 100%
rename from kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt
rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt
diff --git a/kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java b/core-kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java
similarity index 100%
rename from kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java
rename to core-kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java
diff --git a/kotlin/src/test/java/com/baeldung/kotlin/LazyJavaUnitTest.java b/core-kotlin/src/test/java/com/baeldung/kotlin/LazyJavaUnitTest.java
similarity index 100%
rename from kotlin/src/test/java/com/baeldung/kotlin/LazyJavaUnitTest.java
rename to core-kotlin/src/test/java/com/baeldung/kotlin/LazyJavaUnitTest.java
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/ArrayTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ArrayTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/ArrayTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/ArrayTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/CollectionsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CollectionsTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/CollectionsTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CollectionsTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/CustomerTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CustomerTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/CustomerTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CustomerTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/EqualityTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/EqualityTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/EqualityTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/EqualityTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/GenericsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/GenericsTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/GenericsTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/GenericsTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/ItemServiceTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ItemServiceTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/ItemServiceTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/ItemServiceTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/JvmSampleTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/JvmSampleTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/JvmSampleTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/JvmSampleTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinJavaInteroperabilityTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinJavaInteroperabilityTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinJavaInteroperabilityTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinJavaInteroperabilityTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/ListExtensionTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ListExtensionTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/ListExtensionTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/ListExtensionTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/ListToMapTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ListToMapTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/ListToMapTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/ListToMapTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/NullSafetyTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/NullSafetyTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/NullSafetyTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/NullSafetyTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/WhenBlockUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/WhenBlockUnitTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/WhenBlockUnitTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/WhenBlockUnitTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegatesTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegatesTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegatesTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegatesTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt
similarity index 100%
rename from kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt
diff --git a/geotools/README.md b/geotools/README.md
new file mode 100644
index 0000000000..188ff0fddb
--- /dev/null
+++ b/geotools/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles
+
+[Introduction to GeoTools](http://www.baeldung.com/geo-tools)
diff --git a/libraries/src/test/java/com/baeldung/pairs/CoreJavaSimpleEntryUnitTest.java b/libraries/src/test/java/com/baeldung/pairs/CoreJavaSimpleEntryUnitTest.java
new file mode 100644
index 0000000000..ca425339fa
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/pairs/CoreJavaSimpleEntryUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.pairs;
+
+import static org.junit.Assert.*;
+
+import java.util.AbstractMap;
+
+import org.junit.Test;
+
+public class CoreJavaSimpleEntryUnitTest {
+
+ @Test
+ public void givenSimpleEntry_whenGetValue_thenOk() {
+ AbstractMap.SimpleEntry entry = new AbstractMap.SimpleEntry(1, "one");
+ Integer key = entry.getKey();
+ String value = entry.getValue();
+
+ assertEquals(key.intValue(), 1);
+ assertEquals(value, "one");
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void givenSimpleImmutableEntry_whenSetValue_thenException() {
+ AbstractMap.SimpleImmutableEntry entry = new AbstractMap.SimpleImmutableEntry(1, "one");
+
+ entry.setValue("two");
+
+ }
+
+ @Test
+ public void givenSimpleImmutableEntry_whenGetValue_thenOk() {
+ AbstractMap.SimpleImmutableEntry entry = new AbstractMap.SimpleImmutableEntry(1, "one");
+ Integer key = entry.getKey();
+ String value = entry.getValue();
+
+ assertEquals(key.intValue(), 1);
+ assertEquals(value, "one");
+ }
+
+}
diff --git a/linkrest/WebContent/META-INF/MANIFEST.MF b/linkrest/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..254272e1c0
--- /dev/null
+++ b/linkrest/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/linkrest/WebContent/WEB-INF/web.xml b/linkrest/WebContent/WEB-INF/web.xml
new file mode 100644
index 0000000000..046c82b08a
--- /dev/null
+++ b/linkrest/WebContent/WEB-INF/web.xml
@@ -0,0 +1,20 @@
+
+
+ linkrest
+
+ linkrest
+ org.glassfish.jersey.servlet.ServletContainer
+
+ javax.ws.rs.Application
+ com.baeldung.LinkRestApplication
+
+ 1
+
+
+ linkrest
+ /*
+
+
\ No newline at end of file
diff --git a/linkrest/pom.xml b/linkrest/pom.xml
new file mode 100644
index 0000000000..aa2f0f8bda
--- /dev/null
+++ b/linkrest/pom.xml
@@ -0,0 +1,81 @@
+
+ 4.0.0
+ com.baeldung
+ linkrest
+ 0.0.1-SNAPSHOT
+ war
+
+
+
+ com.nhl.link.rest
+ link-rest
+ ${linkrest.version}
+
+
+ org.glassfish.jersey.containers
+ jersey-container-servlet
+ ${jersey.version}
+
+
+ org.glassfish.jersey.media
+ jersey-media-moxy
+ ${jersey.version}
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.5
+
+ 1.8
+ 1.8
+
+
+
+ maven-war-plugin
+ 2.6
+
+ WebContent
+ false
+
+
+
+ org.apache.cayenne.plugins
+ cayenne-maven-plugin
+ ${cayenne.version}
+
+
+
+
+
+
+
+
+ cgen
+
+
+
+
+
+ org.apache.cayenne.plugins
+ cayenne-modeler-maven-plugin
+ ${cayenne.version}
+
+
+
+
+
+ 2.9
+ 4.0.B1
+ 1.4.196
+ 2.25.1
+
+
\ No newline at end of file
diff --git a/linkrest/src/main/java/com/baeldung/LinkRestApplication.java b/linkrest/src/main/java/com/baeldung/LinkRestApplication.java
new file mode 100644
index 0000000000..7a2f7c8903
--- /dev/null
+++ b/linkrest/src/main/java/com/baeldung/LinkRestApplication.java
@@ -0,0 +1,24 @@
+package com.baeldung;
+
+
+import javax.ws.rs.ApplicationPath;
+
+import org.apache.cayenne.configuration.server.ServerRuntime;
+import org.glassfish.jersey.server.ResourceConfig;
+
+import com.nhl.link.rest.runtime.LinkRestBuilder;
+import com.nhl.link.rest.runtime.LinkRestRuntime;
+
+@ApplicationPath("/linkrest")
+public class LinkRestApplication extends ResourceConfig {
+
+ public LinkRestApplication() {
+ ServerRuntime cayenneRuntime = ServerRuntime.builder()
+ .addConfig("cayenne-linkrest-project.xml")
+ .build();
+ LinkRestRuntime lrRuntime = LinkRestBuilder.build(cayenneRuntime);
+ super.register(lrRuntime);
+ packages("com.baeldung.linkrest.apis");
+ }
+
+}
diff --git a/linkrest/src/main/java/com/baeldung/cayenne/Department.java b/linkrest/src/main/java/com/baeldung/cayenne/Department.java
new file mode 100644
index 0000000000..ed7a2bd795
--- /dev/null
+++ b/linkrest/src/main/java/com/baeldung/cayenne/Department.java
@@ -0,0 +1,9 @@
+package com.baeldung.cayenne;
+
+import com.baeldung.cayenne.auto._Department;
+
+public class Department extends _Department {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/linkrest/src/main/java/com/baeldung/cayenne/Employee.java b/linkrest/src/main/java/com/baeldung/cayenne/Employee.java
new file mode 100644
index 0000000000..632ea4fbf9
--- /dev/null
+++ b/linkrest/src/main/java/com/baeldung/cayenne/Employee.java
@@ -0,0 +1,9 @@
+package com.baeldung.cayenne;
+
+import com.baeldung.cayenne.auto._Employee;
+
+public class Employee extends _Employee {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/linkrest/src/main/java/com/baeldung/cayenne/auto/_Department.java b/linkrest/src/main/java/com/baeldung/cayenne/auto/_Department.java
new file mode 100644
index 0000000000..4111a8c8b2
--- /dev/null
+++ b/linkrest/src/main/java/com/baeldung/cayenne/auto/_Department.java
@@ -0,0 +1,44 @@
+package com.baeldung.cayenne.auto;
+
+import java.util.List;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.exp.Property;
+
+import com.baeldung.cayenne.Employee;
+
+/**
+ * Class _Department was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Department extends CayenneDataObject {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String DEP_ID_PK_COLUMN = "dep_id";
+
+ public static final Property NAME = Property.create("name", String.class);
+ public static final Property> EMPLOYEES = Property.create("employees", List.class);
+
+ public void setName(String name) {
+ writeProperty("name", name);
+ }
+ public String getName() {
+ return (String)readProperty("name");
+ }
+
+ public void addToEmployees(Employee obj) {
+ addToManyTarget("employees", obj, true);
+ }
+ public void removeFromEmployees(Employee obj) {
+ removeToManyTarget("employees", obj, true);
+ }
+ @SuppressWarnings("unchecked")
+ public List getEmployees() {
+ return (List)readProperty("employees");
+ }
+
+
+}
diff --git a/linkrest/src/main/java/com/baeldung/cayenne/auto/_Employee.java b/linkrest/src/main/java/com/baeldung/cayenne/auto/_Employee.java
new file mode 100644
index 0000000000..50e1880a56
--- /dev/null
+++ b/linkrest/src/main/java/com/baeldung/cayenne/auto/_Employee.java
@@ -0,0 +1,39 @@
+package com.baeldung.cayenne.auto;
+
+import org.apache.cayenne.CayenneDataObject;
+import org.apache.cayenne.exp.Property;
+
+import com.baeldung.cayenne.Department;
+
+/**
+ * Class _Employee was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Employee extends CayenneDataObject {
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String EMP_ID_PK_COLUMN = "emp_id";
+
+ public static final Property NAME = Property.create("name", String.class);
+ public static final Property DEPARTMENT = Property.create("department", Department.class);
+
+ public void setName(String name) {
+ writeProperty("name", name);
+ }
+ public String getName() {
+ return (String)readProperty("name");
+ }
+
+ public void setDepartment(Department department) {
+ setToOneTarget("department", department, true);
+ }
+
+ public Department getDepartment() {
+ return (Department)readProperty("department");
+ }
+
+
+}
diff --git a/linkrest/src/main/java/com/baeldung/linkrest/apis/DepartmentResource.java b/linkrest/src/main/java/com/baeldung/linkrest/apis/DepartmentResource.java
new file mode 100644
index 0000000000..f4090b580e
--- /dev/null
+++ b/linkrest/src/main/java/com/baeldung/linkrest/apis/DepartmentResource.java
@@ -0,0 +1,58 @@
+package com.baeldung.linkrest.apis;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Configuration;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+import com.baeldung.cayenne.Department;
+import com.nhl.link.rest.DataResponse;
+import com.nhl.link.rest.LinkRest;
+import com.nhl.link.rest.SimpleResponse;
+
+@Path("department")
+@Produces(MediaType.APPLICATION_JSON)
+public class DepartmentResource {
+
+ @Context
+ private Configuration config;
+
+ @GET
+ public DataResponse getAll(@Context UriInfo uriInfo) {
+ return LinkRest.select(Department.class, config).uri(uriInfo).get();
+ }
+
+ @GET
+ @Path("{id}")
+ public DataResponse getOne(@PathParam("id") int id, @Context UriInfo uriInfo) {
+ return LinkRest.select(Department.class, config).byId(id).uri(uriInfo).getOne();
+ }
+
+ @POST
+ public SimpleResponse create(String data) {
+ return LinkRest.create(Department.class, config).sync(data);
+ }
+
+ @PUT
+ public SimpleResponse createOrUpdate(String data) {
+ return LinkRest.createOrUpdate(Department.class, config).sync(data);
+ }
+
+ @Path("{id}/employees")
+ public EmployeeSubResource getEmployees(@PathParam("id") int id, @Context UriInfo uriInfo) {
+ return new EmployeeSubResource(id, config);
+ }
+
+ @DELETE
+ @Path("{id}")
+ public SimpleResponse delete(@PathParam("id") int id) {
+ return LinkRest.delete(Department.class, config).id(id).delete();
+ }
+}
diff --git a/linkrest/src/main/java/com/baeldung/linkrest/apis/EmployeeSubResource.java b/linkrest/src/main/java/com/baeldung/linkrest/apis/EmployeeSubResource.java
new file mode 100644
index 0000000000..ba9c3759bb
--- /dev/null
+++ b/linkrest/src/main/java/com/baeldung/linkrest/apis/EmployeeSubResource.java
@@ -0,0 +1,65 @@
+package com.baeldung.linkrest.apis;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Configuration;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+import com.baeldung.cayenne.Department;
+import com.baeldung.cayenne.Employee;
+import com.nhl.link.rest.DataResponse;
+import com.nhl.link.rest.LinkRest;
+import com.nhl.link.rest.SimpleResponse;
+
+@Produces(MediaType.APPLICATION_JSON)
+public class EmployeeSubResource {
+
+ private Configuration config;
+
+ private int departmentId;
+
+ public EmployeeSubResource(int departmentId, Configuration config) {
+ this.departmentId = departmentId;
+ this.config = config;
+ }
+
+ public EmployeeSubResource() {
+ }
+
+ @GET
+ public DataResponse getAll(@Context UriInfo uriInfo) {
+ return LinkRest.select(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).uri(uriInfo).get();
+ }
+
+ @GET
+ @Path("{id}")
+ public DataResponse getOne(@PathParam("id") int id, @Context UriInfo uriInfo) {
+ return LinkRest.select(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).byId(id).uri(uriInfo).getOne();
+ }
+
+ @POST
+ public SimpleResponse create(String data) {
+
+ return LinkRest.create(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).sync(data);
+ }
+
+ @PUT
+ public SimpleResponse createOrUpdate(String data) {
+ return LinkRest.create(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).sync(data);
+ }
+
+ @DELETE
+ @Path("{id}")
+ public SimpleResponse delete(@PathParam("id") int id) {
+ return LinkRest.delete(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).id(id).delete();
+
+ }
+
+}
diff --git a/linkrest/src/main/resources/cayenne-linkrest-project.xml b/linkrest/src/main/resources/cayenne-linkrest-project.xml
new file mode 100644
index 0000000000..8a4ba39c4d
--- /dev/null
+++ b/linkrest/src/main/resources/cayenne-linkrest-project.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/linkrest/src/main/resources/linkrest.map.xml b/linkrest/src/main/resources/linkrest.map.xml
new file mode 100644
index 0000000000..105d7d9d14
--- /dev/null
+++ b/linkrest/src/main/resources/linkrest.map.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 0b1ee17459..dd0871ae79 100644
--- a/pom.xml
+++ b/pom.xml
@@ -98,7 +98,8 @@
jws
libraries
- libraries-data
+ libraries-data
+ linkrest
log-mdc
log4j
log4j2
diff --git a/spring-all/src/main/java/org/baeldung/controller/controller/PassParametersController.java b/spring-all/src/main/java/org/baeldung/controller/controller/PassParametersController.java
index 54047cedf3..c282ae6a62 100644
--- a/spring-all/src/main/java/org/baeldung/controller/controller/PassParametersController.java
+++ b/spring-all/src/main/java/org/baeldung/controller/controller/PassParametersController.java
@@ -3,8 +3,7 @@ package org.baeldung.controller.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
/**
@@ -16,23 +15,23 @@ import org.springframework.web.servlet.ModelAndView;
*/
@Controller
public class PassParametersController {
- @RequestMapping(value = "/showViewPage", method = RequestMethod.GET)
+ @GetMapping("/showViewPage")
public String passParametersWithModel(Model model) {
model.addAttribute("message", "Baeldung");
return "viewPage";
}
- @RequestMapping(value = "/printViewPage", method = RequestMethod.GET)
+ @GetMapping("/printViewPage")
public String passParametersWithModelMap(ModelMap map) {
map.addAttribute("welcomeMessage", "welcome");
map.addAttribute("message", "Baeldung");
return "viewPage";
}
- @RequestMapping(value = "/goToViewPage", method = RequestMethod.GET)
+ @GetMapping("/goToViewPage")
public ModelAndView passParametersWithModelAndView() {
ModelAndView modelAndView = new ModelAndView("viewPage");
modelAndView.addObject("message", "Baeldung");
return modelAndView;
}
-}
\ No newline at end of file
+}
diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml
index e36f5265b2..44e72535f8 100644
--- a/spring-cloud/pom.xml
+++ b/spring-cloud/pom.xml
@@ -15,6 +15,7 @@
spring-cloud-ribbon-client
spring-cloud-rest
spring-cloud-zookeeper
+ spring-cloud-gateway
pom
diff --git a/spring-cloud/spring-cloud-gateway/README.MD b/spring-cloud/spring-cloud-gateway/README.MD
new file mode 100644
index 0000000000..48fbf41b8e
--- /dev/null
+++ b/spring-cloud/spring-cloud-gateway/README.MD
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Explore the new Spring Cloud Gateway](http://www.baeldung.com/spring-cloud-gateway)
diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml b/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml
new file mode 100644
index 0000000000..14cde4901a
--- /dev/null
+++ b/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml
@@ -0,0 +1,79 @@
+
+ 4.0.0
+
+ gateway-service
+ 1.0.0-SNAPSHOT
+ jar
+
+ Spring Cloud Gateway Service
+
+
+ com.baeldung.spring.cloud
+ spring-cloud-gateway
+ 1.0.0-SNAPSHOT
+ ..
+
+
+
+ 2.0.0.M2
+
+
+
+
+ org.springframework.boot
+ spring-boot-actuator
+ ${version}
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+ ${version}
+
+
+ org.springframework.cloud
+ spring-cloud-gateway-core
+ ${version}
+
+
+ org.springframework.cloud
+ spring-cloud-starter-eureka
+ ${version}
+
+
+ org.hibernate
+ hibernate-validator-cdi
+ 6.0.2.Final
+
+
+ javax.validation
+ validation-api
+ 2.0.0.Final
+
+
+ io.projectreactor.ipc
+ reactor-netty
+ 0.7.0.M1
+
+
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java b/spring-cloud/spring-cloud-gateway/gateway-service/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java
new file mode 100644
index 0000000000..4d5f61315f
--- /dev/null
+++ b/spring-cloud/spring-cloud-gateway/gateway-service/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java
@@ -0,0 +1,12 @@
+package com.baeldung.spring.cloud;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class GatewayApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(GatewayApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/src/main/resources/application.yml b/spring-cloud/spring-cloud-gateway/gateway-service/src/main/resources/application.yml
new file mode 100644
index 0000000000..8b981f8071
--- /dev/null
+++ b/spring-cloud/spring-cloud-gateway/gateway-service/src/main/resources/application.yml
@@ -0,0 +1,13 @@
+server:
+ port: 80
+spring:
+ cloud:
+ gateway:
+ routes:
+ - id: baeldung_route
+ uri: http://www.baeldung.com
+ predicates:
+ - Path=/baeldung
+management:
+ security:
+ enabled: false
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-gateway/pom.xml b/spring-cloud/spring-cloud-gateway/pom.xml
new file mode 100644
index 0000000000..095ca4ea31
--- /dev/null
+++ b/spring-cloud/spring-cloud-gateway/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+ com.baeldung.spring.cloud
+ spring-cloud-gateway
+ 1.0.0-SNAPSHOT
+
+ gateway-service
+
+ pom
+
+ Spring Cloud Gateway
+
+
+ com.baeldung.spring.cloud
+ spring-cloud
+ 1.0.0-SNAPSHOT
+ ..
+
+
+
+ UTF-8
+ 3.6.0
+ 1.4.2.RELEASE
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot-maven-plugin.version}
+
+
+
+
+
diff --git a/vavr/pom.xml b/vavr/pom.xml
index 53cd07ddf7..2efaf7fd8c 100644
--- a/vavr/pom.xml
+++ b/vavr/pom.xml
@@ -74,7 +74,7 @@
1.8
- 0.9.0
+ 0.9.1
4.12
3.0.0
diff --git a/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java b/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java
index 84621e3a68..437742c964 100644
--- a/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java
+++ b/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java
@@ -5,17 +5,23 @@ import static io.vavr.API.Case;
import static io.vavr.API.Match;
import static io.vavr.Predicates.exists;
import static io.vavr.Predicates.forAll;
-import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.CancellationException;
+import java.util.function.Consumer;
import java.util.function.Predicate;
import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.verification.VerificationModeFactory;
+import org.mockito.verification.Timeout;
+import io.vavr.Tuple;
+import io.vavr.Tuple2;
import io.vavr.collection.List;
import io.vavr.concurrent.Future;
+import io.vavr.control.Try;
public class FutureUnitTest {
@@ -26,8 +32,7 @@ public class FutureUnitTest {
public void givenFunctionReturnInteger_WhenCallWithFuture_ShouldReturnFunctionValue() {
Future future = Future.of(() -> 1);
- assertEquals(1, future.get()
- .intValue());
+ assertEquals(1, future.get().intValue());
}
@Test
@@ -57,33 +62,29 @@ public class FutureUnitTest {
@Test
public void givenFunction_WhenCallWithFutureAndRegisterConsumerForSuccess_ShouldCallConsumerToStoreValue() {
- final int[] store = new int[] { 0 };
Future future = Future.of(() -> 1);
- future.onSuccess(i -> {
- store[0] = i;
- });
- await().until(() -> store[0] == 1);
+ MockConsumer consumer = Mockito.mock(MockConsumer.class);
+ future.onSuccess(consumer);
+ Mockito.verify(consumer, new Timeout(1000, VerificationModeFactory.times(1))).accept(1);
}
@Test
public void givenFunctionThrowException_WhenCallWithFutureAndRegisterConsumerForFailer_ShouldCallConsumerToStoreException() {
- final Throwable[] store = new Throwable[] { null };
Future future = Future.of(() -> getResourceThrowException(""));
- future.onFailure(err -> store[0] = err);
- await().until(() -> RuntimeException.class.isInstance(store[0]));
+ MockThrowableConsumer consumer = Mockito.mock(MockThrowableConsumer.class);
+ future.onFailure(consumer);
+ Mockito.verify(consumer, new Timeout(1000, VerificationModeFactory.times(1))).accept(Mockito.any());
}
@Test
public void givenAFuture_WhenAddAndThenConsumer_ShouldCallConsumerWithResultOfFutureAction() {
- int[] store1 = new int[1];
- int[] store2 = new int[1];
+ MockTryConsumer consumer1 = Mockito.mock(MockTryConsumer.class);
+ MockTryConsumer consumer2 = Mockito.mock(MockTryConsumer.class);
Future future = Future.of(() -> 1);
- Future andThenFuture = future.andThen(i -> store1[0] = i.get() + 1)
- .andThen(i -> store2[0] = store1[0] + 1);
+ Future andThenFuture = future.andThen(consumer1).andThen(consumer2);
andThenFuture.await();
-
- assertEquals(2, store1[0]);
- assertEquals(3, store2[0]);
+ Mockito.verify(consumer1, VerificationModeFactory.times(1)).accept(Try.success(1));
+ Mockito.verify(consumer2, VerificationModeFactory.times(1)).accept(Try.success(1));
}
@Test
@@ -91,8 +92,7 @@ public class FutureUnitTest {
Future future = Future.failed(new RuntimeException());
Future future2 = future.orElse(Future.of(() -> 2));
- assertEquals(2, future2.get()
- .intValue());
+ assertEquals(2, future2.get().intValue());
}
@Test(expected = CancellationException.class)
@@ -124,17 +124,46 @@ public class FutureUnitTest {
Future future = Future.failed(new RuntimeException());
Future fallbackFuture = Future.of(() -> expectedResult);
Future futureResult = future.fallbackTo(fallbackFuture);
- futureResult.await();
assertEquals(expectedResult, futureResult.get());
}
+
+ @Test
+ public void givenAFuture_WhenTransformByAddingOne_ShouldReturn() {
+ Future