http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java 
b/gossip-base/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java
new file mode 100644
index 0000000..8ae783e
--- /dev/null
+++ b/gossip-base/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip; 
+
+import io.teknek.tunit.TUnit;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import org.junit.platform.runner.JUnitPlatform;
+import org.junit.runner.RunWith;
+import org.apache.gossip.manager.GossipManager;
+import org.apache.gossip.manager.GossipManagerBuilder;
+import org.junit.jupiter.api.Test;
+
+@RunWith(JUnitPlatform.class)
+public class TenNodeThreeSeedTest {
+
+  @Test
+  public void test() throws UnknownHostException, InterruptedException, 
URISyntaxException {
+    abc(30150);
+  }
+
+  @Test
+  public void testAgain() throws UnknownHostException, InterruptedException, 
URISyntaxException {
+    abc(30100);
+  }
+
+  public void abc(int base) throws InterruptedException, UnknownHostException, 
URISyntaxException {
+    GossipSettings settings = new GossipSettings(1000, 10000, 1000, 1, 1.6, 
"exponential");
+    settings.setPersistRingState(false);
+    settings.setPersistDataState(false);
+    String cluster = UUID.randomUUID().toString();
+    int seedNodes = 3;
+    List<Member> startupMembers = new ArrayList<>();
+    for (int i = 1; i < seedNodes+1; ++i) {
+      URI uri = new URI("udp://" + "127.0.0.1" + ":" + (base + i));
+      startupMembers.add(new RemoteMember(cluster, uri, i + ""));
+    }
+    final List<GossipManager> clients = new ArrayList<>();
+    final int clusterMembers = 5;
+    for (int i = 1; i < clusterMembers+1; ++i) {
+      URI uri = new URI("udp://" + "127.0.0.1" + ":" + (base + i));
+      GossipManager gossipService = GossipManagerBuilder.newBuilder()
+              .cluster(cluster)
+              .uri(uri)
+              .id(i + "")
+              .gossipSettings(settings)
+              .gossipMembers(startupMembers)
+              .build();
+      gossipService.init();
+      clients.add(gossipService);
+    }    
+    TUnit.assertThat(new Callable<Integer> (){
+      public Integer call() throws Exception {
+        int total = 0;
+        for (int i = 0; i < clusterMembers; ++i) {
+          total += clients.get(i).getLiveMembers().size();
+        }
+        return total;
+      }}).afterWaitingAtMost(40, TimeUnit.SECONDS).isEqualTo(20);
+          
+    for (int i = 0; i < clusterMembers; ++i) {
+      int j = i;
+      new Thread(){
+        public void run(){
+          clients.get(j).shutdown();
+        }
+      }.start();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/accrual/FailureDetectorTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/accrual/FailureDetectorTest.java 
b/gossip-base/src/test/java/org/apache/gossip/accrual/FailureDetectorTest.java
new file mode 100644
index 0000000..3434c17
--- /dev/null
+++ 
b/gossip-base/src/test/java/org/apache/gossip/accrual/FailureDetectorTest.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.accrual;
+
+import org.apache.gossip.GossipSettings;
+import org.junit.Assert;
+import org.junit.jupiter.api.Test;
+import org.junit.platform.runner.JUnitPlatform;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+@RunWith(JUnitPlatform.class)
+public class FailureDetectorTest {
+
+  @FunctionalInterface
+  interface TriConsumer<A, B, C> {
+    void accept(A a, B b, C c);
+  }
+
+  static final Double failureThreshold = new 
GossipSettings().getConvictThreshold();
+
+  List<Integer> generateTimeList(int begin, int end, int step) {
+    List<Integer> values = new ArrayList<>();
+    Random rand = new Random();
+    for (int i = begin; i < end; i += step) {
+      int delta = (int) ((rand.nextDouble() - 0.5) * step / 2);
+
+      values.add(i + delta);
+    }
+    return values;
+  }
+
+  @Test
+  public void normalDistribution() {
+    FailureDetector fd = new FailureDetector(1, 1000, "normal");
+    List<Integer> values = generateTimeList(0, 10000, 100);
+    Double deltaSum = 0.0;
+    Integer deltaCount = 0;
+    for (int i = 0; i < values.size() - 1; i++) {
+      fd.recordHeartbeat(values.get(i));
+      if (i != 0) {
+        deltaSum += values.get(i) - values.get(i - 1);
+        deltaCount++;
+      }
+    }
+    Integer lastRecorded = values.get(values.size() - 2);
+
+    //after "step" delay we need to be considered UP
+    Assert.assertTrue(fd.computePhiMeasure(values.get(values.size() - 1)) < 
failureThreshold);
+
+    //if we check phi-measure after mean delay we get value for 0.5 
probability(normal distribution)
+    Assert.assertEquals(fd.computePhiMeasure(lastRecorded + 
Math.round(deltaSum / deltaCount)), -Math.log10(0.5), 0.1);
+  }
+
+  @Test
+  public void checkMinimumSamples() {
+    Integer minimumSamples = 5;
+    FailureDetector fd = new FailureDetector(minimumSamples, 1000, "normal");
+    for (int i = 0; i < minimumSamples + 1; i++) { // +1 because we don't 
place first heartbeat into structure
+      Assert.assertNull(fd.computePhiMeasure(100));
+      fd.recordHeartbeat(i);
+    }
+    Assert.assertNotNull(fd.computePhiMeasure(100));
+  }
+
+  @Test
+  public void checkMonotonicDead() {
+    final FailureDetector fd = new FailureDetector(5, 1000, "normal");
+    TriConsumer<Integer, Integer, Integer> checkAlive = (begin, end, step) -> {
+      List<Integer> times = generateTimeList(begin, end, step);
+      for (int i = 0; i < times.size(); i++) {
+        Double current = fd.computePhiMeasure(times.get(i));
+        if (current != null) {
+          Assert.assertTrue(current < failureThreshold);
+        }
+        fd.recordHeartbeat(times.get(i));
+      }
+    };
+
+    TriConsumer<Integer, Integer, Integer> checkDeadMonotonic = (begin, end, 
step) -> {
+      List<Integer> times = generateTimeList(begin, end, step);
+      Double prev = null;
+      for (int i = 0; i < times.size(); i++) {
+        Double current = fd.computePhiMeasure(times.get(i));
+        if (current != null && prev != null) {
+          Assert.assertTrue(current >= prev);
+        }
+        prev = current;
+      }
+    };
+
+    checkAlive.accept(0, 20000, 100);
+    checkDeadMonotonic.accept(20000, 20500, 5);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlyCounterTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlyCounterTest.java 
b/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlyCounterTest.java
new file mode 100644
index 0000000..3a134af
--- /dev/null
+++ b/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlyCounterTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.crdt;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class GrowOnlyCounterTest {
+  
+  @Test
+  public void mergeTest() {
+    
+    Map<String, Long> node1Counter = new HashMap<>();
+    node1Counter.put("1", 3L);
+    Map<String, Long> node2Counter = new HashMap<>();
+    node2Counter.put("2", 1L);
+    Map<String, Long> node3Counter = new HashMap<>();
+    node3Counter.put("3", 2L);
+    
+    GrowOnlyCounter gCounter1 = new GrowOnlyCounter(node1Counter);
+    GrowOnlyCounter gCounter2 = new GrowOnlyCounter(node2Counter);
+    GrowOnlyCounter gCounter3 = new GrowOnlyCounter(node3Counter);
+    
+    // After node 2 receive from node 1
+    gCounter2 = gCounter2.merge(gCounter1);
+    Assert.assertEquals(4, (long) gCounter2.value());
+    
+    // After node 3 receive from node 1
+    gCounter3 = gCounter3.merge(gCounter1);
+    Assert.assertEquals(5, (long) gCounter3.value());
+    
+    // After node 3 receive from node 2
+    gCounter3 = gCounter3.merge(gCounter2);
+    Assert.assertEquals(6, (long) gCounter3.value());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlySetTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlySetTest.java 
b/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlySetTest.java
new file mode 100644
index 0000000..d4f12b6
--- /dev/null
+++ b/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlySetTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.crdt;
+
+import java.util.Arrays;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class GrowOnlySetTest {
+
+  @SuppressWarnings("rawtypes")
+  @Test
+  public void mergeTest(){
+    ConcurrentHashMap<String, Crdt> a = new ConcurrentHashMap<>();
+    GrowOnlySet<String> gset = new GrowOnlySet<>(Arrays.asList("a", "b"));
+    Assert.assertEquals(gset, a.merge("a", gset, new CrdtBiFunctionMerge()));
+    GrowOnlySet<String> over = new GrowOnlySet<>(Arrays.asList("b", "d"));
+    Assert.assertEquals(new GrowOnlySet<>(Arrays.asList("a", "b", "d")), 
+            a.merge("a", over, CrdtBiFunctionMerge::applyStatic));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/crdt/OrSetTest.java
----------------------------------------------------------------------
diff --git a/gossip-base/src/test/java/org/apache/gossip/crdt/OrSetTest.java 
b/gossip-base/src/test/java/org/apache/gossip/crdt/OrSetTest.java
new file mode 100644
index 0000000..b19f221
--- /dev/null
+++ b/gossip-base/src/test/java/org/apache/gossip/crdt/OrSetTest.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.crdt;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.gossip.GossipSettings;
+import org.apache.gossip.manager.GossipManager;
+import org.apache.gossip.manager.GossipManagerBuilder;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class OrSetTest {
+
+  @Test
+  public void atest() {
+    OrSet<Integer> i = new OrSet<>(new 
OrSet.Builder<Integer>().add(4).add(5).add(6).remove(5));
+    Assert.assertArrayEquals(Arrays.asList(4, 6).toArray(), 
i.value().toArray());
+  }
+    
+  @Test
+  public void mergeTest(){
+    OrSet<Integer> i = new OrSet<>(new 
OrSet.Builder<Integer>().add(4).add(5).add(6).remove(5));
+    Assert.assertArrayEquals(Arrays.asList(4, 6).toArray(), 
i.value().toArray());
+    OrSet<Integer> j = new OrSet<>(new 
OrSet.Builder<Integer>().add(9).add(4).add(5).remove(6));
+    OrSet<Integer> h = i.merge(j);
+    Assert.assertEquals(new OrSet<Integer>(4,6,9,5), h);
+  }
+  
+  @Test
+  public void mergeTest2(){
+    OrSet<Integer> i = new OrSet<>(new 
OrSet.Builder<Integer>().add(5).add(4).remove(4).add(6));
+    Assert.assertEquals(new OrSet<Integer>(5,6), i);
+    SortedSet<Integer> tree = new TreeSet<>();
+    for (Integer in: i.value()){
+      tree.add(in);
+    }
+    TreeSet<Integer> compare = new TreeSet<>();
+    compare.add(5);
+    compare.add(6);
+    Assert.assertEquals(tree, compare);
+  }
+  
+  @Test
+  public void mergeTest4() {
+    Assert.assertArrayEquals(new Integer[] {},
+            new OrSet<Integer>(new 
OrSet.Builder<Integer>().add(1).remove(1)).toArray());
+  }
+  
+  @Test
+  public void mergeTest3(){
+    OrSet<Integer> i = new OrSet<>(1);
+    OrSet<Integer> j = new OrSet<>(2);
+    OrSet<Integer> k = new OrSet<>(i.merge(j),  new 
OrSet.Builder<Integer>().remove(1));
+    Assert.assertArrayEquals(new Integer[] { 2 }, 
i.merge(j).merge(k).toArray());
+    Assert.assertArrayEquals(new Integer[] { 2 }, 
j.merge(i).merge(k).toArray());
+    Assert.assertArrayEquals(new Integer[] { 2 }, 
k.merge(i).merge(j).toArray());
+    Assert.assertArrayEquals(new Integer[] { 2 }, 
k.merge(j).merge(i).toArray());
+    Assert.assertEquals(j , i.merge(j.merge(k)));
+  }
+  
+  @Test
+  public void mergeTest9(){
+    OrSet<Integer> i = new OrSet<>(19);
+    OrSet<Integer> j = i.merge(i);
+    Assert.assertEquals(i.value(), j.value());
+  }
+  
+  @Test
+  public void serialTest() throws InterruptedException, URISyntaxException, 
IOException {
+    GossipManager gossipService2 = GossipManagerBuilder.newBuilder()
+            .cluster("a")
+            .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
+            .id("1")
+            .gossipSettings(new GossipSettings())
+            .build();
+    OrSet<Integer> i = new OrSet<Integer>(new 
OrSet.Builder<Integer>().add(1).remove(1));
+    String s = gossipService2.getObjectMapper().writeValueAsString(i);
+    @SuppressWarnings("unchecked")
+    OrSet<Integer> back = gossipService2.getObjectMapper().readValue(s, 
OrSet.class);
+    Assert.assertEquals(back, i);
+  }
+  
+  @Test
+  public void mergeTestSame() {
+    OrSet<Integer> i = new OrSet<>(19);
+    OrSet<Integer> j = new OrSet<>(19);
+    OrSet<Integer> k = i.merge(j);
+    Assert.assertEquals(2, k.getElements().get(19).size());
+    OrSet<Integer> y = new OrSet<>(k, new OrSet.Builder<Integer>().remove(19));
+    Assert.assertEquals(2, y.getTombstones().get(19).size());
+    Assert.assertEquals(2, y.getElements().get(19).size());
+    Assert.assertEquals(new OrSet<Integer>().value(), y.value());
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/manager/DataReaperTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/manager/DataReaperTest.java 
b/gossip-base/src/test/java/org/apache/gossip/manager/DataReaperTest.java
new file mode 100644
index 0000000..e328c24
--- /dev/null
+++ b/gossip-base/src/test/java/org/apache/gossip/manager/DataReaperTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.manager;
+
+import com.codahale.metrics.MetricRegistry;
+import java.net.URI;
+
+import org.apache.gossip.GossipSettings;
+import org.apache.gossip.model.PerNodeDataMessage;
+import org.apache.gossip.model.SharedDataMessage;
+import org.junit.Assert;
+import org.junit.Test;
+
+import io.teknek.tunit.TUnit;
+
+public class DataReaperTest {
+
+  private final MetricRegistry registry = new MetricRegistry();
+  String myId = "4";
+  String key = "key";
+  String value = "a";
+  
+  @Test
+  public void testReaperOneShot() {
+    GossipSettings settings = new GossipSettings();
+    settings.setPersistRingState(false);
+    settings.setPersistDataState(false);
+    GossipManager gm = 
GossipManagerBuilder.newBuilder().cluster("abc").gossipSettings(settings)
+            
.id(myId).uri(URI.create("udp://localhost:6000")).registry(registry).build();
+    gm.init();
+    gm.gossipPerNodeData(perNodeDatum(key, value));
+    gm.gossipSharedData(sharedDatum(key, value));
+    assertDataIsAtCorrectValue(gm);
+    gm.getDataReaper().runPerNodeOnce();
+    gm.getDataReaper().runSharedOnce();
+    assertDataIsRemoved(gm);
+    gm.shutdown();
+  }
+
+  private void assertDataIsAtCorrectValue(GossipManager gm){
+    Assert.assertEquals(value, gm.findPerNodeGossipData(myId, 
key).getPayload());
+    Assert.assertEquals(1, 
registry.getGauges().get(GossipCoreConstants.PER_NODE_DATA_SIZE).getValue());
+    Assert.assertEquals(value, gm.findSharedGossipData(key).getPayload());
+    Assert.assertEquals(1, 
registry.getGauges().get(GossipCoreConstants.SHARED_DATA_SIZE).getValue());
+  }
+  
+  private void assertDataIsRemoved(GossipManager gm){
+    TUnit.assertThat(() -> gm.findPerNodeGossipData(myId, key)).equals(null);
+    TUnit.assertThat(() -> gm.findSharedGossipData(key)).equals(null);
+  }
+  
+  private PerNodeDataMessage perNodeDatum(String key, String value) {
+    PerNodeDataMessage m = new PerNodeDataMessage();
+    m.setExpireAt(System.currentTimeMillis() + 5L);
+    m.setKey(key);
+    m.setPayload(value);
+    m.setTimestamp(System.currentTimeMillis());
+    return m;
+  }
+  
+  private SharedDataMessage sharedDatum(String key, String value) {
+    SharedDataMessage m = new SharedDataMessage();
+    m.setExpireAt(System.currentTimeMillis() + 5L);
+    m.setKey(key);
+    m.setPayload(value);
+    m.setTimestamp(System.currentTimeMillis());
+    return m;
+  }
+  
+  @Test
+  public void testHigherTimestampWins() {
+    String myId = "4";
+    String key = "key";
+    String value = "a";
+    GossipSettings settings = new GossipSettings();
+    GossipManager gm = 
GossipManagerBuilder.newBuilder().cluster("abc").gossipSettings(settings)
+            
.id(myId).uri(URI.create("udp://localhost:7000")).registry(registry).build();
+    gm.init();
+    PerNodeDataMessage before = perNodeDatum(key, value);
+    PerNodeDataMessage after = perNodeDatum(key, "b");
+    after.setTimestamp(after.getTimestamp() - 1);
+    gm.gossipPerNodeData(before);
+    Assert.assertEquals(value, gm.findPerNodeGossipData(myId, 
key).getPayload());
+    gm.gossipPerNodeData(after);
+    Assert.assertEquals(value, gm.findPerNodeGossipData(myId, 
key).getPayload());
+    gm.shutdown();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/manager/GossipManagerBuilderTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/manager/GossipManagerBuilderTest.java
 
b/gossip-base/src/test/java/org/apache/gossip/manager/GossipManagerBuilderTest.java
new file mode 100644
index 0000000..8842643
--- /dev/null
+++ 
b/gossip-base/src/test/java/org/apache/gossip/manager/GossipManagerBuilderTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.manager;
+
+import com.codahale.metrics.MetricRegistry;
+import org.apache.gossip.Member;
+import org.apache.gossip.GossipSettings;
+import org.apache.gossip.LocalMember;
+import org.apache.gossip.manager.handlers.DefaultMessageInvoker;
+import org.apache.gossip.manager.handlers.MessageInvoker;
+import org.apache.gossip.manager.handlers.ResponseHandler;
+import org.apache.gossip.manager.handlers.SimpleMessageInvoker;
+import org.junit.Assert;
+import org.junit.jupiter.api.Test;
+import org.junit.platform.runner.JUnitPlatform;
+import org.junit.runner.RunWith;
+
+import javax.xml.ws.Response;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.expectThrows;
+
+@RunWith(JUnitPlatform.class)
+public class GossipManagerBuilderTest {
+
+  @Test
+  public void idShouldNotBeNull() {
+    expectThrows(IllegalArgumentException.class,() -> {
+        GossipManagerBuilder.newBuilder().cluster("aCluster").build();
+    });
+  }
+
+  @Test
+  public void clusterShouldNotBeNull() {
+      expectThrows(IllegalArgumentException.class,() -> {
+          GossipManagerBuilder.newBuilder().id("id").build();
+      });
+  }
+
+  @Test
+  public void settingsShouldNotBeNull() {
+      expectThrows(IllegalArgumentException.class,() -> {
+          
GossipManagerBuilder.newBuilder().id("id").cluster("aCluster").build();
+      });
+  }
+  
+  @Test
+  public void createMembersListIfNull() throws URISyntaxException {
+    GossipManager gossipManager = GossipManagerBuilder.newBuilder()
+        .id("id")
+        .cluster("aCluster")
+        .uri(new URI("udp://localhost:2000"))
+        .gossipSettings(new GossipSettings())
+        .gossipMembers(null).registry(new MetricRegistry()).build();
+    assertNotNull(gossipManager.getLiveMembers());
+  }
+
+  @Test
+  public void createDefaultMessageInvokerIfNull() throws URISyntaxException {
+    GossipManager gossipManager = GossipManagerBuilder.newBuilder()
+        .id("id")
+        .cluster("aCluster")
+        .uri(new URI("udp://localhost:2000"))
+        .gossipSettings(new GossipSettings())
+        .messageInvoker(null).registry(new MetricRegistry()).build();
+    assertNotNull(gossipManager.getMessageInvoker());
+    Assert.assertEquals(gossipManager.getMessageInvoker().getClass(), new 
DefaultMessageInvoker().getClass());
+  }
+
+  @Test
+  public void testMessageInvokerKeeping() throws URISyntaxException {
+    MessageInvoker mi = new SimpleMessageInvoker(Response.class, new 
ResponseHandler());
+    GossipManager gossipManager = GossipManagerBuilder.newBuilder()
+        .id("id")
+        .cluster("aCluster")
+        .uri(new URI("udp://localhost:2000"))
+        .gossipSettings(new GossipSettings())
+        .messageInvoker(mi).registry(new MetricRegistry()).build();
+    assertNotNull(gossipManager.getMessageInvoker());
+    Assert.assertEquals(gossipManager.getMessageInvoker(), mi);
+  }
+
+  @Test
+  public void useMemberListIfProvided() throws URISyntaxException {
+    LocalMember member = new LocalMember(
+            "aCluster", new URI("udp://localhost:2000"), "aGossipMember",
+            System.nanoTime(), new HashMap<String, String>(), 1000, 1, 
"exponential");
+    List<Member> memberList = new ArrayList<>();
+    memberList.add(member);
+    GossipManager gossipManager = GossipManagerBuilder.newBuilder()
+        .id("id")
+        .cluster("aCluster")
+        .gossipSettings(new GossipSettings())
+        .uri(new URI("udp://localhost:8000"))
+        .gossipMembers(memberList).registry(new MetricRegistry()).build();
+    assertEquals(1, gossipManager.getDeadMembers().size());
+    assertEquals(member.getId(), 
gossipManager.getDeadMembers().get(0).getId());
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/manager/RingPersistenceTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/manager/RingPersistenceTest.java 
b/gossip-base/src/test/java/org/apache/gossip/manager/RingPersistenceTest.java
new file mode 100644
index 0000000..d448b98
--- /dev/null
+++ 
b/gossip-base/src/test/java/org/apache/gossip/manager/RingPersistenceTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.manager;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import org.apache.gossip.GossipSettings;
+import org.apache.gossip.RemoteMember;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RingPersistenceTest {
+
+  @Test
+  public void givenThatRingIsPersisted() throws UnknownHostException, 
InterruptedException, URISyntaxException {
+    GossipSettings settings = new GossipSettings();
+    File f = aGossiperPersists(settings);
+    Assert.assertTrue(f.exists());
+    aNewInstanceGetsRingInfo(settings);
+    f.delete();
+  }
+  
+  private File aGossiperPersists(GossipSettings settings) throws 
UnknownHostException, InterruptedException, URISyntaxException {
+    GossipManager gossipService = GossipManagerBuilder.newBuilder()
+            .cluster("a")
+            .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
+            .id("1")
+            .gossipSettings(settings)
+            .gossipMembers(
+                    Arrays.asList(
+                            new RemoteMember("a", new URI("udp://" + 
"127.0.0.1" + ":" + (29000 + 0)), "0"),
+                            new RemoteMember("a", new URI("udp://" + 
"127.0.0.1" + ":" + (29000 + 2)), "2"))).build();
+    gossipService.getRingState().writeToDisk();
+    return gossipService.getRingState().computeTarget();
+  }
+  
+  private void aNewInstanceGetsRingInfo(GossipSettings settings) throws 
UnknownHostException, InterruptedException, URISyntaxException {
+    GossipManager gossipService2 = GossipManagerBuilder.newBuilder()
+            .cluster("a")
+            .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
+            .id("1")
+            .gossipSettings(settings).build();
+    Assert.assertEquals(2, gossipService2.getMembers().size());
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/manager/UserDataPersistenceTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/manager/UserDataPersistenceTest.java
 
b/gossip-base/src/test/java/org/apache/gossip/manager/UserDataPersistenceTest.java
new file mode 100644
index 0000000..7b17e41
--- /dev/null
+++ 
b/gossip-base/src/test/java/org/apache/gossip/manager/UserDataPersistenceTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.manager;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.gossip.GossipSettings;
+import org.apache.gossip.model.PerNodeDataMessage;
+import org.apache.gossip.model.SharedDataMessage;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class UserDataPersistenceTest {
+
+  String nodeId = "1";
+  
+  private GossipManager sameService() throws URISyntaxException {  
+    GossipSettings settings = new GossipSettings();
+    return GossipManagerBuilder.newBuilder()
+            .cluster("a")
+            .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
+            .id(nodeId)
+            .gossipSettings(settings).build();
+  }
+  
+  @Test
+  public void givenThatRingIsPersisted() throws UnknownHostException, 
InterruptedException, URISyntaxException {
+    
+    { //Create a gossip service and force it to persist its user data
+      GossipManager gossipService = sameService();
+      gossipService.init();
+      gossipService.gossipPerNodeData(getToothpick());
+      gossipService.gossipSharedData(getAnotherToothpick());
+      gossipService.getUserDataState().writePerNodeToDisk();
+      gossipService.getUserDataState().writeSharedToDisk();
+      { //read the raw data and confirm
+        ConcurrentHashMap<String, ConcurrentHashMap<String, 
PerNodeDataMessage>> l = gossipService.getUserDataState().readPerNodeFromDisk();
+        Assert.assertEquals("red", ((AToothpick) 
l.get(nodeId).get("a").getPayload()).getColor());
+      }
+      {
+        ConcurrentHashMap<String, SharedDataMessage> l = 
+                gossipService.getUserDataState().readSharedDataFromDisk();
+        Assert.assertEquals("blue", ((AToothpick) 
l.get("a").getPayload()).getColor());
+      }
+      gossipService.shutdown();
+    }
+    { //recreate the service and see that the data is read back in
+      GossipManager gossipService = sameService();
+      gossipService.init();
+      Assert.assertEquals("red", ((AToothpick) 
gossipService.findPerNodeGossipData(nodeId, "a").getPayload()).getColor());
+      Assert.assertEquals("blue", ((AToothpick) 
gossipService.findSharedGossipData("a").getPayload()).getColor());
+      File f = gossipService.getUserDataState().computeSharedTarget();
+      File g = gossipService.getUserDataState().computePerNodeTarget();
+      gossipService.shutdown();
+      f.delete();
+      g.delete();
+    }
+  }
+  
+  public PerNodeDataMessage getToothpick(){
+    AToothpick a = new AToothpick();
+    a.setColor("red");
+    PerNodeDataMessage d = new PerNodeDataMessage();
+    d.setExpireAt(Long.MAX_VALUE);
+    d.setKey("a");
+    d.setPayload(a);
+    d.setTimestamp(System.currentTimeMillis());
+    return d;
+  }
+  
+  public SharedDataMessage getAnotherToothpick(){
+    AToothpick a = new AToothpick();
+    a.setColor("blue");
+    SharedDataMessage d = new SharedDataMessage();
+    d.setExpireAt(Long.MAX_VALUE);
+    d.setKey("a");
+    d.setPayload(a);
+    d.setTimestamp(System.currentTimeMillis());
+    return d;
+  }
+  
+  public static class AToothpick {
+    private String color;
+    public AToothpick(){
+      
+    }
+    public String getColor() {
+      return color;
+    }
+    public void setColor(String color) {
+      this.color = color;
+    }
+    
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/java/org/apache/gossip/manager/handlers/MessageInvokerTest.java
----------------------------------------------------------------------
diff --git 
a/gossip-base/src/test/java/org/apache/gossip/manager/handlers/MessageInvokerTest.java
 
b/gossip-base/src/test/java/org/apache/gossip/manager/handlers/MessageInvokerTest.java
new file mode 100644
index 0000000..571d7ba
--- /dev/null
+++ 
b/gossip-base/src/test/java/org/apache/gossip/manager/handlers/MessageInvokerTest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gossip.manager.handlers;
+
+import org.apache.gossip.manager.GossipCore;
+import org.apache.gossip.manager.GossipManager;
+import org.apache.gossip.model.ActiveGossipMessage;
+import org.apache.gossip.model.Base;
+import org.apache.gossip.udp.UdpSharedDataMessage;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MessageInvokerTest {
+  private class FakeMessage extends Base {
+    public FakeMessage() {
+    }
+  }
+
+  private class FakeMessageData extends Base {
+    public int data;
+
+    public FakeMessageData(int data) {
+      this.data = data;
+    }
+  }
+
+  private class FakeMessageDataHandler implements MessageHandler {
+    public int data;
+
+    public FakeMessageDataHandler() {
+      data = 0;
+    }
+
+    public void invoke(GossipCore gossipCore, GossipManager gossipManager, 
Base base) {
+      data = ((FakeMessageData) base).data;
+    }
+  }
+
+  private class FakeMessageHandler implements MessageHandler {
+    public int counter;
+
+    public FakeMessageHandler() {
+      counter = 0;
+    }
+
+    public void invoke(GossipCore gossipCore, GossipManager gossipManager, 
Base base) {
+      counter++;
+    }
+  }
+
+  @Test
+  public void testSimpleInvoker() {
+    MessageInvoker mi = new SimpleMessageInvoker(FakeMessage.class, new 
FakeMessageHandler());
+    Assert.assertTrue(mi.invoke(null, null, new FakeMessage()));
+    Assert.assertFalse(mi.invoke(null, null, new ActiveGossipMessage()));
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void testSimpleInvokerNullClassConstructor() {
+    new SimpleMessageInvoker(null, new FakeMessageHandler());
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void testSimpleInvokerNullHandlerConstructor() {
+    new SimpleMessageInvoker(FakeMessage.class, null);
+  }
+
+  @Test
+  public void testCallCountSimpleInvoker() {
+    FakeMessageHandler h = new FakeMessageHandler();
+    MessageInvoker mi = new SimpleMessageInvoker(FakeMessage.class, h);
+    mi.invoke(null, null, new FakeMessage());
+    Assert.assertEquals(1, h.counter);
+    mi.invoke(null, null, new ActiveGossipMessage());
+    Assert.assertEquals(1, h.counter);
+    mi.invoke(null, null, new FakeMessage());
+    Assert.assertEquals(2, h.counter);
+  }
+
+  @Test(expected = NullPointerException.class)
+  public void cantAddNullInvoker() {
+    MessageInvokerCombiner mi = new MessageInvokerCombiner();
+    mi.add(null);
+  }
+
+  @Test
+  public void testCombinerClear() {
+    MessageInvokerCombiner mi = new MessageInvokerCombiner();
+    mi.add(new SimpleMessageInvoker(FakeMessage.class, new 
FakeMessageHandler()));
+    Assert.assertTrue(mi.invoke(null, null, new FakeMessage()));
+
+    mi.clear();
+    Assert.assertFalse(mi.invoke(null, null, new FakeMessage()));
+  }
+
+  @Test
+  public void testMessageInvokerCombiner() {
+    //Empty combiner - false result
+    MessageInvokerCombiner mi = new MessageInvokerCombiner();
+    Assert.assertFalse(mi.invoke(null, null, new Base()));
+
+    FakeMessageHandler h = new FakeMessageHandler();
+    mi.add(new SimpleMessageInvoker(FakeMessage.class, h));
+    mi.add(new SimpleMessageInvoker(FakeMessage.class, h));
+
+    Assert.assertTrue(mi.invoke(null, null, new FakeMessage()));
+    Assert.assertFalse(mi.invoke(null, null, new ActiveGossipMessage()));
+    Assert.assertEquals(2, h.counter);
+
+    //Increase size in runtime. Should be 3 calls: 2+3 = 5
+    mi.add(new SimpleMessageInvoker(FakeMessage.class, h));
+    Assert.assertTrue(mi.invoke(null, null, new FakeMessage()));
+    Assert.assertEquals(5, h.counter);
+  }
+
+  @Test
+  public void testMessageInvokerCombiner2levels() {
+    MessageInvokerCombiner mi = new MessageInvokerCombiner();
+    FakeMessageHandler h = new FakeMessageHandler();
+
+    MessageInvokerCombiner mi1 = new MessageInvokerCombiner();
+    mi1.add(new SimpleMessageInvoker(FakeMessage.class, h));
+    mi1.add(new SimpleMessageInvoker(FakeMessage.class, h));
+
+    MessageInvokerCombiner mi2 = new MessageInvokerCombiner();
+    mi2.add(new SimpleMessageInvoker(FakeMessage.class, h));
+    mi2.add(new SimpleMessageInvoker(FakeMessage.class, h));
+
+    mi.add(mi1);
+    mi.add(mi2);
+
+    Assert.assertTrue(mi.invoke(null, null, new FakeMessage()));
+    Assert.assertEquals(4, h.counter);
+  }
+
+  @Test
+  public void testMessageInvokerCombinerDataShipping() {
+    MessageInvokerCombiner mi = new MessageInvokerCombiner();
+    FakeMessageDataHandler h = new FakeMessageDataHandler();
+    mi.add(new SimpleMessageInvoker(FakeMessageData.class, h));
+
+    Assert.assertTrue(mi.invoke(null, null, new FakeMessageData(101)));
+    Assert.assertEquals(101, h.data);
+  }
+
+  @Test
+  public void testCombiningDefaultInvoker() {
+    MessageInvokerCombiner mi = new MessageInvokerCombiner();
+    mi.add(new DefaultMessageInvoker());
+    mi.add(new SimpleMessageInvoker(FakeMessage.class, new 
FakeMessageHandler()));
+    //UdpSharedGossipDataMessage with null gossipCore -> exception
+    boolean thrown = false;
+    try {
+      mi.invoke(null, null, new UdpSharedDataMessage());
+    } catch (NullPointerException e) {
+      thrown = true;
+    }
+    Assert.assertTrue(thrown);
+    //DefaultInvoker skips FakeMessage and FakeHandler works ok
+    Assert.assertTrue(mi.invoke(null, null, new FakeMessage()));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/gossip-base/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/gossip-base/src/test/resources/log4j.properties 
b/gossip-base/src/test/resources/log4j.properties
new file mode 100644
index 0000000..e2a60e1
--- /dev/null
+++ b/gossip-base/src/test/resources/log4j.properties
@@ -0,0 +1,20 @@
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+log4j.rootLogger=INFO,stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%5p %d{HH:mm:ss,SSS} %m%n
+
+log4j.logger.io.teknek=DEBUG
+log4j.logger.com.google.code.gossip=INFO

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 827f914..f9c7814 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,25 +19,11 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
        <modelVersion>4.0.0</modelVersion>
        
-       <parent>
-               <groupId>org.apache</groupId>
-               <artifactId>apache</artifactId>
-               <version>RELEASE</version>
-       </parent>
-       
-       <groupId>org.apache.gossip</groupId>
-       <artifactId>gossip</artifactId>
-       <name>gossip</name>
-       <version>0.1.3-incubating-SNAPSHOT</version>
-       <packaging>jar</packaging>
-       <description>A peer to peer cluster discovery service</description>
-       <url>http://gossip.incubator.apache.org/</url>
-
        <properties>
                
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <java.version>1.8</java.version>
                
-               <!-- dependecy versions -->
+               <!-- dependency versions -->
                <jackson.version>2.8.5</jackson.version>
                <metrics.version>3.1.2</metrics.version>
                <commons-math.version>1.2</commons-math.version>
@@ -55,6 +41,26 @@
                
<maven-dependency-plugin.version>2.10</maven-dependency-plugin.version>
        </properties>
        
+       <parent>
+               <groupId>org.apache</groupId>
+               <artifactId>apache</artifactId>
+               <version>RELEASE</version>
+       </parent>
+  
+  <name>Gossip Parent</name>
+  <groupId>org.apache.gossip</groupId>
+       <artifactId>gossip-parent</artifactId>
+       <version>0.1.3-incubating-SNAPSHOT</version>
+       
+       <packaging>pom</packaging>
+       
+       <modules>
+               <module>gossip-base</module>
+       </modules>
+       
+       <description>A peer to peer cluster discovery service</description>
+       <url>http://gossip.incubator.apache.org/</url>
+
        <licenses>
                <license>
                        <name>The Apache Software License, Version 2.0</name>
@@ -75,96 +81,23 @@
                <url>https://issues.apache.org/jira/browse/GOSSIP</url>
        </issueManagement>
        
-       <dependencies>
-               <dependency>
-                       <groupId>com.fasterxml.jackson.core</groupId>
-                       <artifactId>jackson-core</artifactId>
-                       <version>${jackson.version}</version>
-               </dependency>
-               <dependency>
-                       <groupId>commons-math</groupId>
-                       <artifactId>commons-math</artifactId>
-                       <version>${commons-math.version}</version>
-               </dependency> 
-               <dependency>
-                       <groupId>com.fasterxml.jackson.core</groupId>
-                       <artifactId>jackson-databind</artifactId>
-                       <version>${jackson.version}</version>
-               </dependency>
-               <dependency>
-                       <groupId>io.dropwizard.metrics</groupId>
-                       <artifactId>metrics-core</artifactId>
-                       <version>${metrics.version}</version></dependency>
-               <dependency>
-                       <groupId>org.junit.jupiter</groupId>
-                       <artifactId>junit-jupiter-api</artifactId>
-                       <version>${junit.jupiter.version}</version>
-                       <scope>test</scope>
-               </dependency>
-               <dependency>
-                       <groupId>org.junit.jupiter</groupId>
-                       <artifactId>junit-jupiter-engine</artifactId>
-                       <version>${junit.jupiter.version}</version>
-                       <scope>test</scope>
-               </dependency>
-               <dependency>
-                       <groupId>org.junit.vintage</groupId>
-                       <artifactId>junit-vintage-engine</artifactId>
-                       <version>${junit.vintage.version}</version>
-                       <scope>test</scope>
-               </dependency>
-               <dependency>
-                       <groupId>org.junit.platform</groupId>
-                       <artifactId>junit-platform-runner</artifactId>
-                       <version>${junit.platform.version}</version>
-                       <scope>test</scope>
-               </dependency>
-               <dependency>
-                       <groupId>io.teknek</groupId>
-                       <artifactId>tunit</artifactId>
-                       <version>${tunit.version}</version>
-                       <scope>test</scope>
-               </dependency>
-               <dependency>
-                       <groupId>log4j</groupId>
-                       <artifactId>log4j</artifactId>
-                       <version>${log4j.version}</version>
-                       <type>jar</type>
-                       <scope>compile</scope>
-                       <exclusions>
-                               <exclusion>
-                                       <groupId>javax.jms</groupId>
-                                       <artifactId>jms</artifactId>
-                               </exclusion>
-                               <exclusion>
-                                       <groupId>com.sun.jdmk</groupId>
-                                       <artifactId>jmxtools</artifactId>
-                               </exclusion>
-                               <exclusion>
-                                       <groupId>com.sun.jmx</groupId>
-                                       <artifactId>jmxri</artifactId>
-                               </exclusion>
-                       </exclusions>
-               </dependency>
-       </dependencies>
-       
        <build>
                <pluginManagement>
                        <plugins>
-                                       <!-- we need to tweak the 
maven-release-plugin for GIT -->
-                                       <plugin>
-                                               
<groupId>org.apache.maven.plugins</groupId>
-                                               
<artifactId>maven-release-plugin</artifactId>
-                                               <version>2.5.1</version>
-                                               <configuration>
-                                                       
<pushChanges>false</pushChanges>
-                                                       
<localCheckout>true</localCheckout>
-                                                       
<autoVersionSubmodules>true</autoVersionSubmodules>
+                               <!-- we need to tweak the maven-release-plugin 
for GIT -->
+                               <plugin>
+                                       
<groupId>org.apache.maven.plugins</groupId>
+                                       
<artifactId>maven-release-plugin</artifactId>
+                                       <version>2.5.1</version>
+                                       <configuration>
+                                               <pushChanges>false</pushChanges>
+                                               
<localCheckout>true</localCheckout>
+                                               
<autoVersionSubmodules>true</autoVersionSubmodules>
 
-                                                       
<releaseProfiles>distribution</releaseProfiles>
-                                                       <preparationGoals>clean 
install</preparationGoals>
-                                               </configuration>
-                                       </plugin>
+                                               
<releaseProfiles>distribution</releaseProfiles>
+                                               <preparationGoals>clean 
install</preparationGoals>
+                                       </configuration>
+                               </plugin>
                                <plugin>
                                        
<groupId>org.apache.maven.plugins</groupId>
                                        
<artifactId>maven-jar-plugin</artifactId>
@@ -197,49 +130,49 @@
                        </plugins>
                </pluginManagement>
                <plugins>
-                       <plugin>
-                               <artifactId>maven-compiler-plugin</artifactId>
-                               <version>3.1</version>
-                               <configuration>
-                                       <source>${java.version}</source>
-                                       <target>${java.version}</target>
-                               </configuration>
-                       </plugin>
-                       <plugin>
-                               <artifactId>maven-surefire-plugin</artifactId>
-                               <version>2.19.1</version>
-                    <configuration>
-                      <systemPropertyVariables>
-                        
<java.io.tmpdir>${project.build.directory}</java.io.tmpdir>
-                      </systemPropertyVariables>
-                    </configuration>
-                               <dependencies>
-                                       <dependency>
-                                               
<groupId>org.junit.platform</groupId>
-                                               
<artifactId>junit-platform-surefire-provider</artifactId>
-                                               
<version>${junit.platform.version}</version>
-                                       </dependency>
-                               </dependencies>
-                       </plugin>
                        <plugin>
-                               <groupId>org.apache.rat</groupId>
-                               <artifactId>apache-rat-plugin</artifactId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                               <version>3.1</version>
+                               <configuration>
+                                       <source>${java.version}</source>
+                                       <target>${java.version}</target>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <artifactId>maven-surefire-plugin</artifactId>
+                               <version>2.19.1</version>
+                               <configuration>
+                                       <systemPropertyVariables>
+                                               
<java.io.tmpdir>${project.build.directory}</java.io.tmpdir>
+                                       </systemPropertyVariables>
+                               </configuration>
+                               <dependencies>
+                                       <dependency>
+                                               
<groupId>org.junit.platform</groupId>
+                                               
<artifactId>junit-platform-surefire-provider</artifactId>
+                                               
<version>${junit.platform.version}</version>
+                                       </dependency>
+                               </dependencies>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.rat</groupId>
+                               <artifactId>apache-rat-plugin</artifactId>
                                <configuration>
                                        <excludes>
                                                <exclude>README.md</exclude>
                                                
<exclude>eclipse_template.xml</exclude>
                                        </excludes>
                                </configuration>
-                               <executions>
-                                       <execution>
-                                               <phase>verify</phase>
-                                               <goals>
-                                                       <goal>check</goal>
-                                               </goals>
-                                       </execution>
-                               </executions>
-                       </plugin>
-               </plugins>
+                               <executions>
+                                       <execution>
+                                               <phase>verify</phase>
+                                               <goals>
+                                                       <goal>check</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
        </build>
        
        <repositories>

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/GossipSettings.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/GossipSettings.java 
b/src/main/java/org/apache/gossip/GossipSettings.java
deleted file mode 100644
index 6b2bf8b..0000000
--- a/src/main/java/org/apache/gossip/GossipSettings.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * In this object the settings used by the GossipService are held.
- * 
- */
-public class GossipSettings {
-
-  /** Time between gossip'ing in ms. Default is 1 second. */
-  private int gossipInterval = 10;
-
-  /** Time between cleanups in ms. Default is 10 seconds. */
-  private int cleanupInterval = 5000;
-
-  /** the minimum samples needed before reporting a result */
-  private int minimumSamples = 5;
-  
-  /** the number of samples to keep per host */
-  private int windowSize = 5000;
-  
-  /** the threshold for the detector */
-  private double convictThreshold = 10;
-  
-  private String distribution = "normal";
-  
-  private String activeGossipClass = 
"org.apache.gossip.manager.SimpleActiveGossipper";
-  
-  private Map<String,String> activeGossipProperties = new HashMap<>();
-  
-  private String pathToRingState = "./";
-  
-  private boolean persistRingState = true;
-  
-  private String pathToDataState = "./";
-  
-  private boolean persistDataState = true;
-  
-  private String pathToKeyStore = "./keys";
-  
-  private boolean signMessages = false;
-  
-  
-  /**
-   * Construct GossipSettings with default settings.
-   */
-  public GossipSettings() {
-  }
-
-  /**
-   * Construct GossipSettings with given settings.
-   * 
-   * @param gossipInterval
-   *          The gossip interval in ms.
-   * @param cleanupInterval
-   *          The cleanup interval in ms.
-   */
-  public GossipSettings(int gossipInterval, int cleanupInterval, int 
windowSize, 
-          int minimumSamples, double convictThreshold, String distribution) {
-    this.gossipInterval = gossipInterval;
-    this.cleanupInterval = cleanupInterval;
-    this.windowSize = windowSize;
-    this.minimumSamples = minimumSamples;
-    this.convictThreshold = convictThreshold;
-    this.distribution = distribution;
-  }
-
-  /**
-   * Set the gossip interval. This is the time between a gossip message is 
send.
-   * 
-   * @param gossipInterval
-   *          The gossip interval in ms.
-   */
-  public void setGossipTimeout(int gossipInterval) {
-    this.gossipInterval = gossipInterval;
-  }
-
-  /**
-   * Set the cleanup interval. This is the time between the last heartbeat 
received from a member
-   * and when it will be marked as dead.
-   * 
-   * @param cleanupInterval
-   *          The cleanup interval in ms.
-   */
-  public void setCleanupInterval(int cleanupInterval) {
-    this.cleanupInterval = cleanupInterval;
-  }
-
-  /**
-   * Get the gossip interval.
-   * 
-   * @return The gossip interval in ms.
-   */
-  public int getGossipInterval() {
-    return gossipInterval;
-  }
-
-  /**
-   * Get the clean interval.
-   * 
-   * @return The cleanup interval.
-   */
-  public int getCleanupInterval() {
-    return cleanupInterval;
-  }
-
-  public int getMinimumSamples() {
-    return minimumSamples;
-  }
-
-  public void setMinimumSamples(int minimumSamples) {
-    this.minimumSamples = minimumSamples;
-  }
-
-  public int getWindowSize() {
-    return windowSize;
-  }
-
-  public void setWindowSize(int windowSize) {
-    this.windowSize = windowSize;
-  }
-
-  public double getConvictThreshold() {
-    return convictThreshold;
-  }
-
-  public void setConvictThreshold(double convictThreshold) {
-    this.convictThreshold = convictThreshold;
-  }
-
-  public void setGossipInterval(int gossipInterval) {
-    this.gossipInterval = gossipInterval;
-  }
-
-  public String getDistribution() {
-    return distribution;
-  }
-
-  public void setDistribution(String distribution) {
-    this.distribution = distribution;
-  }
-
-  public String getActiveGossipClass() {
-    return activeGossipClass;
-  }
-
-  public void setActiveGossipClass(String activeGossipClass) {
-    this.activeGossipClass = activeGossipClass;
-  }
-
-  public Map<String, String> getActiveGossipProperties() {
-    return activeGossipProperties;
-  }
-
-  public void setActiveGossipProperties(Map<String, String> 
activeGossipProperties) {
-    this.activeGossipProperties = activeGossipProperties;
-  }
-
-  public String getPathToRingState() {
-    return pathToRingState;
-  }
-
-  public void setPathToRingState(String pathToRingState) {
-    this.pathToRingState = pathToRingState;
-  }
-
-  public boolean isPersistRingState() {
-    return persistRingState;
-  }
-
-  public void setPersistRingState(boolean persistRingState) {
-    this.persistRingState = persistRingState;
-  }
-
-  public String getPathToDataState() {
-    return pathToDataState;
-  }
-
-  public void setPathToDataState(String pathToDataState) {
-    this.pathToDataState = pathToDataState;
-  }
-
-  public boolean isPersistDataState() {
-    return persistDataState;
-  }
-
-  public void setPersistDataState(boolean persistDataState) {
-    this.persistDataState = persistDataState;
-  }
-
-  public String getPathToKeyStore() {
-    return pathToKeyStore;
-  }
-
-  public void setPathToKeyStore(String pathToKeyStore) {
-    this.pathToKeyStore = pathToKeyStore;
-  }
-
-  public boolean isSignMessages() {
-    return signMessages;
-  }
-
-  public void setSignMessages(boolean signMessages) {
-    this.signMessages = signMessages;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/LocalMember.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/LocalMember.java 
b/src/main/java/org/apache/gossip/LocalMember.java
deleted file mode 100644
index 450bce5..0000000
--- a/src/main/java/org/apache/gossip/LocalMember.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip;
-
-import java.net.URI;
-import java.util.Map;
-
-import org.apache.gossip.accrual.FailureDetector;
-
-/**
- * This object represent a gossip member with the properties known locally. 
These objects are stored
- * in the local list of gossip members.
- * 
- */
-public class LocalMember extends Member {
-  /** The failure detector for this member */
-  private transient FailureDetector detector;
-
-  /**
-   * 
-   * @param uri
-   *          The uri of the member
-   * @param id
-   *          id of the node
-   * @param heartbeat
-   *          The current heartbeat
-   */
-  public LocalMember(String clusterName, URI uri, String id,
-          long heartbeat, Map<String,String> properties, int windowSize, int 
minSamples, String distribution) {
-    super(clusterName, uri, id, heartbeat, properties );
-    detector = new FailureDetector(minSamples, windowSize, distribution);
-  }
-
-  protected LocalMember(){
-    
-  }
-  
-  public void recordHeartbeat(long now){
-    detector.recordHeartbeat(now);
-  }
-  
-  public Double detect(long now) {
-    return detector.computePhiMeasure(now);
-  }
-
-  @Override
-  public String toString() {
-    Double d = null;
-    try {
-      d = detect(System.nanoTime());
-    } catch (RuntimeException ex) {}
-    return "LocalGossipMember [uri=" + uri + ", heartbeat=" + heartbeat + ", 
clusterName="
-            + clusterName + ", id=" + id + ", currentdetect=" + d  +" ]";
-  }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/Member.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/Member.java 
b/src/main/java/org/apache/gossip/Member.java
deleted file mode 100644
index d04a7b6..0000000
--- a/src/main/java/org/apache/gossip/Member.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip;
-
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.util.Map;
-
-/**
- * A abstract class representing a gossip member.
- * 
- */
-public abstract class Member implements Comparable<Member> {
-
-  
-  protected URI uri;
-
-  protected volatile long heartbeat;
-
-  protected String clusterName;
-
-  /**
-   * The purpose of the id field is to be able for nodes to identify 
themselves beyond their
-   * host/port. For example an application might generate a persistent id so 
if they rejoin the
-   * cluster at a different host and port we are aware it is the same node.
-   */
-  protected String id;
-
-  /* properties provided at startup time */
-  protected Map<String,String> properties;
-  
-  /**
-   * Constructor.
-   *
-   * @param clusterName
-   *          The name of the cluster 
-   * @param uri
-   *          A URI object containing IP/hostname and port
-   * @param heartbeat
-   *          The current heartbeat
-   * @param id
-   *          An id that may be replaced after contact
-   */
-  public Member(String clusterName, URI uri, String id, long heartbeat, 
Map<String,String> properties) {
-    this.clusterName = clusterName;
-    this.id = id;
-    this.heartbeat = heartbeat;
-    this.uri = uri;
-    this.properties = properties;
-  }
-
-  protected Member(){}
-  /**
-   * Get the name of the cluster the member belongs to.
-   * 
-   * @return The cluster name
-   */
-  public String getClusterName() {
-    return clusterName;
-  }
-
- 
-  /**
-   * @return The member address in the form IP/host:port Similar to the 
toString in
-   * {@link InetSocketAddress}
-   */
-  public String computeAddress() {
-    return uri.getHost() + ":" + uri.getPort();
-  }
-
-  /**
-   * Get the heartbeat of this gossip member.
-   * 
-   * @return The current heartbeat.
-   */
-  public long getHeartbeat() {
-    return heartbeat;
-  }
-
-  /**
-   * Set the heartbeat of this gossip member.
-   * 
-   * @param heartbeat
-   *          The new heartbeat.
-   */
-  public void setHeartbeat(long heartbeat) {
-    this.heartbeat = heartbeat;
-  }
-
-  public String getId() {
-    return id;
-  }
-
-  public void setId(String _id) {
-    this.id = _id;
-  }
-
-  public Map<String, String> getProperties() {
-    return properties;
-  }
-
-  public void setProperties(Map<String, String> properties) {
-    this.properties = properties;
-  }
-
-  public String toString() {
-    return "Member [address=" + computeAddress() + ", id=" + id + ", 
heartbeat=" + heartbeat + "]";
-  }
-
-  /**
-   * @see java.lang.Object#hashCode()
-   */
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    String address = computeAddress();
-    result = prime * result + ((address == null) ? 0 : address.hashCode()) + 
(clusterName == null ? 0
-            : clusterName.hashCode());
-    return result;
-  }
-
-  public URI getUri() {
-    return uri;
-  }
-
-  /**
-   * @see java.lang.Object#equals(java.lang.Object)
-   */
-  @Override
-  public boolean equals(Object obj) {
-    if (this == obj) {
-      return true;
-    }
-    if (obj == null) {
-      System.err.println("equals(): obj is null.");
-      return false;
-    }
-    if (!(obj instanceof Member)) {
-      System.err.println("equals(): obj is not of type GossipMember.");
-      return false;
-    }
-    // The object is the same of they both have the same address (hostname and 
port).
-    return computeAddress().equals(((LocalMember) obj).computeAddress())
-            && getClusterName().equals(((LocalMember) obj).getClusterName());
-  }
-
-  public int compareTo(Member other) {
-    return this.computeAddress().compareTo(other.computeAddress());
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/RemoteMember.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/RemoteMember.java 
b/src/main/java/org/apache/gossip/RemoteMember.java
deleted file mode 100644
index 6b42da2..0000000
--- a/src/main/java/org/apache/gossip/RemoteMember.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip;
-
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The object represents a gossip member with the properties as received from 
a remote gossip
- * member.
- * 
- */
-public class RemoteMember extends Member {
-
-  /**
-   * Constructor.
-   * 
-   * @param uri
-   *          A URI object containing IP/hostname and port
-   * @param heartbeat
-   *          The current heartbeat
-   */
-  public RemoteMember(String clusterName, URI uri, String id, long heartbeat, 
Map<String,String> properties) {
-    super(clusterName, uri, id, heartbeat, properties);
-  }
-
-  public RemoteMember(String clusterName, URI uri, String id) {
-    super(clusterName, uri, id, System.nanoTime(), new 
HashMap<String,String>());
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/StartupSettings.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/StartupSettings.java 
b/src/main/java/org/apache/gossip/StartupSettings.java
deleted file mode 100644
index 17eaaf2..0000000
--- a/src/main/java/org/apache/gossip/StartupSettings.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.log4j.Logger;
-
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * This object represents the settings used when starting the gossip service.
- * 
- */
-public class StartupSettings {
-  private static final Logger log = Logger.getLogger(StartupSettings.class);
-
-  /** The id to use fo the service */
-  private String id;
-
-  private URI uri;
-  
-  private String cluster;
-
-  /** The gossip settings used at startup. */
-  private final GossipSettings gossipSettings;
-
-  /** The list with gossip members to start with. */
-  private final List<Member> gossipMembers;
-
-  /**
-   * Constructor.
-   * 
-   * @param id
-   *          The id to be used for this service
-   * @param uri
-   *          A URI object containing IP/hostname and port
-   * @param logLevel
-   *          unused
-   */
-  public StartupSettings(String id, URI uri, int logLevel, String cluster) {
-    this(id, uri, new GossipSettings(), cluster);
-  }
-
-  public URI getUri() {
-    return uri;
-  }
-
-  public void setUri(URI uri) {
-    this.uri = uri;
-  }
-
-  /**
-   * Constructor.
-   * 
-   * @param id
-   *          The id to be used for this service
-   * @param uri
-   *          A URI object containing IP/hostname and port
-   */
-  public StartupSettings(String id, URI uri, GossipSettings gossipSettings, 
String cluster) {
-    this.id = id;
-    this.uri = uri;
-    this.gossipSettings = gossipSettings;
-    this.setCluster(cluster);
-    gossipMembers = new ArrayList<>();
-  }
-
-  public void setCluster(String cluster) {
-    this.cluster = cluster;
-  }
-
-  public String getCluster() {
-    return cluster;
-  }
-
-  /**
-   * Set the id to be used for this service.
-   * 
-   * @param id
-   *          The id for this service.
-   */
-  public void setId(String id) {
-    this.id = id;
-  }
-
-  /**
-   * Get the id for this service.
-   * 
-   * @return the service's id.
-   */
-  public String getId() {
-    return id;
-  }
-
-  /**
-   * Get the GossipSettings.
-   * 
-   * @return The GossipSettings object.
-   */
-  public GossipSettings getGossipSettings() {
-    return gossipSettings;
-  }
-
-  /**
-   * Add a gossip member to the list of members to start with.
-   * 
-   * @param member
-   *          The member to add.
-   */
-  public void addGossipMember(Member member) {
-    gossipMembers.add(member);
-  }
-
-  /**
-   * Get the list with gossip members.
-   * 
-   * @return The gossip members.
-   */
-  public List<Member> getGossipMembers() {
-    return gossipMembers;
-  }
-
-  /**
-   * Parse the settings for the gossip service from a JSON file.
-   * 
-   * @param jsonFile
-   *          The file object which refers to the JSON config file.
-   * @return The StartupSettings object with the settings from the config file.
-   * @throws FileNotFoundException
-   *           Thrown when the file cannot be found.
-   * @throws IOException
-   *           Thrown when reading the file gives problems.
-   * @throws URISyntaxException 
-   */
-  public static StartupSettings fromJSONFile(File jsonFile) throws  
-          FileNotFoundException, IOException, URISyntaxException {
-    ObjectMapper om = new ObjectMapper();
-    JsonNode root = om.readTree(jsonFile);
-    JsonNode jsonObject = root.get(0);
-    String uri = jsonObject.get("uri").textValue();
-    String id = jsonObject.get("id").textValue();
-    Map<String,String> properties = new HashMap<String,String>();
-    JsonNode n = jsonObject.get("properties");
-    Iterator<Entry<String, JsonNode>> l = n.fields();
-    while (l.hasNext()){
-      Entry<String, JsonNode> i = l.next();
-      properties.put(i.getKey(), i.getValue().asText());
-    }
-    //TODO constants as defaults?
-    int gossipInterval = jsonObject.get("gossip_interval").intValue();
-    int cleanupInterval = jsonObject.get("cleanup_interval").intValue();
-    int windowSize = jsonObject.get("window_size").intValue();
-    int minSamples = jsonObject.get("minimum_samples").intValue();
-    double convictThreshold = jsonObject.get("convict_threshold").asDouble();
-    String cluster = jsonObject.get("cluster").textValue();
-    String distribution = jsonObject.get("distribution").textValue();
-    if (cluster == null){
-      throw new IllegalArgumentException("cluster was null. It is required");
-    }
-    URI uri2 = new URI(uri);
-    StartupSettings settings = new StartupSettings(id, uri2, 
-            new GossipSettings(gossipInterval, cleanupInterval, windowSize, 
-                    minSamples, convictThreshold, distribution), cluster);
-    String configMembersDetails = "Config-members [";
-    JsonNode membersJSON = jsonObject.get("members");
-    Iterator<JsonNode> it = membersJSON.iterator();
-    while (it.hasNext()){
-      JsonNode child = it.next();
-      URI uri3 = new URI(child.get("uri").textValue());
-      RemoteMember member = new RemoteMember(child.get("cluster").asText(),
-              uri3, "", 0, new HashMap<String,String>());
-      settings.addGossipMember(member);
-      configMembersDetails += member.computeAddress();
-      configMembersDetails += ", ";
-    }
-    log.info(configMembersDetails + "]");
-    return settings;
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/accrual/FailureDetector.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/accrual/FailureDetector.java 
b/src/main/java/org/apache/gossip/accrual/FailureDetector.java
deleted file mode 100644
index 5abd5c6..0000000
--- a/src/main/java/org/apache/gossip/accrual/FailureDetector.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip.accrual;
-
-import org.apache.commons.math.MathException;
-import org.apache.commons.math.distribution.ExponentialDistributionImpl;
-import org.apache.commons.math.distribution.NormalDistributionImpl;
-import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
-import org.apache.log4j.Logger;
-
-public class FailureDetector {
-
-  public static final Logger LOGGER = Logger.getLogger(FailureDetector.class);
-  private final DescriptiveStatistics descriptiveStatistics;
-  private final long minimumSamples;
-  private volatile long latestHeartbeatMs = -1;
-  private final String distribution;
-
-  public FailureDetector(long minimumSamples, int windowSize, String 
distribution) {
-    descriptiveStatistics = new DescriptiveStatistics(windowSize);
-    this.minimumSamples = minimumSamples;
-    this.distribution = distribution;
-  }
-
-  /**
-   * Updates the statistics based on the delta between the last
-   * heartbeat and supplied time
-   *
-   * @param now the time of the heartbeat in milliseconds
-   */
-  public synchronized void recordHeartbeat(long now) {
-    if (now <= latestHeartbeatMs) {
-      return;
-    }
-    if (latestHeartbeatMs != -1) {
-      descriptiveStatistics.addValue(now - latestHeartbeatMs);
-    }
-    latestHeartbeatMs = now;
-  }
-
-  public synchronized Double computePhiMeasure(long now) {
-    if (latestHeartbeatMs == -1 || descriptiveStatistics.getN() < 
minimumSamples) {
-      return null;
-    }
-    long delta = now - latestHeartbeatMs;
-    try {
-      double probability;
-      if (distribution.equals("normal")) {
-        double standardDeviation = 
descriptiveStatistics.getStandardDeviation();
-        standardDeviation = standardDeviation < 0.1 ? 0.1 : standardDeviation;
-        probability = new 
NormalDistributionImpl(descriptiveStatistics.getMean(), 
standardDeviation).cumulativeProbability(delta);
-      } else {
-        probability = new 
ExponentialDistributionImpl(descriptiveStatistics.getMean()).cumulativeProbability(delta);
-      }
-      final double eps = 1e-12;
-      if (1 - probability < eps) {
-        probability = 1.0;
-      }
-      return -1.0d * Math.log10(1.0d - probability);
-    } catch (MathException | IllegalArgumentException e) {
-      LOGGER.debug(e);
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/crdt/Crdt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/crdt/Crdt.java 
b/src/main/java/org/apache/gossip/crdt/Crdt.java
deleted file mode 100644
index 8edfa8c..0000000
--- a/src/main/java/org/apache/gossip/crdt/Crdt.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip.crdt;
-/**
- * 
- * Immutable type 
- *
- * @param <SetType>
- * @param <MergeReturnType>
- */
-public interface Crdt<SetType, MergeReturnType extends Crdt<SetType, 
MergeReturnType>> {
-
- 
-  MergeReturnType merge(MergeReturnType other);
-  SetType value();
-  /**
-   * Called to self optimize. Some CRDTs may use some mechanism to clean up be 
-   * removing obsolete data outside the scope of merging. IE this could clean 
up 
-   * temporal values, old copies etc. 
-   * @return the Crdt structure optimized 
-   */
-  MergeReturnType optimize();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/crdt/CrdtBiFunctionMerge.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/crdt/CrdtBiFunctionMerge.java 
b/src/main/java/org/apache/gossip/crdt/CrdtBiFunctionMerge.java
deleted file mode 100644
index 1ac7a30..0000000
--- a/src/main/java/org/apache/gossip/crdt/CrdtBiFunctionMerge.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip.crdt;
-
-import java.util.function.BiFunction;
-
-@SuppressWarnings("rawtypes")
-public class CrdtBiFunctionMerge implements BiFunction<Crdt,Crdt,Crdt> {
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public Crdt apply(Crdt t, Crdt u) {
-    if (t == null && u == null){
-      return null;
-    } else if (t == null){
-      return u;
-    } else if (u == null){
-      return t;
-    }
-    if (! u.getClass().equals(t.getClass())){
-      throw new IllegalArgumentException( "Can not merge " + t.getClass() + " 
"+ u.getClass());
-    }
-    return t.merge(u);
-  }
-
-  @SuppressWarnings("unchecked")
-  public static Crdt applyStatic(Crdt t, Crdt u){
-    if (t == null && u == null){
-      return null;
-    } else if (t == null){
-      return u;
-    } else if (u == null){
-      return t;
-    }
-    if (! u.getClass().equals(t.getClass())){
-      throw new IllegalArgumentException( "Can not merge " + t.getClass() + " 
"+ u.getClass());
-    }
-    return t.merge(u);
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/crdt/CrdtCounter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/crdt/CrdtCounter.java 
b/src/main/java/org/apache/gossip/crdt/CrdtCounter.java
deleted file mode 100644
index cdc9445..0000000
--- a/src/main/java/org/apache/gossip/crdt/CrdtCounter.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip.crdt;
-
-public interface CrdtCounter<ValueType extends Number, R extends 
CrdtCounter<ValueType, R>>
-        extends Crdt<ValueType, R> {
-  
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/crdt/CrdtModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/crdt/CrdtModule.java 
b/src/main/java/org/apache/gossip/crdt/CrdtModule.java
deleted file mode 100644
index cfb3f47..0000000
--- a/src/main/java/org/apache/gossip/crdt/CrdtModule.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip.crdt;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.core.Version;
-import com.fasterxml.jackson.databind.module.SimpleModule;
-
-abstract class OrSetMixin<E> {
-  @JsonCreator
-  OrSetMixin(@JsonProperty("elements") Map<E, Set<UUID>> w, 
@JsonProperty("tombstones") Map<E, Set<UUID>> h) { }
-  @JsonProperty("elements") abstract Map<E, Set<UUID>> getElements();
-  @JsonProperty("tombstones") abstract Map<E, Set<UUID>> getTombstones();
-  @JsonIgnore abstract boolean isEmpty();
-}
-
-abstract class GrowOnlySetMixin<E>{
-  @JsonCreator
-  GrowOnlySetMixin(@JsonProperty("elements") Set<E> elements){ }
-  @JsonProperty("elements") abstract Set<E> getElements();
-  @JsonIgnore abstract boolean isEmpty();
-}
-
-abstract class GrowOnlyCounterMixin {
-  @JsonCreator
-  GrowOnlyCounterMixin(@JsonProperty("counters") Map<String, Long> counters) { 
}
-  @JsonProperty("counters") abstract Map<String, Long> getCounters();
-}
-
-//If anyone wants to take a stab at this. please have at it
-//https://github.com/FasterXML/jackson-datatype-guava/blob/master/src/main/java/com/fasterxml/jackson/datatype/guava/ser/MultimapSerializer.java
-public class CrdtModule extends SimpleModule {
-
-  private static final long serialVersionUID = 6134836523275023418L;
-
-  public CrdtModule() {
-    super("CrdtModule", new Version(0, 0, 0, "0.0.0", "org.apache.gossip", 
"gossip"));
-  }
-
-  @Override
-  public void setupModule(SetupContext context) {
-    context.setMixInAnnotations(OrSet.class, OrSetMixin.class);
-    context.setMixInAnnotations(GrowOnlySet.class, GrowOnlySetMixin.class);
-    context.setMixInAnnotations(GrowOnlyCounter.class, 
GrowOnlyCounterMixin.class);
-  }
-
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/298b1ae3/src/main/java/org/apache/gossip/crdt/CrdtSet.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/gossip/crdt/CrdtSet.java 
b/src/main/java/org/apache/gossip/crdt/CrdtSet.java
deleted file mode 100644
index 21b41da..0000000
--- a/src/main/java/org/apache/gossip/crdt/CrdtSet.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.gossip.crdt;
-
-import java.util.Set;
-
-public interface CrdtSet<ElementType, SetType extends Set<ElementType>, R 
extends CrdtSet<ElementType, SetType, R>>
-extends Crdt<SetType, R> {
-
-}
-


Reply via email to