diff --git a/libraries/pom.xml b/libraries/pom.xml
index c5b386b6b0bd..15446975f39f 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -1,6 +1,6 @@
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
parent-modules
com.baeldung
@@ -487,7 +487,7 @@
vavr
${vavr.version}
-
+
com.squareup.retrofit2
@@ -503,7 +503,7 @@
com.squareup.retrofit2
adapter-rxjava
${retrofit.version}
-
+
com.squareup.okhttp3
logging-interceptor
@@ -596,6 +596,11 @@
jgrapht-core
1.0.1
+
+ com.netopyr.wurmloch
+ wurmloch-crdt
+ ${crdt.version}
+
@@ -617,6 +622,7 @@
+ 0.1.0
0.7.0
3.2.4
3.6
@@ -669,6 +675,6 @@
1.14
1.0.3
1.0.0
- 3.8.4
+ 3.8.4
diff --git a/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java b/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java
new file mode 100644
index 000000000000..8309e755ce95
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java
@@ -0,0 +1,153 @@
+package com.baeldung.crdt;
+
+import com.netopyr.wurmloch.crdt.GCounter;
+import com.netopyr.wurmloch.crdt.GSet;
+import com.netopyr.wurmloch.crdt.LWWRegister;
+import com.netopyr.wurmloch.crdt.PNCounter;
+import com.netopyr.wurmloch.store.LocalCrdtStore;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CRDTTest {
+
+ @Test
+ public void givenGrowOnlySet_whenTwoReplicasDiverge_thenShouldMergeItWithoutAConflict() {
+ //given
+ final LocalCrdtStore crdtStore1 = new LocalCrdtStore();
+ final LocalCrdtStore crdtStore2 = new LocalCrdtStore();
+ crdtStore1.connect(crdtStore2);
+
+ final GSet replica1 = crdtStore1.createGSet("ID_1");
+ final GSet replica2 = crdtStore2.findGSet("ID_1").get();
+
+ //when
+ replica1.add("apple");
+ replica2.add("banana");
+
+ //then
+ assertThat(replica1).contains("apple", "banana");
+ assertThat(replica2).contains("apple", "banana");
+
+ //when
+ crdtStore1.disconnect(crdtStore2);
+
+ replica1.add("strawberry");
+ replica2.add("pear");
+
+
+ assertThat(replica1).contains("apple", "banana", "strawberry");
+ assertThat(replica2).contains("apple", "banana", "pear");
+
+ crdtStore1.connect(crdtStore2);
+
+ //then
+ assertThat(replica1).contains("apple", "banana", "strawberry", "pear");
+ assertThat(replica2).contains("apple", "banana", "strawberry", "pear");
+ }
+
+ @Test
+ public void givenIncrementOnlyCounter_whenTwoReplicasDiverge_thenShouldMergeIt() {
+ //given
+ final LocalCrdtStore crdtStore1 = new LocalCrdtStore();
+ final LocalCrdtStore crdtStore2 = new LocalCrdtStore();
+ crdtStore1.connect(crdtStore2);
+
+ final GCounter replica1 = crdtStore1.createGCounter("ID_1");
+ final GCounter replica2 = crdtStore2.findGCounter("ID_1").get();
+
+ //when
+ replica1.increment();
+ replica2.increment(2L);
+
+ //then
+ assertThat(replica1.get()).isEqualTo(3L);
+ assertThat(replica2.get()).isEqualTo(3L);
+
+ //when
+ crdtStore1.disconnect(crdtStore2);
+
+ replica1.increment(3L);
+ replica2.increment(5L);
+
+
+ assertThat(replica1.get()).isEqualTo(6L);
+ assertThat(replica2.get()).isEqualTo(8L);
+
+ crdtStore1.connect(crdtStore2);
+
+ // then
+ assertThat(replica1.get()).isEqualTo(11L);
+ assertThat(replica2.get()).isEqualTo(11L);
+ }
+
+ @Test
+ public void givenPNCounter_whenReplicasDiverge_thenShouldMergeWithoutAConflict() {
+ // given
+ final LocalCrdtStore crdtStore1 = new LocalCrdtStore();
+ final LocalCrdtStore crdtStore2 = new LocalCrdtStore();
+ crdtStore1.connect(crdtStore2);
+
+ final PNCounter replica1 = crdtStore1.createPNCounter("ID_1");
+ final PNCounter replica2 = crdtStore2.findPNCounter("ID_1").get();
+
+ //when
+ replica1.increment();
+ replica2.decrement(2L);
+
+ //then
+ assertThat(replica1.get()).isEqualTo(-1L);
+ assertThat(replica2.get()).isEqualTo(-1L);
+
+ //when
+ crdtStore1.disconnect(crdtStore2);
+
+ replica1.decrement(3L);
+ replica2.increment(5L);
+
+ assertThat(replica1.get()).isEqualTo(-4L);
+ assertThat(replica2.get()).isEqualTo(4L);
+
+ crdtStore1.connect(crdtStore2);
+
+ //then
+ assertThat(replica1.get()).isEqualTo(1L);
+ assertThat(replica2.get()).isEqualTo(1L);
+ }
+
+ @Test
+ public void givenLastWriteWinsStrategy_whenReplicasDiverge_thenAfterMergeShouldKeepOnlyLastValue() {
+ //given
+ final LocalCrdtStore crdtStore1 = new LocalCrdtStore("N_1");
+ final LocalCrdtStore crdtStore2 = new LocalCrdtStore("N_2");
+ crdtStore1.connect(crdtStore2);
+
+ final LWWRegister replica1 = crdtStore1.createLWWRegister("ID_1");
+ final LWWRegister replica2 = crdtStore2.findLWWRegister("ID_1").get();
+
+ //when
+ replica1.set("apple");
+ replica2.set("banana");
+
+ // then
+ assertThat(replica1.get()).isEqualTo("banana");
+ assertThat(replica2.get()).isEqualTo("banana");
+
+
+ // when
+ crdtStore1.disconnect(crdtStore2);
+
+ replica1.set("strawberry");
+ replica2.set("pear");
+
+
+ assertThat(replica1.get()).isEqualTo("strawberry");
+ assertThat(replica2.get()).isEqualTo("pear");
+
+ crdtStore1.connect(crdtStore2);
+
+ //then
+ assertThat(replica1.get()).isEqualTo("pear");
+ assertThat(replica2.get()).isEqualTo("pear");
+ }
+}