From 789a5f6abc603adea6fd93b8ce2eade05d9187d6 Mon Sep 17 00:00:00 2001 From: Jaime Freire <5436581+jaimefreire@users.noreply.github.com> Date: Sat, 25 Nov 2023 08:18:02 +0100 Subject: [PATCH] Fixed build --- README.md | 16 +- eclipse_template.xml | 655 ++++++++++-------- gossip-base/pom.xml | 107 ++- .../org/apache/gossip/GossipSettings.java | 35 +- .../java/org/apache/gossip/LocalMember.java | 53 +- .../main/java/org/apache/gossip/Member.java | 50 +- .../java/org/apache/gossip/RemoteMember.java | 15 +- .../org/apache/gossip/StartupSettings.java | 195 +++--- .../gossip/accrual/FailureDetector.java | 24 +- .../java/org/apache/gossip/crdt/Crdt.java | 16 +- .../apache/gossip/crdt/CrdtAddRemoveSet.java | 10 +- .../gossip/crdt/CrdtBiFunctionMerge.java | 42 +- .../org/apache/gossip/crdt/CrdtCounter.java | 5 +- .../org/apache/gossip/crdt/CrdtModule.java | 9 +- .../java/org/apache/gossip/crdt/CrdtSet.java | 8 +- .../apache/gossip/crdt/GrowOnlyCounter.java | 3 +- .../org/apache/gossip/crdt/GrowOnlySet.java | 42 +- .../java/org/apache/gossip/crdt/LwwSet.java | 158 +++-- .../org/apache/gossip/crdt/MaxChangeSet.java | 53 +- .../java/org/apache/gossip/crdt/OrSet.java | 103 ++- .../org/apache/gossip/crdt/PNCounter.java | 1 - .../org/apache/gossip/crdt/TwoPhaseSet.java | 46 +- .../org/apache/gossip/event/GossipState.java | 4 +- .../gossip/event/data/DataEventConstants.java | 21 +- .../gossip/event/data/DataEventManager.java | 80 ++- .../data/UpdateNodeDataEventHandler.java | 15 +- .../data/UpdateSharedDataEventHandler.java | 7 +- .../org/apache/gossip/lock/LockManager.java | 37 +- .../gossip/lock/LockManagerSettings.java | 32 +- .../lock/exceptions/VoteFailedException.java | 9 +- .../apache/gossip/lock/vote/MajorityVote.java | 3 +- .../gossip/lock/vote/RandomVoteSelector.java | 4 +- .../org/apache/gossip/lock/vote/Vote.java | 2 +- .../gossip/lock/vote/VoteCandidate.java | 14 +- .../apache/gossip/lock/vote/VoteSelector.java | 7 +- .../manager/AbstractActiveGossiper.java | 23 +- .../java/org/apache/gossip/manager/Clock.java | 2 +- .../org/apache/gossip/manager/DataReaper.java | 1 - .../DatacenterRackAwareActiveGossiper.java | 16 +- .../org/apache/gossip/manager/GossipCore.java | 74 +- .../gossip/manager/GossipCoreConstants.java | 2 +- .../apache/gossip/manager/GossipManager.java | 104 ++- .../gossip/manager/GossipManagerBuilder.java | 36 +- .../manager/GossipMemberStateRefresher.java | 21 +- .../gossip/manager/RingStatePersister.java | 11 +- .../gossip/manager/SimpleActiveGossiper.java | 78 ++- .../apache/gossip/manager/SystemClock.java | 1 - .../gossip/manager/UserDataPersister.java | 53 +- .../handlers/ActiveGossipMessageHandler.java | 15 +- .../manager/handlers/MessageHandler.java | 2 +- .../handlers/MessageHandlerFactory.java | 41 +- .../PerNodeDataBulkMessageHandler.java | 5 +- .../manager/handlers/ResponseHandler.java | 2 +- .../SharedDataBulkMessageHandler.java | 7 +- .../handlers/SharedDataMessageHandler.java | 4 +- .../handlers/ShutdownMessageHandler.java | 2 +- ...r.java => TypedMessageHandlerWrapper.java} | 8 +- .../gossip/model/ActiveGossipMessage.java | 7 +- .../apache/gossip/model/ActiveGossipOk.java | 4 +- .../java/org/apache/gossip/model/Base.java | 14 +- .../java/org/apache/gossip/model/Fault.java | 4 +- .../java/org/apache/gossip/model/Member.java | 26 +- .../java/org/apache/gossip/model/Message.java | 4 +- .../apache/gossip/model/NotAMemberFault.java | 8 +- .../gossip/model/PerNodeDataBulkMessage.java | 8 +- .../gossip/model/PerNodeDataMessage.java | 28 +- .../org/apache/gossip/model/Response.java | 4 +- .../gossip/model/SharedDataBulkMessage.java | 8 +- .../gossip/model/SharedDataMessage.java | 1 - .../apache/gossip/model/ShutdownMessage.java | 7 +- .../apache/gossip/model/SignedPayload.java | 11 +- .../gossip/protocol/ProtocolManager.java | 3 +- .../gossip/replication/AllReplicable.java | 2 +- .../replication/BlackListReplicable.java | 4 +- .../replication/DataCenterReplicable.java | 12 +- .../gossip/replication/NotReplicable.java | 2 +- .../apache/gossip/replication/Replicable.java | 5 +- .../replication/WhiteListReplicable.java | 5 +- .../org/apache/gossip/secure/KeyTool.java | 10 +- .../transport/AbstractTransportManager.java | 22 +- .../gossip/transport/TransportManager.java | 20 +- .../java/org/apache/gossip/udp/Trackable.java | 7 +- .../gossip/udp/UdpActiveGossipMessage.java | 18 +- .../apache/gossip/udp/UdpActiveGossipOk.java | 10 +- .../apache/gossip/udp/UdpNotAMemberFault.java | 15 +- .../gossip/udp/UdpPerNodeDataBulkMessage.java | 18 +- .../gossip/udp/UdpPerNodeDataMessage.java | 18 +- .../gossip/udp/UdpSharedDataBulkMessage.java | 19 +- .../gossip/udp/UdpSharedDataMessage.java | 30 +- .../apache/gossip/utils/ReflectionUtils.java | 14 +- .../src/main/resources/log4j.properties | 3 - .../gossip/AbstractIntegrationBase.java | 30 +- .../java/org/apache/gossip/MemberTest.java | 30 +- .../gossip/accrual/FailureDetectorTest.java | 60 +- .../gossip/crdt/AddRemoveStringSetTest.java | 42 +- .../gossip/crdt/GrowOnlyCounterTest.java | 5 +- .../apache/gossip/crdt/GrowOnlySetTest.java | 7 +- .../org/apache/gossip/crdt/LwwSetTest.java | 15 +- .../apache/gossip/crdt/MaxChangeSetTest.java | 5 +- .../org/apache/gossip/crdt/OrSetTest.java | 5 +- .../org/apache/gossip/crdt/PNCounterTest.java | 1 - .../apache/gossip/crdt/TwoPhaseSetTest.java | 29 +- .../event/data/DataEventManagerTest.java | 119 ++-- .../gossip/lock/vote/MajorityVoteTest.java | 15 +- .../apache/gossip/manager/DataReaperTest.java | 41 +- .../manager/GossipManagerBuilderTest.java | 107 +-- .../gossip/manager/RingPersistenceTest.java | 31 +- .../manager/UserDataPersistenceTest.java | 58 +- .../manager/handlers/MessageHandlerTest.java | 243 ++++--- .../protocol/UnitTestProtocolManager.java | 7 +- .../replication/DataReplicationTest.java | 82 ++- .../transport/UnitTestTransportManager.java | 8 +- .../src/test/resources/log4j.properties | 3 - gossip-examples/README.md | 186 +++-- gossip-examples/pom.xml | 56 +- .../gossip/examples/RunStandardExamples.java | 18 +- .../examples/StandAloneDatacenterAndRack.java | 24 +- .../examples/StandAloneExampleBase.java | 42 +- .../gossip/examples/StandAloneNode.java | 11 +- .../examples/StandAloneNodeCrdtOrSet.java | 111 +-- .../gossip/examples/StandAlonePNCounter.java | 20 +- gossip-itest/pom.xml | 101 +-- .../test/java/org/apache/gossip/DataTest.java | 28 +- .../org/apache/gossip/IdAndPropertyTest.java | 71 +- .../apache/gossip/PerNodeDataEventTest.java | 70 +- .../PerNodeDataReplicationControlTest.java | 236 ++++--- .../apache/gossip/SharedDataEventTest.java | 13 +- .../org/apache/gossip/SharedDataLockTest.java | 71 +- .../SharedDataReplicationControlTest.java | 228 +++--- .../apache/gossip/ShutdownDeadtimeTest.java | 117 ++-- .../org/apache/gossip/SignedMessageTest.java | 60 +- .../apache/gossip/StartupSettingsTest.java | 79 ++- .../apache/gossip/TenNodeThreeSeedTest.java | 40 +- gossip-protocol-jackson/pom.xml | 52 +- .../protocol/json/JacksonProtocolManager.java | 63 +- .../gossip/protocol/json/JacksonTest.java | 76 +- .../gossip/protocol/json/TestMessage.java | 48 +- gossip-transport-udp/pom.xml | 42 +- .../transport/udp/UdpTransportManager.java | 49 +- .../udp/UdpTransportIntegrationTest.java | 19 +- pom.xml | 582 ++++++++-------- 141 files changed, 3259 insertions(+), 2957 deletions(-) rename gossip-base/src/main/java/org/apache/gossip/manager/handlers/{TypedMessageHandler.java => TypedMessageHandlerWrapper.java} (86%) diff --git a/README.md b/README.md index 2eae09d..b90bc7c 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,15 @@ # Gossip ![Build status](https://travis-ci.org/edwardcapriolo/incubator-gossip.svg?) -Gossip protocol is a method for a group of nodes to discover and check the liveliness of a cluster. More information can be found at http://en.wikipedia.org/wiki/Gossip_protocol. +Gossip protocol is a method for a group of nodes to discover and check the liveliness of a cluster. More information can +be found at http://en.wikipedia.org/wiki/Gossip_protocol. -The original implementation was forked from https://code.google.com/p/java-gossip/. Several bug fixes and changes have already been added. +The original implementation was forked from https://code.google.com/p/java-gossip/. Several bug fixes and changes have +already been added. -A set of easily-run examples, illustrating various features of Gossip, are available in the gossip-examples module. The README.md file, in that module described how to run those examples. +A set of easily-run examples, illustrating various features of Gossip, are available in the gossip-examples module. The +README.md file, in that module described how to run those examples. -Below, a list of code snippits which show how to incorproate Apache Gossip into your project. +Below, a list of code snippits which show how to incorproate Apache Gossip into your project. Usage ----- @@ -23,7 +26,8 @@ To gossip you need one or more seed nodes. Seed is just a list of places to init } ``` -Here we start five gossip processes and check that they discover each other. (Normally these are on different hosts but here we give each process a distinct local ip. +Here we start five gossip processes and check that they discover each other. (Normally these are on different hosts but +here we give each process a distinct local ip. ```java List clients = new ArrayList<>(); @@ -64,7 +68,7 @@ For a very simple client setup with a settings file you first need a JSON file s where: -* `cluster` - is the name of the cluster +* `cluster` - is the name of the cluster * `id` - is a unique id for this node (you can use any string, but above we use a UUID) * `uri` - is a URI object containing IP/hostname and port to use on the default adapter on the node's machine * `gossip_interval` - how often (in milliseconds) to gossip list of members to other node(s) diff --git a/eclipse_template.xml b/eclipse_template.xml index 3d6e91a..1152632 100644 --- a/eclipse_template.xml +++ b/eclipse_template.xml @@ -1,30 +1,38 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -36,256 +44,349 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gossip-base/pom.xml b/gossip-base/pom.xml index e72a455..cdf2d1c 100644 --- a/gossip-base/pom.xml +++ b/gossip-base/pom.xml @@ -16,70 +16,51 @@ See the License for the specific language governing permissions and limitations under the License. --> - - 4.0.0 + 4.0.0 - - org.apache.gossip - gossip-parent + + org.apache.gossip + gossip-parent + 0.1.3-incubating-SNAPSHOT + ../pom.xml + + + Gossip Base + gossip-base 0.1.3-incubating-SNAPSHOT - ../pom.xml - - - Gossip Base - gossip-base - 0.1.3-incubating-SNAPSHOT - - - - com.fasterxml.jackson.core - jackson-core - ${jackson.version} - - - commons-math - commons-math - ${commons-math.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - io.dropwizard.metrics - metrics-core - ${metrics.version} - - log4j - log4j - ${log4j.version} - jar - compile - - - javax.jms - jms - - - com.sun.jdmk - jmxtools - - - com.sun.jmx - jmxri - - - - - org.mockito - mockito-core - ${mockito.version} - test - - - - + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + + org.apache.commons + commons-math3 + 3.6.1 + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + io.dropwizard.metrics + metrics-core + ${metrics.version} + + + + org.apache.logging.log4j + log4j-core + 2.22.0 + + + diff --git a/gossip-base/src/main/java/org/apache/gossip/GossipSettings.java b/gossip-base/src/main/java/org/apache/gossip/GossipSettings.java index 2fe8a0c..34834ed 100644 --- a/gossip-base/src/main/java/org/apache/gossip/GossipSettings.java +++ b/gossip-base/src/main/java/org/apache/gossip/GossipSettings.java @@ -17,10 +17,9 @@ */ package org.apache.gossip; -import org.apache.gossip.lock.LockManagerSettings; - import java.util.HashMap; import java.util.Map; +import org.apache.gossip.lock.LockManagerSettings; /** * In this object the settings used by the GossipService are held. @@ -107,26 +106,19 @@ public class GossipSettings { 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; } + public void setGossipInterval(int gossipInterval) { + this.gossipInterval = gossipInterval; + } + /** * Get the clean interval. * @@ -136,6 +128,17 @@ public class GossipSettings { return cleanupInterval; } + /** + * 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; + } + public int getMinimumSamples() { return minimumSamples; } @@ -160,10 +163,6 @@ public class GossipSettings { this.convictThreshold = convictThreshold; } - public void setGossipInterval(int gossipInterval) { - this.gossipInterval = gossipInterval; - } - public String getDistribution() { return distribution; } diff --git a/gossip-base/src/main/java/org/apache/gossip/LocalMember.java b/gossip-base/src/main/java/org/apache/gossip/LocalMember.java index 450bce5..cd2490c 100644 --- a/gossip-base/src/main/java/org/apache/gossip/LocalMember.java +++ b/gossip-base/src/main/java/org/apache/gossip/LocalMember.java @@ -25,35 +25,35 @@ 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 + * @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 properties, int windowSize, int minSamples, String distribution) { - super(clusterName, uri, id, heartbeat, properties ); + public LocalMember( + String clusterName, + URI uri, + String id, + long heartbeat, + Map 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){ + protected LocalMember() {} + + public void recordHeartbeat(long now) { detector.recordHeartbeat(now); } - + public Double detect(long now) { return detector.computePhiMeasure(now); } @@ -63,9 +63,18 @@ public class LocalMember extends Member { Double d = null; try { d = detect(System.nanoTime()); - } catch (RuntimeException ex) {} - return "LocalGossipMember [uri=" + uri + ", heartbeat=" + heartbeat + ", clusterName=" - + clusterName + ", id=" + id + ", currentdetect=" + d +" ]"; + } catch (RuntimeException ex) { + } + return "LocalGossipMember [uri=" + + uri + + ", heartbeat=" + + heartbeat + + ", clusterName=" + + clusterName + + ", id=" + + id + + ", currentdetect=" + + d + + " ]"; } - -} \ No newline at end of file +} diff --git a/gossip-base/src/main/java/org/apache/gossip/Member.java b/gossip-base/src/main/java/org/apache/gossip/Member.java index 54a6737..20db9c7 100644 --- a/gossip-base/src/main/java/org/apache/gossip/Member.java +++ b/gossip-base/src/main/java/org/apache/gossip/Member.java @@ -21,13 +21,9 @@ import java.net.InetSocketAddress; import java.net.URI; import java.util.Map; -/** - * An abstract class representing a gossip member. - * - */ +/** An abstract class representing a gossip member. */ public abstract class Member implements Comparable { - protected URI uri; protected volatile long heartbeat; @@ -42,21 +38,18 @@ public abstract class Member implements Comparable { protected String id; /* properties provided at startup time */ - protected Map properties; - + protected Map 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 + * @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 properties) { + public Member( + String clusterName, URI uri, String id, long heartbeat, Map properties) { this.clusterName = clusterName; this.id = id; this.heartbeat = heartbeat; @@ -64,20 +57,20 @@ public abstract class Member implements Comparable { this.properties = properties; } - protected Member(){} + 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} + * @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(); @@ -85,7 +78,7 @@ public abstract class Member implements Comparable { /** * Get the heartbeat of this gossip member. - * + * * @return The current heartbeat. */ public long getHeartbeat() { @@ -94,9 +87,8 @@ public abstract class Member implements Comparable { /** * Set the heartbeat of this gossip member. - * - * @param heartbeat - * The new heartbeat. + * + * @param heartbeat The new heartbeat. */ public void setHeartbeat(long heartbeat) { this.heartbeat = heartbeat; @@ -130,8 +122,10 @@ public abstract class Member implements Comparable { final int prime = 31; int result = 1; String address = computeAddress(); - result = prime * result + ((address == null) ? 0 : address.hashCode()) + (clusterName == null ? 0 - : clusterName.hashCode()); + result = + prime * result + + ((address == null) ? 0 : address.hashCode()) + + (clusterName == null ? 0 : clusterName.hashCode()); return result; } @@ -157,7 +151,7 @@ public abstract class Member implements Comparable { } // 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()); + && getClusterName().equals(((LocalMember) obj).getClusterName()); } public int compareTo(Member other) { diff --git a/gossip-base/src/main/java/org/apache/gossip/RemoteMember.java b/gossip-base/src/main/java/org/apache/gossip/RemoteMember.java index 6b42da2..be76874 100644 --- a/gossip-base/src/main/java/org/apache/gossip/RemoteMember.java +++ b/gossip-base/src/main/java/org/apache/gossip/RemoteMember.java @@ -24,24 +24,21 @@ 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 + * + * @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 properties) { + public RemoteMember( + String clusterName, URI uri, String id, long heartbeat, Map properties) { super(clusterName, uri, id, heartbeat, properties); } public RemoteMember(String clusterName, URI uri, String id) { - super(clusterName, uri, id, System.nanoTime(), new HashMap()); + super(clusterName, uri, id, System.nanoTime(), new HashMap()); } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/StartupSettings.java b/gossip-base/src/main/java/org/apache/gossip/StartupSettings.java index 23608f2..8c269eb 100644 --- a/gossip-base/src/main/java/org/apache/gossip/StartupSettings.java +++ b/gossip-base/src/main/java/org/apache/gossip/StartupSettings.java @@ -17,6 +17,8 @@ */ package org.apache.gossip; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -28,36 +30,26 @@ 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; +import lombok.extern.slf4j.Slf4j; /** * This object represents the settings used when starting the gossip service. * */ +@Slf4j 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 gossipMembers; + public static final int DEFAULT_BULK_TRANSFER_SIZE = 100; /** Default setting values */ private static final boolean DEFAULT_BULK_TRANSFER = false; - public static final int DEFAULT_BULK_TRANSFER_SIZE = 100; + /** The gossip settings used at startup. */ + private final GossipSettings gossipSettings; + /** The list with gossip members to start with. */ + private final List gossipMembers; + /** The id to use fo the service */ + private String id; + private URI uri; + private String cluster; /** * Constructor. @@ -73,17 +65,9 @@ public class StartupSettings { 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 @@ -97,64 +81,9 @@ public class StartupSettings { 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 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. @@ -162,9 +91,9 @@ public class StartupSettings { * Thrown when the file cannot be found. * @throws IOException * Thrown when reading the file gives problems. - * @throws URISyntaxException + * @throws URISyntaxException */ - public static StartupSettings fromJSONFile(File jsonFile) throws + public static StartupSettings fromJSONFile(File jsonFile) throws FileNotFoundException, IOException, URISyntaxException { ObjectMapper om = new ObjectMapper(); JsonNode root = om.readTree(jsonFile); @@ -196,11 +125,11 @@ public class StartupSettings { if (cluster == null){ throw new IllegalArgumentException("cluster was null. It is required"); } - String transportClass = jsonObject.has("transport_manager_class") ? - jsonObject.get("transport_manager_class").textValue() : + String transportClass = jsonObject.has("transport_manager_class") ? + jsonObject.get("transport_manager_class").textValue() : null; - String protocolClass = jsonObject.has("protocol_manager_class") ? - jsonObject.get("protocol_manager_class").textValue() : + String protocolClass = jsonObject.has("protocol_manager_class") ? + jsonObject.get("protocol_manager_class").textValue() : null; URI uri2 = new URI(uri); GossipSettings gossipSettings = new GossipSettings(gossipInterval, cleanupInterval, windowSize, @@ -215,17 +144,79 @@ public class StartupSettings { StartupSettings settings = new StartupSettings(id, uri2, gossipSettings, cluster); String configMembersDetails = "Config-members ["; JsonNode membersJSON = jsonObject.get("members"); - Iterator 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()); - settings.addGossipMember(member); - configMembersDetails += member.computeAddress(); - configMembersDetails += ", "; - } + for (JsonNode child : membersJSON) { + URI uri3 = new URI(child.get("uri").textValue()); + RemoteMember member = new RemoteMember(child.get("cluster").asText(), + uri3, "", 0, new HashMap() + ); + settings.addGossipMember(member); + configMembersDetails += member.computeAddress(); + configMembersDetails += ", "; + } log.info(configMembersDetails + "]"); return settings; } + + public URI getUri() { + return uri; + } + + public void setUri(URI uri) { + this.uri = uri; + } + + public String getCluster() { + return cluster; + } + + public void setCluster(String cluster) { + this.cluster = cluster; + } + + /** + * Get the id for this service. + * + * @return the service's id. + */ + public String getId() { + return id; + } + + /** + * 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 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 getGossipMembers() { + return gossipMembers; + } } diff --git a/gossip-base/src/main/java/org/apache/gossip/accrual/FailureDetector.java b/gossip-base/src/main/java/org/apache/gossip/accrual/FailureDetector.java index 5abd5c6..0166bae 100644 --- a/gossip-base/src/main/java/org/apache/gossip/accrual/FailureDetector.java +++ b/gossip-base/src/main/java/org/apache/gossip/accrual/FailureDetector.java @@ -17,19 +17,19 @@ */ 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; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.math3.distribution.ExponentialDistribution; +import org.apache.commons.math3.distribution.NormalDistribution; +import org.apache.commons.math3.exception.MathArithmeticException; +import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; +@Slf4j 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; + private volatile long latestHeartbeatMs = -1; public FailureDetector(long minimumSamples, int windowSize, String distribution) { descriptiveStatistics = new DescriptiveStatistics(windowSize); @@ -62,18 +62,18 @@ public class FailureDetector { 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); + standardDeviation = Math.max(standardDeviation, 0.1); + probability = new NormalDistribution(descriptiveStatistics.getMean(), standardDeviation).cumulativeProbability(delta); } else { - probability = new ExponentialDistributionImpl(descriptiveStatistics.getMean()).cumulativeProbability(delta); + probability = new ExponentialDistribution(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); + } catch (MathArithmeticException | IllegalArgumentException e) { + log.error("Error!", e); return null; } } diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/Crdt.java b/gossip-base/src/main/java/org/apache/gossip/crdt/Crdt.java index 8edfa8c..44cf8f3 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/Crdt.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/Crdt.java @@ -16,24 +16,24 @@ * limitations under the License. */ package org.apache.gossip.crdt; + /** - * - * Immutable type + * Immutable type * * @param * @param */ public interface Crdt> { - 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 + * 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(); - } diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtAddRemoveSet.java b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtAddRemoveSet.java index 6d44735..84b19a2 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtAddRemoveSet.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtAddRemoveSet.java @@ -19,10 +19,14 @@ package org.apache.gossip.crdt; import java.util.Set; -// Interface extends CrdtSet interface with add and remove operation that are guaranteed to be immutable. -// If your implementation provide immutable add/remove operations you can extend AbstractCRDTStringSetTest to check it in the most ways. +// Interface extends CrdtSet interface with add and remove operation that are guaranteed to be +// immutable. +// If your implementation provide immutable add/remove operations you can extend +// AbstractCRDTStringSetTest to check it in the most ways. -public interface CrdtAddRemoveSet, R extends CrdtAddRemoveSet> extends CrdtSet { +public interface CrdtAddRemoveSet< + T, SetType extends Set, R extends CrdtAddRemoveSet> + extends CrdtSet { R add(T element); R remove(T element); diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtBiFunctionMerge.java b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtBiFunctionMerge.java index 1ac7a30..b45916f 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtBiFunctionMerge.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtBiFunctionMerge.java @@ -20,35 +20,35 @@ package org.apache.gossip.crdt; import java.util.function.BiFunction; @SuppressWarnings("rawtypes") -public class CrdtBiFunctionMerge implements BiFunction { +public class CrdtBiFunctionMerge implements BiFunction { + + @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); + } @SuppressWarnings("unchecked") @Override public Crdt apply(Crdt t, Crdt u) { - if (t == null && u == null){ + if (t == null && u == null) { return null; - } else if (t == null){ + } else if (t == null) { return u; - } else if (u == null){ + } 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()); + if (!u.getClass().equals(t.getClass())) { + throw new IllegalArgumentException("Can not merge " + t.getClass() + " " + u.getClass()); } return t.merge(u); } diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtCounter.java b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtCounter.java index cdc9445..e5d15fb 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtCounter.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtCounter.java @@ -18,7 +18,4 @@ package org.apache.gossip.crdt; public interface CrdtCounter> - extends Crdt { - -} - + extends Crdt {} diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtModule.java b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtModule.java index 83d573d..1a869bb 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtModule.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtModule.java @@ -23,6 +23,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.module.SimpleModule; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import org.apache.gossip.LocalMember; import org.apache.gossip.lock.vote.MajorityVote; import org.apache.gossip.lock.vote.Vote; @@ -31,11 +35,6 @@ import org.apache.gossip.replication.BlackListReplicable; import org.apache.gossip.replication.Replicable; import org.apache.gossip.replication.WhiteListReplicable; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - abstract class OrSetMixin { @JsonCreator OrSetMixin(@JsonProperty("elements") Map> w, @JsonProperty("tombstones") Map> h) { } diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtSet.java b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtSet.java index 21b41da..a9290d0 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtSet.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/CrdtSet.java @@ -19,8 +19,6 @@ package org.apache.gossip.crdt; import java.util.Set; -public interface CrdtSet, R extends CrdtSet> -extends Crdt { - -} - +public interface CrdtSet< + ElementType, SetType extends Set, R extends CrdtSet> + extends Crdt {} diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/GrowOnlyCounter.java b/gossip-base/src/main/java/org/apache/gossip/crdt/GrowOnlyCounter.java index dd1505a..63f76ac 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/GrowOnlyCounter.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/GrowOnlyCounter.java @@ -18,10 +18,9 @@ package org.apache.gossip.crdt; -import org.apache.gossip.manager.GossipManager; - import java.util.HashMap; import java.util.Map; +import org.apache.gossip.manager.GossipManager; public class GrowOnlyCounter implements CrdtCounter { diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/GrowOnlySet.java b/gossip-base/src/main/java/org/apache/gossip/crdt/GrowOnlySet.java index 9e2dd49..b2026fd 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/GrowOnlySet.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/GrowOnlySet.java @@ -24,31 +24,30 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; -public class GrowOnlySet implements CrdtSet, GrowOnlySet>{ +public class GrowOnlySet + implements CrdtSet, GrowOnlySet> { private final Set hidden = new LinkedHashSet<>(); - + @SuppressWarnings("unused") /* * Used by SerDe */ - private GrowOnlySet(){ - - } - - public GrowOnlySet(Set c){ + private GrowOnlySet() {} + + public GrowOnlySet(Set c) { hidden.addAll(c); } - - public GrowOnlySet(Collection c){ + + public GrowOnlySet(Collection c) { hidden.addAll(c); } - - public GrowOnlySet(GrowOnlySet first, GrowOnlySet second){ + + public GrowOnlySet(GrowOnlySet first, GrowOnlySet second) { hidden.addAll(first.value()); hidden.addAll(second.value()); } - + @Override public GrowOnlySet merge(GrowOnlySet other) { return new GrowOnlySet<>(this, other); @@ -60,7 +59,7 @@ public class GrowOnlySet implements CrdtSet optimize() { return new GrowOnlySet<>(hidden); @@ -135,23 +134,18 @@ public class GrowOnlySet implements CrdtSet getElements(){ + Set getElements() { return hidden; } } diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/LwwSet.java b/gossip-base/src/main/java/org/apache/gossip/crdt/LwwSet.java index 391cb09..190b08d 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/LwwSet.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/LwwSet.java @@ -17,9 +17,6 @@ */ package org.apache.gossip.crdt; -import org.apache.gossip.manager.Clock; -import org.apache.gossip.manager.SystemClock; - import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -28,6 +25,8 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.gossip.manager.Clock; +import org.apache.gossip.manager.SystemClock; /* Last write wins CrdtSet @@ -49,6 +48,82 @@ public class LwwSet implements CrdtAddRemoveSet struct; + public LwwSet(){ + struct = new HashMap<>(); + } + + + @SafeVarargs + public LwwSet(ElementType... elements){ + this(new HashSet<>(Arrays.asList(elements))); + } + + public LwwSet(Set set){ + struct = new HashMap<>(); + for (ElementType e : set){ + struct.put(e, new Timestamps().updateAdd()); + } + } + + public LwwSet(LwwSet first, LwwSet second){ + Function timestampsFor = p -> { + Timestamps firstTs = first.struct.get(p); + Timestamps secondTs = second.struct.get(p); + if (firstTs == null){ + return secondTs; + } + return firstTs.merge(secondTs); + }; + struct = Stream.concat(first.struct.keySet().stream(), second.struct.keySet().stream()) + .distinct().collect(Collectors.toMap(p -> p, timestampsFor)); + } + + // for serialization + LwwSet(Map struct){ + this.struct = struct; + } + + public LwwSet add(ElementType e){ + return this.merge(new LwwSet<>(e)); + } + + Map getStruct(){ + return struct; + } + + public LwwSet remove(ElementType e){ + Timestamps eTimestamps = struct.get(e); + if (eTimestamps == null || !eTimestamps.isPresent()){ + return this; + } + Map changeMap = new HashMap<>(); + changeMap.put(e, eTimestamps.updateRemove()); + return this.merge(new LwwSet<>(changeMap)); + } + + @Override + public LwwSet merge(LwwSet other){ + return new LwwSet<>(this, other); + } + + @Override + public Set value(){ + return struct.entrySet().stream() + .filter(entry -> entry.getValue().isPresent()) + .map(Map.Entry::getKey) + .collect(Collectors.toSet()); + } + + @Override + public LwwSet optimize(){ + return this; + } + + @Override + public boolean equals(Object obj){ + return this == obj || (obj != null && getClass() == obj.getClass() && value().equals(((LwwSet) obj).value())); + } + static class Timestamps { private final long latestAdd; private final long latestRemove; @@ -91,81 +166,4 @@ public class LwwSet implements CrdtAddRemoveSet(); - } - - @SafeVarargs - public LwwSet(ElementType... elements){ - this(new HashSet<>(Arrays.asList(elements))); - } - - public LwwSet(Set set){ - struct = new HashMap<>(); - for (ElementType e : set){ - struct.put(e, new Timestamps().updateAdd()); - } - } - - public LwwSet(LwwSet first, LwwSet second){ - Function timestampsFor = p -> { - Timestamps firstTs = first.struct.get(p); - Timestamps secondTs = second.struct.get(p); - if (firstTs == null){ - return secondTs; - } - return firstTs.merge(secondTs); - }; - struct = Stream.concat(first.struct.keySet().stream(), second.struct.keySet().stream()) - .distinct().collect(Collectors.toMap(p -> p, timestampsFor)); - } - - public LwwSet add(ElementType e){ - return this.merge(new LwwSet<>(e)); - } - - // for serialization - LwwSet(Map struct){ - this.struct = struct; - } - - Map getStruct(){ - return struct; - } - - - public LwwSet remove(ElementType e){ - Timestamps eTimestamps = struct.get(e); - if (eTimestamps == null || !eTimestamps.isPresent()){ - return this; - } - Map changeMap = new HashMap<>(); - changeMap.put(e, eTimestamps.updateRemove()); - return this.merge(new LwwSet<>(changeMap)); - } - - @Override - public LwwSet merge(LwwSet other){ - return new LwwSet<>(this, other); - } - - @Override - public Set value(){ - return struct.entrySet().stream() - .filter(entry -> entry.getValue().isPresent()) - .map(Map.Entry::getKey) - .collect(Collectors.toSet()); - } - - @Override - public LwwSet optimize(){ - return this; - } - - @Override - public boolean equals(Object obj){ - return this == obj || (obj != null && getClass() == obj.getClass() && value().equals(((LwwSet) obj).value())); - } } \ No newline at end of file diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/MaxChangeSet.java b/gossip-base/src/main/java/org/apache/gossip/crdt/MaxChangeSet.java index 0b72b80..3677c7e 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/MaxChangeSet.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/MaxChangeSet.java @@ -37,68 +37,72 @@ import java.util.stream.Stream; DataTest - integration test with 2 nodes, MaxChangeSet was serialized/deserialized, sent between nodes, merged */ -public class MaxChangeSet implements CrdtAddRemoveSet, MaxChangeSet> { +public class MaxChangeSet + implements CrdtAddRemoveSet, MaxChangeSet> { private final Map struct; - public MaxChangeSet(){ + public MaxChangeSet() { struct = new HashMap<>(); } @SafeVarargs - public MaxChangeSet(ElementType... elements){ + public MaxChangeSet(ElementType... elements) { this(new HashSet<>(Arrays.asList(elements))); } - public MaxChangeSet(Set set){ + public MaxChangeSet(Set set) { struct = new HashMap<>(); - for (ElementType e : set){ + for (ElementType e : set) { struct.put(e, 1); } } - public MaxChangeSet(MaxChangeSet first, MaxChangeSet second){ - Function valueFor = element -> - Math.max(first.struct.getOrDefault(element, 0), second.struct.getOrDefault(element, 0)); - struct = Stream.concat(first.struct.keySet().stream(), second.struct.keySet().stream()) - .distinct().collect(Collectors.toMap(p -> p, valueFor)); + public MaxChangeSet(MaxChangeSet first, MaxChangeSet second) { + Function valueFor = + element -> + Math.max(first.struct.getOrDefault(element, 0), second.struct.getOrDefault(element, 0)); + struct = + Stream.concat(first.struct.keySet().stream(), second.struct.keySet().stream()) + .distinct() + .collect(Collectors.toMap(p -> p, valueFor)); } // for serialization - MaxChangeSet(Map struct){ + MaxChangeSet(Map struct) { this.struct = struct; } - Map getStruct(){ + Map getStruct() { return struct; } - private MaxChangeSet increment(ElementType e){ + private MaxChangeSet increment(ElementType e) { Map changeMap = new HashMap<>(); changeMap.put(e, struct.getOrDefault(e, 0) + 1); return this.merge(new MaxChangeSet<>(changeMap)); } - public MaxChangeSet add(ElementType e){ - if (struct.getOrDefault(e, 0) % 2 == 1){ + public MaxChangeSet add(ElementType e) { + if (struct.getOrDefault(e, 0) % 2 == 1) { return this; } return increment(e); } - public MaxChangeSet remove(ElementType e){ - if (struct.getOrDefault(e, 0) % 2 == 0){ + public MaxChangeSet remove(ElementType e) { + if (struct.getOrDefault(e, 0) % 2 == 0) { return this; } return increment(e); } @Override - public MaxChangeSet merge(MaxChangeSet other){ + public MaxChangeSet merge(MaxChangeSet other) { return new MaxChangeSet<>(this, other); } @Override - public Set value(){ + public Set value() { return struct.entrySet().stream() .filter(entry -> (entry.getValue() % 2 == 1)) .map(Map.Entry::getKey) @@ -106,12 +110,15 @@ public class MaxChangeSet implements CrdtAddRemoveSet optimize(){ + public MaxChangeSet optimize() { return this; } @Override - public boolean equals(Object obj){ - return this == obj || (obj != null && getClass() == obj.getClass() && value().equals(((MaxChangeSet) obj).value())); + public boolean equals(Object obj) { + return this == obj + || (obj != null + && getClass() == obj.getClass() + && value().equals(((MaxChangeSet) obj).value())); } -} \ No newline at end of file +} diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/OrSet.java b/gossip-base/src/main/java/org/apache/gossip/crdt/OrSet.java index 68b089a..7bbd2a3 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/OrSet.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/OrSet.java @@ -20,7 +20,6 @@ package org.apache.gossip.crdt; import java.util.*; import java.util.Map.Entry; import java.util.function.BiConsumer; - import org.apache.gossip.crdt.OrSet.Builder.Operation; /* @@ -83,6 +82,21 @@ public class OrSet implements CrdtAddRemoveSet, OrSet> { val = computeValue(); } + public OrSet(OrSet left, OrSet right){ + BiConsumer>, Map>> internalMerge = (items, other) -> { + for (Entry> l : other.entrySet()){ + internalSetMerge(items, l.getKey(), l.getValue()); + } + }; + + internalMerge.accept(elements, left.elements); + internalMerge.accept(elements, right.elements); + internalMerge.accept(tombstones, left.tombstones); + internalMerge.accept(tombstones, right.tombstones); + + val = computeValue(); + } + static Set mergeSets(Set a, Set b) { if ((a == null || a.isEmpty()) && (b == null || b.isEmpty())) { return null; @@ -99,21 +113,6 @@ public class OrSet implements CrdtAddRemoveSet, OrSet> { map.merge(key, value, OrSet::mergeSets); } - public OrSet(OrSet left, OrSet right){ - BiConsumer>, Map>> internalMerge = (items, other) -> { - for (Entry> l : other.entrySet()){ - internalSetMerge(items, l.getKey(), l.getValue()); - } - }; - - internalMerge.accept(elements, left.elements); - internalMerge.accept(elements, right.elements); - internalMerge.accept(tombstones, left.tombstones); - internalMerge.accept(tombstones, right.tombstones); - - val = computeValue(); - } - public OrSet add(E e) { return this.merge(new OrSet<>(e)); } @@ -166,55 +165,18 @@ public class OrSet implements CrdtAddRemoveSet, OrSet> { return this; } - public static class Builder { - public static enum Operation { - ADD, REMOVE - }; - - private class OrSetElement { - EL element; - Operation operation; - - private OrSetElement(EL element, Operation operation) { - this.element = element; - this.operation = operation; - } - } - - private List> elements = new ArrayList<>(); - - public Builder add(E element) { - elements.add(new OrSetElement(element, Operation.ADD)); - return this; - } - - public Builder remove(E element) { - elements.add(new OrSetElement(element, Operation.REMOVE)); - return this; - } - - public Builder mutate(E element, Operation operation) { - elements.add(new OrSetElement(element, operation)); - return this; - } - } - - public int size() { return value().size(); } - public boolean isEmpty() { return value().size() == 0; } - public boolean contains(Object o) { return value().contains(o); } - public Iterator iterator() { Iterator managed = value().iterator(); return new Iterator() { @@ -233,7 +195,7 @@ public class OrSet implements CrdtAddRemoveSet, OrSet> { public E next() { return managed.next(); } - + }; } @@ -304,4 +266,37 @@ public class OrSet implements CrdtAddRemoveSet, OrSet> { return tombstones; } + public static class Builder { + private List> elements = new ArrayList<>();; + + public Builder add(E element) { + elements.add(new OrSetElement(element, Operation.ADD)); + return this; + } + + public Builder remove(E element) { + elements.add(new OrSetElement(element, Operation.REMOVE)); + return this; + } + + public Builder mutate(E element, Operation operation) { + elements.add(new OrSetElement(element, operation)); + return this; + } + +public static enum Operation { + ADD, REMOVE + } + + private class OrSetElement { + EL element; + Operation operation; + + private OrSetElement(EL element, Operation operation) { + this.element = element; + this.operation = operation; + } + } + } + } diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/PNCounter.java b/gossip-base/src/main/java/org/apache/gossip/crdt/PNCounter.java index f00a5f1..21286f6 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/PNCounter.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/PNCounter.java @@ -18,7 +18,6 @@ package org.apache.gossip.crdt; import java.util.Map; - import org.apache.gossip.manager.GossipManager; public class PNCounter implements CrdtCounter { diff --git a/gossip-base/src/main/java/org/apache/gossip/crdt/TwoPhaseSet.java b/gossip-base/src/main/java/org/apache/gossip/crdt/TwoPhaseSet.java index a1f44a9..b0fa4d3 100644 --- a/gossip-base/src/main/java/org/apache/gossip/crdt/TwoPhaseSet.java +++ b/gossip-base/src/main/java/org/apache/gossip/crdt/TwoPhaseSet.java @@ -36,57 +36,58 @@ import java.util.stream.Stream; DataTest - integration test with 2 nodes, TwoPhaseSet was serialized/deserialized, sent between nodes, merged */ -public class TwoPhaseSet implements CrdtAddRemoveSet, TwoPhaseSet> { +public class TwoPhaseSet + implements CrdtAddRemoveSet, TwoPhaseSet> { private final Set added; private final Set removed; - public TwoPhaseSet(){ + public TwoPhaseSet() { added = new HashSet<>(); removed = new HashSet<>(); } @SafeVarargs - public TwoPhaseSet(ElementType... elements){ + public TwoPhaseSet(ElementType... elements) { this(new HashSet<>(Arrays.asList(elements))); } - public TwoPhaseSet(Set set){ + public TwoPhaseSet(Set set) { this(); - for (ElementType e : set){ + for (ElementType e : set) { added.add(e); } } - public TwoPhaseSet(TwoPhaseSet first, TwoPhaseSet second){ - BiFunction, Set, Set> mergeSets = (f, s) -> - Stream.concat(f.stream(), s.stream()).collect(Collectors.toSet()); + public TwoPhaseSet(TwoPhaseSet first, TwoPhaseSet second) { + BiFunction, Set, Set> mergeSets = + (f, s) -> Stream.concat(f.stream(), s.stream()).collect(Collectors.toSet()); added = mergeSets.apply(first.added, second.added); removed = mergeSets.apply(first.removed, second.removed); } - TwoPhaseSet(Set added, Set removed){ + TwoPhaseSet(Set added, Set removed) { this.added = added; this.removed = removed; } - Set getAdded(){ + Set getAdded() { return added; } - Set getRemoved(){ + Set getRemoved() { return removed; } - public TwoPhaseSet add(ElementType e){ - if (removed.contains(e) || added.contains(e)){ + public TwoPhaseSet add(ElementType e) { + if (removed.contains(e) || added.contains(e)) { return this; } return this.merge(new TwoPhaseSet<>(e)); } - public TwoPhaseSet remove(ElementType e){ - if (removed.contains(e) || !added.contains(e)){ + public TwoPhaseSet remove(ElementType e) { + if (removed.contains(e) || !added.contains(e)) { return this; } Set eSet = new HashSet<>(Collections.singletonList(e)); @@ -94,22 +95,25 @@ public class TwoPhaseSet implements CrdtAddRemoveSet merge(TwoPhaseSet other){ + public TwoPhaseSet merge(TwoPhaseSet other) { return new TwoPhaseSet<>(this, other); } @Override - public Set value(){ + public Set value() { return added.stream().filter(e -> !removed.contains(e)).collect(Collectors.toSet()); } @Override - public TwoPhaseSet optimize(){ + public TwoPhaseSet optimize() { return new TwoPhaseSet<>(value(), removed); } @Override - public boolean equals(Object obj){ - return this == obj || (obj != null && getClass() == obj.getClass() && value().equals(((TwoPhaseSet) obj).value())); + public boolean equals(Object obj) { + return this == obj + || (obj != null + && getClass() == obj.getClass() + && value().equals(((TwoPhaseSet) obj).value())); } -} \ No newline at end of file +} diff --git a/gossip-base/src/main/java/org/apache/gossip/event/GossipState.java b/gossip-base/src/main/java/org/apache/gossip/event/GossipState.java index 3b76c9e..085db34 100644 --- a/gossip-base/src/main/java/org/apache/gossip/event/GossipState.java +++ b/gossip-base/src/main/java/org/apache/gossip/event/GossipState.java @@ -18,7 +18,9 @@ package org.apache.gossip.event; public enum GossipState { - UP("up"), DOWN("down"); + UP("up"), + DOWN("down"); + @SuppressWarnings("unused") private final String state; diff --git a/gossip-base/src/main/java/org/apache/gossip/event/data/DataEventConstants.java b/gossip-base/src/main/java/org/apache/gossip/event/data/DataEventConstants.java index 217087f..131f888 100644 --- a/gossip-base/src/main/java/org/apache/gossip/event/data/DataEventConstants.java +++ b/gossip-base/src/main/java/org/apache/gossip/event/data/DataEventConstants.java @@ -18,17 +18,17 @@ package org.apache.gossip.event.data; public class DataEventConstants { - + // MetricRegistry - public static final String PER_NODE_DATA_SUBSCRIBERS_SIZE - = "gossip.event.data.pernode.subscribers.size"; - public static final String PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE - = "gossip.event.data.pernode.subscribers.queue.size"; - public static final String SHARED_DATA_SUBSCRIBERS_SIZE - = "gossip.event.data.shared.subscribers.size"; - public static final String SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE - = "gossip.event.data.shared.subscribers.queue.size"; - + public static final String PER_NODE_DATA_SUBSCRIBERS_SIZE = + "gossip.event.data.pernode.subscribers.size"; + public static final String PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE = + "gossip.event.data.pernode.subscribers.queue.size"; + public static final String SHARED_DATA_SUBSCRIBERS_SIZE = + "gossip.event.data.shared.subscribers.size"; + public static final String SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE = + "gossip.event.data.shared.subscribers.queue.size"; + // Thread pool public static final int PER_NODE_DATA_QUEUE_SIZE = 64; public static final int PER_NODE_DATA_CORE_POOL_SIZE = 1; @@ -38,5 +38,4 @@ public class DataEventConstants { public static final int SHARED_DATA_CORE_POOL_SIZE = 1; public static final int SHARED_DATA_MAX_POOL_SIZE = 30; public static final int SHARED_DATA_KEEP_ALIVE_TIME_SECONDS = 1; - } diff --git a/gossip-base/src/main/java/org/apache/gossip/event/data/DataEventManager.java b/gossip-base/src/main/java/org/apache/gossip/event/data/DataEventManager.java index 3124df1..2e4e4a3 100644 --- a/gossip-base/src/main/java/org/apache/gossip/event/data/DataEventManager.java +++ b/gossip-base/src/main/java/org/apache/gossip/event/data/DataEventManager.java @@ -29,74 +29,86 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class DataEventManager { - + private final List perNodeDataHandlers; private final BlockingQueue perNodeDataHandlerQueue; private final ExecutorService perNodeDataEventExecutor; private final List sharedDataHandlers; private final BlockingQueue sharedDataHandlerQueue; private final ExecutorService sharedDataEventExecutor; - + public DataEventManager(MetricRegistry metrics) { perNodeDataHandlers = new CopyOnWriteArrayList<>(); perNodeDataHandlerQueue = new ArrayBlockingQueue<>(DataEventConstants.PER_NODE_DATA_QUEUE_SIZE); - perNodeDataEventExecutor = new ThreadPoolExecutor( + perNodeDataEventExecutor = + new ThreadPoolExecutor( DataEventConstants.PER_NODE_DATA_CORE_POOL_SIZE, DataEventConstants.PER_NODE_DATA_MAX_POOL_SIZE, - DataEventConstants.PER_NODE_DATA_KEEP_ALIVE_TIME_SECONDS, TimeUnit.SECONDS, - perNodeDataHandlerQueue, new ThreadPoolExecutor.DiscardOldestPolicy()); - + DataEventConstants.PER_NODE_DATA_KEEP_ALIVE_TIME_SECONDS, + TimeUnit.SECONDS, + perNodeDataHandlerQueue, + new ThreadPoolExecutor.DiscardOldestPolicy()); + sharedDataHandlers = new CopyOnWriteArrayList<>(); sharedDataHandlerQueue = new ArrayBlockingQueue<>(DataEventConstants.SHARED_DATA_QUEUE_SIZE); - sharedDataEventExecutor = new ThreadPoolExecutor(DataEventConstants.SHARED_DATA_CORE_POOL_SIZE, + sharedDataEventExecutor = + new ThreadPoolExecutor( + DataEventConstants.SHARED_DATA_CORE_POOL_SIZE, DataEventConstants.SHARED_DATA_MAX_POOL_SIZE, - DataEventConstants.SHARED_DATA_KEEP_ALIVE_TIME_SECONDS, TimeUnit.SECONDS, - sharedDataHandlerQueue, new ThreadPoolExecutor.DiscardOldestPolicy()); - - metrics.register(DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_SIZE, - (Gauge) () -> perNodeDataHandlers.size()); - metrics.register(DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE, - (Gauge) () -> perNodeDataHandlerQueue.size()); - metrics.register(DataEventConstants.SHARED_DATA_SUBSCRIBERS_SIZE, - (Gauge) () -> sharedDataHandlers.size()); - metrics.register(DataEventConstants.SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE, - (Gauge) () -> sharedDataHandlerQueue.size()); - + DataEventConstants.SHARED_DATA_KEEP_ALIVE_TIME_SECONDS, + TimeUnit.SECONDS, + sharedDataHandlerQueue, + new ThreadPoolExecutor.DiscardOldestPolicy()); + + metrics.register( + DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_SIZE, + (Gauge) () -> perNodeDataHandlers.size()); + metrics.register( + DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE, + (Gauge) () -> perNodeDataHandlerQueue.size()); + metrics.register( + DataEventConstants.SHARED_DATA_SUBSCRIBERS_SIZE, + (Gauge) () -> sharedDataHandlers.size()); + metrics.register( + DataEventConstants.SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE, + (Gauge) () -> sharedDataHandlerQueue.size()); } - + public void notifySharedData(final String key, final Object newValue, final Object oldValue) { - sharedDataHandlers.forEach(handler -> sharedDataEventExecutor - .execute(() -> handler.onUpdate(key, oldValue, newValue))); + sharedDataHandlers.forEach( + handler -> + sharedDataEventExecutor.execute(() -> handler.onUpdate(key, oldValue, newValue))); } - - public void notifyPerNodeData(final String nodeId, final String key, final Object newValue, - final Object oldValue) { - perNodeDataHandlers.forEach(handler -> perNodeDataEventExecutor - .execute(() -> handler.onUpdate(nodeId, key, oldValue, newValue))); + + public void notifyPerNodeData( + final String nodeId, final String key, final Object newValue, final Object oldValue) { + perNodeDataHandlers.forEach( + handler -> + perNodeDataEventExecutor.execute( + () -> handler.onUpdate(nodeId, key, oldValue, newValue))); } - + public void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler) { perNodeDataHandlers.add(handler); } - + public void unregisterPerNodeDataSubscriber(UpdateNodeDataEventHandler handler) { perNodeDataHandlers.remove(handler); } - + public int getPerNodeSubscribersSize() { return perNodeDataHandlers.size(); } - + public void registerSharedDataSubscriber(UpdateSharedDataEventHandler handler) { sharedDataHandlers.add(handler); } - + public void unregisterSharedDataSubscriber(UpdateSharedDataEventHandler handler) { sharedDataHandlers.remove(handler); } - + public int getSharedDataSubscribersSize() { return sharedDataHandlers.size(); } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/event/data/UpdateNodeDataEventHandler.java b/gossip-base/src/main/java/org/apache/gossip/event/data/UpdateNodeDataEventHandler.java index ca88c17..d887ca8 100644 --- a/gossip-base/src/main/java/org/apache/gossip/event/data/UpdateNodeDataEventHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/event/data/UpdateNodeDataEventHandler.java @@ -18,20 +18,19 @@ package org.apache.gossip.event.data; /** - * Event handler interface for the per node data items. - * Classes which implement this interface get notifications when per node data item get changed. + * Event handler interface for the per node data items. Classes which implement this interface get + * notifications when per node data item get changed. */ public interface UpdateNodeDataEventHandler { - + /** * This method get called when a per node datum get changed. * - * @param nodeId id of the node that change the value - * @param key key of the datum - * @param oldValue previous value of the datum or null if the datum is discovered - * for the first time + * @param nodeId id of the node that change the value + * @param key key of the datum + * @param oldValue previous value of the datum or null if the datum is discovered for the first + * time * @param newValue updated value of the datum */ void onUpdate(String nodeId, String key, Object oldValue, Object newValue); - } diff --git a/gossip-base/src/main/java/org/apache/gossip/event/data/UpdateSharedDataEventHandler.java b/gossip-base/src/main/java/org/apache/gossip/event/data/UpdateSharedDataEventHandler.java index 5655732..c624e32 100644 --- a/gossip-base/src/main/java/org/apache/gossip/event/data/UpdateSharedDataEventHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/event/data/UpdateSharedDataEventHandler.java @@ -18,17 +18,16 @@ package org.apache.gossip.event.data; /** - * Event handler interface for shared data items. - * Classes which implement this interface get notifications when shared data get changed. + * Event handler interface for shared data items. Classes which implement this interface get + * notifications when shared data get changed. */ public interface UpdateSharedDataEventHandler { /** * This method get called when shared data get changed. * - * @param key key of the shared data item + * @param key key of the shared data item * @param oldValue previous value or null if the data is discovered for the first time * @param newValue updated value of the data item */ void onUpdate(String key, Object oldValue, Object newValue); - } diff --git a/gossip-base/src/main/java/org/apache/gossip/lock/LockManager.java b/gossip-base/src/main/java/org/apache/gossip/lock/LockManager.java index 9f4636a..58e2a12 100644 --- a/gossip-base/src/main/java/org/apache/gossip/lock/LockManager.java +++ b/gossip-base/src/main/java/org/apache/gossip/lock/LockManager.java @@ -20,15 +20,6 @@ package org.apache.gossip.lock; import com.codahale.metrics.Gauge; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; -import org.apache.gossip.Member; -import org.apache.gossip.lock.exceptions.VoteFailedException; -import org.apache.gossip.lock.vote.MajorityVote; -import org.apache.gossip.lock.vote.Vote; -import org.apache.gossip.lock.vote.VoteCandidate; -import org.apache.gossip.manager.GossipManager; -import org.apache.gossip.model.SharedDataMessage; -import org.apache.log4j.Logger; - import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -43,19 +34,27 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.apache.gossip.Member; +import org.apache.gossip.lock.exceptions.VoteFailedException; +import org.apache.gossip.lock.vote.MajorityVote; +import org.apache.gossip.lock.vote.Vote; +import org.apache.gossip.lock.vote.VoteCandidate; +import org.apache.gossip.manager.GossipManager; +import org.apache.gossip.model.SharedDataMessage; +@Slf4j public class LockManager { - public static final Logger LOGGER = Logger.getLogger(LockManager.class); + // For MetricRegistry + public static final String LOCK_KEY_SET_SIZE = "gossip.lock.key_set_size"; + public static final String LOCK_TIME = "gossip.lock.time"; private final GossipManager gossipManager; private final LockManagerSettings lockSettings; private final ScheduledExecutorService voteService; private final AtomicInteger numberOfNodes; private final Set lockKeys; - // For MetricRegistry - public static final String LOCK_KEY_SET_SIZE = "gossip.lock.key_set_size"; - public static final String LOCK_TIME = "gossip.lock.time"; private final Timer lockTimeMetric; public LockManager(GossipManager gossipManager, final LockManagerSettings lockManagerSettings, @@ -95,20 +94,16 @@ public class LockManager { long passedCandidates = voteResultMap.values().stream().filter(aBoolean -> aBoolean).count(); String myNodeId = gossipManager.getMyself().getId(); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("NodeId=" + myNodeId + ", VoteMap=" + voteResultMap + ", WinnerCount=" + log.debug("NodeId=" + myNodeId + ", VoteMap=" + voteResultMap + ", WinnerCount=" + passedCandidates); - } // Check for possible dead lock when no candidates were won if (passedCandidates == 0) { if (isDeadLock(voteCandidatesMap)) { deadlockDetectCount++; // Testing for deadlock is not always correct, therefore test for continues deadlocks if (deadlockDetectCount >= lockSettings.getDeadlockDetectionThreshold()) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Deadlock detected from node " + myNodeId + ". VoteCandidatesMap=" + log.debug("Deadlock detected from node " + myNodeId + ". VoteCandidatesMap=" + voteCandidatesMap); - } preventDeadLock(voteCandidatesMap); } } else { @@ -251,9 +246,7 @@ public class LockManager { } } } - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Node " + myNodeId + " give up votes to node " + selectedCandidateId); - } + log.debug("Node " + myNodeId + " give up votes to node " + selectedCandidateId); } private String getVotedCandidateNodeId(String nodeId, diff --git a/gossip-base/src/main/java/org/apache/gossip/lock/LockManagerSettings.java b/gossip-base/src/main/java/org/apache/gossip/lock/LockManagerSettings.java index 4af47a2..e225ab8 100644 --- a/gossip-base/src/main/java/org/apache/gossip/lock/LockManagerSettings.java +++ b/gossip-base/src/main/java/org/apache/gossip/lock/LockManagerSettings.java @@ -20,9 +20,7 @@ package org.apache.gossip.lock; import org.apache.gossip.lock.vote.RandomVoteSelector; import org.apache.gossip.lock.vote.VoteSelector; -/** - * Stores the lock manager related settings. - */ +/** Stores the lock manager related settings. */ public class LockManagerSettings { // Time between vote updates in ms. Default is 1 second. private final int voteUpdateInterval; @@ -35,30 +33,32 @@ public class LockManagerSettings { // Wait time between vote result calculation. Default is 1000 private final int resultCalculationDelay; - /** - * Construct LockManagerSettings with default settings. - */ - public static LockManagerSettings getLockManagerDefaultSettings() { - return new LockManagerSettings(1000, new RandomVoteSelector(), -1, 3, 1000); - } - /** * Construct a custom LockManagerSettings * - * @param voteUpdateInterval Time between vote updates in milliseconds. - * @param voteSelector Vote selection algorithm. Cannot be null - * @param numberOfNodes Number of nodes available for voting. Set to negative value for auto calculate + * @param voteUpdateInterval Time between vote updates in milliseconds. + * @param voteSelector Vote selection algorithm. Cannot be null + * @param numberOfNodes Number of nodes available for voting. Set to negative value for auto + * calculate * @param deadlockDetectionThreshold Number of times to test for deadlock before preventing - * @param resultCalculationDelay Wait time between vote result calculation + * @param resultCalculationDelay Wait time between vote result calculation */ - public LockManagerSettings(int voteUpdateInterval, VoteSelector voteSelector, int numberOfNodes, - int deadlockDetectionThreshold, int resultCalculationDelay) { + public LockManagerSettings( + int voteUpdateInterval, + VoteSelector voteSelector, + int numberOfNodes, + int deadlockDetectionThreshold, + int resultCalculationDelay) { this.voteUpdateInterval = voteUpdateInterval; this.voteSelector = voteSelector; this.numberOfNodes = numberOfNodes; this.deadlockDetectionThreshold = deadlockDetectionThreshold; this.resultCalculationDelay = resultCalculationDelay; + } + /** Construct LockManagerSettings with default settings. */ + public static LockManagerSettings getLockManagerDefaultSettings() { + return new LockManagerSettings(1000, new RandomVoteSelector(), -1, 3, 1000); } public int getVoteUpdateInterval() { diff --git a/gossip-base/src/main/java/org/apache/gossip/lock/exceptions/VoteFailedException.java b/gossip-base/src/main/java/org/apache/gossip/lock/exceptions/VoteFailedException.java index bd0a606..129b06f 100644 --- a/gossip-base/src/main/java/org/apache/gossip/lock/exceptions/VoteFailedException.java +++ b/gossip-base/src/main/java/org/apache/gossip/lock/exceptions/VoteFailedException.java @@ -17,9 +17,7 @@ */ package org.apache.gossip.lock.exceptions; -/** - * This exception is thrown when the lock based voting is failed. - */ +/** This exception is thrown when the lock based voting is failed. */ public class VoteFailedException extends Exception { /** * Constructs a new VoteFailedException with the specified detail message. @@ -31,11 +29,10 @@ public class VoteFailedException extends Exception { } /** - * Constructs a new VoteFailedException with the specified detail message and - * cause. + * Constructs a new VoteFailedException with the specified detail message and cause. * * @param message the detail message - * @param cause the cause for this exception + * @param cause the cause for this exception */ public VoteFailedException(String message, Throwable cause) { super(message, cause); diff --git a/gossip-base/src/main/java/org/apache/gossip/lock/vote/MajorityVote.java b/gossip-base/src/main/java/org/apache/gossip/lock/vote/MajorityVote.java index a18f3c9..24c506e 100644 --- a/gossip-base/src/main/java/org/apache/gossip/lock/vote/MajorityVote.java +++ b/gossip-base/src/main/java/org/apache/gossip/lock/vote/MajorityVote.java @@ -17,14 +17,13 @@ */ package org.apache.gossip.lock.vote; -import org.apache.gossip.crdt.Crdt; - import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import org.apache.gossip.crdt.Crdt; /** * CRDT which used for distribute a votes for a given key. diff --git a/gossip-base/src/main/java/org/apache/gossip/lock/vote/RandomVoteSelector.java b/gossip-base/src/main/java/org/apache/gossip/lock/vote/RandomVoteSelector.java index d07f190..f895e44 100644 --- a/gossip-base/src/main/java/org/apache/gossip/lock/vote/RandomVoteSelector.java +++ b/gossip-base/src/main/java/org/apache/gossip/lock/vote/RandomVoteSelector.java @@ -22,9 +22,7 @@ import java.util.List; import java.util.Random; import java.util.Set; -/** - * VoteSelector implementation which randomly select a voting node. - */ +/** VoteSelector implementation which randomly select a voting node. */ public class RandomVoteSelector implements VoteSelector { @Override diff --git a/gossip-base/src/main/java/org/apache/gossip/lock/vote/Vote.java b/gossip-base/src/main/java/org/apache/gossip/lock/vote/Vote.java index e68401c..bd147a6 100644 --- a/gossip-base/src/main/java/org/apache/gossip/lock/vote/Vote.java +++ b/gossip-base/src/main/java/org/apache/gossip/lock/vote/Vote.java @@ -25,9 +25,9 @@ import java.util.List; public class Vote { private final String votingNode; private final Boolean voteValue; // TODO: 7/16/17 weight? - private Boolean voteExchange; private final List liveMembers; private final List deadMembers; + private Boolean voteExchange; public Vote(String votingNode, Boolean voteValue, Boolean voteExchange, List liveMembers, List deadMembers) { diff --git a/gossip-base/src/main/java/org/apache/gossip/lock/vote/VoteCandidate.java b/gossip-base/src/main/java/org/apache/gossip/lock/vote/VoteCandidate.java index b81b0b9..27370d9 100644 --- a/gossip-base/src/main/java/org/apache/gossip/lock/vote/VoteCandidate.java +++ b/gossip-base/src/main/java/org/apache/gossip/lock/vote/VoteCandidate.java @@ -20,9 +20,7 @@ package org.apache.gossip.lock.vote; import java.util.Map; import java.util.Objects; -/** - * Stores the vote candidate details and its votes. - */ +/** Stores the vote candidate details and its votes. */ public class VoteCandidate { private final String candidateNodeId; @@ -59,13 +57,11 @@ public class VoteCandidate { @Override public boolean equals(Object obj) { - if (!(obj instanceof VoteCandidate)) - return false; - if (obj == this) - return true; + if (!(obj instanceof VoteCandidate)) return false; + if (obj == this) return true; VoteCandidate other = (VoteCandidate) obj; - return this.candidateNodeId.equals(other.candidateNodeId) && this.votingKey - .equals(other.votingKey); + return this.candidateNodeId.equals(other.candidateNodeId) + && this.votingKey.equals(other.votingKey); } @Override diff --git a/gossip-base/src/main/java/org/apache/gossip/lock/vote/VoteSelector.java b/gossip-base/src/main/java/org/apache/gossip/lock/vote/VoteSelector.java index 91c22b3..7390895 100644 --- a/gossip-base/src/main/java/org/apache/gossip/lock/vote/VoteSelector.java +++ b/gossip-base/src/main/java/org/apache/gossip/lock/vote/VoteSelector.java @@ -19,12 +19,11 @@ package org.apache.gossip.lock.vote; import java.util.Set; -/** - * This interface defines vote selection algorithm for the vote based locking. - */ +/** This interface defines vote selection algorithm for the vote based locking. */ public interface VoteSelector { /** - * This method get call by the lock manager of a node to decide which candidate need to be choose for voting. + * This method get call by the lock manager of a node to decide which candidate need to be choose + * for voting. * * @param voteCandidateIds node id set for the vote candidates * @return selected node id to vote from the given vote candidate set. diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/AbstractActiveGossiper.java b/gossip-base/src/main/java/org/apache/gossip/manager/AbstractActiveGossiper.java index 4bd44f2..5319d20 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/AbstractActiveGossiper.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/AbstractActiveGossiper.java @@ -17,33 +17,32 @@ */ package org.apache.gossip.manager; -import java.util.Map.Entry; +import static com.codahale.metrics.MetricRegistry.name; + +import com.codahale.metrics.Histogram; +import com.codahale.metrics.MetricRegistry; import java.util.List; +import java.util.Map.Entry; import java.util.Random; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import com.codahale.metrics.Histogram; -import com.codahale.metrics.MetricRegistry; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.GossipSettings; import org.apache.gossip.LocalMember; import org.apache.gossip.model.ActiveGossipOk; -import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.Member; +import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.Response; import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.model.ShutdownMessage; import org.apache.gossip.udp.*; -import org.apache.log4j.Logger; - -import static com.codahale.metrics.MetricRegistry.name; /** * The ActiveGossipThread sends information. Pick a random partner and send the membership list to that partner */ +@Slf4j public abstract class AbstractActiveGossiper { - protected static final Logger LOGGER = Logger.getLogger(AbstractActiveGossiper.class); - protected final GossipManager gossipManager; protected final GossipCore gossipCore; private final Histogram sharedDataHistogram; @@ -128,7 +127,7 @@ public abstract class AbstractActiveGossiper { udpMessage.setUriFrom(me.getId()); } } - if (udpMessage.getMessages().size() > 0) { + if (!udpMessage.getMessages().isEmpty()) { gossipCore.sendOneWay(udpMessage, member.getUri()); } } @@ -229,7 +228,7 @@ public abstract class AbstractActiveGossiper { if (r instanceof ActiveGossipOk){ //maybe count metrics here } else { - LOGGER.debug("Message " + message + " generated response " + r); + log.debug("Message " + message + " generated response " + r); } sendMembershipHistogram.update(System.currentTimeMillis() - startTime); } @@ -252,7 +251,7 @@ public abstract class AbstractActiveGossiper { */ protected LocalMember selectPartner(List memberList) { LocalMember member = null; - if (memberList.size() > 0) { + if (!memberList.isEmpty()) { int randomNeighborIndex = random.nextInt(memberList.size()); member = memberList.get(randomNeighborIndex); } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/Clock.java b/gossip-base/src/main/java/org/apache/gossip/manager/Clock.java index 6629c62..10053ae 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/Clock.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/Clock.java @@ -20,6 +20,6 @@ package org.apache.gossip.manager; public interface Clock { long currentTimeMillis(); + long nanoTime(); - } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/DataReaper.java b/gossip-base/src/main/java/org/apache/gossip/manager/DataReaper.java index 8175a1b..28c3ddc 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/DataReaper.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/DataReaper.java @@ -22,7 +22,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; - import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.SharedDataMessage; diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/DatacenterRackAwareActiveGossiper.java b/gossip-base/src/main/java/org/apache/gossip/manager/DatacenterRackAwareActiveGossiper.java index 2f489a2..9d45221 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/DatacenterRackAwareActiveGossiper.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/DatacenterRackAwareActiveGossiper.java @@ -17,20 +17,19 @@ */ package org.apache.gossip.manager; -import java.util.List; +import com.codahale.metrics.MetricRegistry; import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; - +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.LocalMember; -import com.codahale.metrics.MetricRegistry; - /** * Sends gossip traffic at different rates to other racks and data-centers. * This implementation controls the rate at which gossip traffic is shared. @@ -38,18 +37,17 @@ import com.codahale.metrics.MetricRegistry; * in the rack than in the the datacenter. We can adjust the rate at which we send messages to each group. * */ +@Slf4j public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper { public static final String DATACENTER = "datacenter"; public static final String RACK = "rack"; - + private final BlockingQueue workQueue; private int sameRackGossipIntervalMs = 100; private int sameDcGossipIntervalMs = 500; private int differentDatacenterGossipIntervalMs = 1000; private int randomDeadMemberSendIntervalMs = 250; - private ScheduledExecutorService scheduledExecutorService; - private final BlockingQueue workQueue; private ThreadPoolExecutor threadService; public DatacenterRackAwareActiveGossiper(GossipManager gossipManager, GossipCore gossipCore, @@ -220,14 +218,14 @@ public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper { try { scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { - LOGGER.debug("Issue during shutdown", e); + log.debug("Issue during shutdown", e); } sendShutdownMessage(); threadService.shutdown(); try { threadService.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { - LOGGER.debug("Issue during shutdown", e); + log.debug("Issue during shutdown", e); } } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/GossipCore.java b/gossip-base/src/main/java/org/apache/gossip/manager/GossipCore.java index 384d796..baa8fbb 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/GossipCore.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/GossipCore.java @@ -20,6 +20,13 @@ package org.apache.gossip.manager; import com.codahale.metrics.Gauge; import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; +import java.io.IOException; +import java.net.URI; +import java.util.List; +import java.util.Map.Entry; +import java.util.concurrent.*; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.LocalMember; import org.apache.gossip.Member; import org.apache.gossip.RemoteMember; @@ -33,35 +40,20 @@ import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.Response; import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.udp.Trackable; -import org.apache.log4j.Logger; - -import java.io.IOException; -import java.net.URI; -import java.util.List; -import java.util.Map.Entry; -import java.util.concurrent.*; +@Slf4j public class GossipCore implements GossipCoreConstants { - class LatchAndBase { - private final CountDownLatch latch; - private volatile Base base; - - LatchAndBase(){ - latch = new CountDownLatch(1); - } - - } - public static final Logger LOGGER = Logger.getLogger(GossipCore.class); private final GossipManager gossipManager; - private ConcurrentHashMap requests; + @Getter private final ConcurrentHashMap> perNodeData; + @Getter private final ConcurrentHashMap sharedData; private final Meter messageSerdeException; private final Meter transmissionException; private final Meter transmissionSuccess; private final DataEventManager eventManager; - + private ConcurrentHashMap requests; public GossipCore(GossipManager manager, MetricRegistry metrics){ this.gossipManager = manager; requests = new ConcurrentHashMap<>(); @@ -75,7 +67,7 @@ public class GossipCore implements GossipCoreConstants { transmissionException = metrics.meter(MESSAGE_TRANSMISSION_EXCEPTION); transmissionSuccess = metrics.meter(MESSAGE_TRANSMISSION_SUCCESS); } - + @SuppressWarnings({ "unchecked", "rawtypes" }) public void addSharedData(SharedDataMessage message) { while (true){ @@ -135,20 +127,12 @@ public class GossipCore implements GossipCoreConstants { } } - public ConcurrentHashMap> getPerNodeData(){ - return perNodeData; - } - - public ConcurrentHashMap getSharedData() { - return sharedData; - } - public void shutdown(){ } public void receive(Base base) { if (!gossipManager.getMessageHandler().invoke(this, gossipManager, base)) { - LOGGER.warn("received message can not be handled"); + log.warn("received message can not be handled"); } } @@ -177,10 +161,8 @@ public class GossipCore implements GossipCoreConstants { } public Response send(Base message, URI uri){ - if (LOGGER.isDebugEnabled()){ - LOGGER.debug("Sending " + message); - LOGGER.debug("Current request queue " + requests); - } + log.debug("Sending " + message); + log.debug("Current request queue " + requests); final Trackable t; LatchAndBase latchAndBase = null; @@ -195,7 +177,7 @@ public class GossipCore implements GossipCoreConstants { if (latchAndBase == null){ return null; } - + try { boolean complete = latchAndBase.latch.await(1, TimeUnit.SECONDS); if (complete){ @@ -206,9 +188,7 @@ public class GossipCore implements GossipCoreConstants { } catch (InterruptedException e) { throw new RuntimeException(e); } finally { - if (latchAndBase != null){ requests.remove(t.getUuid() + "/" + t.getUriFrom()); - } } } @@ -222,7 +202,7 @@ public class GossipCore implements GossipCoreConstants { try { sendInternal(message, u); } catch (RuntimeException ex) { - LOGGER.debug("Send one way failed", ex); + log.debug("Send one way failed", ex); } } @@ -240,12 +220,12 @@ public class GossipCore implements GossipCoreConstants { * */ public void mergeLists(RemoteMember senderMember, List remoteList) { - if (LOGGER.isDebugEnabled()){ + if (log.isDebugEnabled()){ debugState(senderMember, remoteList); } for (LocalMember i : gossipManager.getDeadMembers()) { if (i.getId().equals(senderMember.getId())) { - LOGGER.debug(gossipManager.getMyself() + " contacted by dead member " + senderMember.getUri()); + log.debug(gossipManager.getMyself() + " contacted by dead member " + senderMember.getUri()); i.recordHeartbeat(senderMember.getHeartbeat()); i.setHeartbeat(senderMember.getHeartbeat()); //TODO consider forcing an UP here @@ -275,14 +255,14 @@ public class GossipCore implements GossipCoreConstants { } } } - if (LOGGER.isDebugEnabled()){ + if (log.isDebugEnabled()){ debugState(senderMember, remoteList); } } private void debugState(RemoteMember senderMember, List remoteList){ - LOGGER.warn( + log.warn( "-----------------------\n" + "Me " + gossipManager.getMyself() + "\n" + "Sender " + senderMember + "\n" + @@ -313,7 +293,7 @@ public class GossipCore implements GossipCoreConstants { } } } - + void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler){ eventManager.registerPerNodeDataSubscriber(handler); } @@ -329,4 +309,14 @@ public class GossipCore implements GossipCoreConstants { void unregisterSharedDataSubscriber(UpdateSharedDataEventHandler handler){ eventManager.unregisterSharedDataSubscriber(handler); } + + class LatchAndBase { + private final CountDownLatch latch; + private volatile Base base; + + LatchAndBase(){ + latch = new CountDownLatch(1); + } + + } } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/GossipCoreConstants.java b/gossip-base/src/main/java/org/apache/gossip/manager/GossipCoreConstants.java index 9cac7c0..820071f 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/GossipCoreConstants.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/GossipCoreConstants.java @@ -18,7 +18,7 @@ package org.apache.gossip.manager; public interface GossipCoreConstants { - String PER_NODE_DATA_SIZE = "gossip.core.pernodedata.size"; + String PER_NODE_DATA_SIZE = "gossip.core.pernodedata.size"; String SHARED_DATA_SIZE = "gossip.core.shareddata.size"; String REQUEST_SIZE = "gossip.core.requests.size"; String THREADPOOL_ACTIVE = "gossip.core.threadpool.active"; diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/GossipManager.java b/gossip-base/src/main/java/org/apache/gossip/manager/GossipManager.java index 2e45843..3e1b0f3 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/GossipManager.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/GossipManager.java @@ -20,6 +20,22 @@ package org.apache.gossip.manager; import com.codahale.metrics.MetricRegistry; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.Serial; +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.GossipSettings; import org.apache.gossip.LocalMember; import org.apache.gossip.Member; @@ -36,29 +52,14 @@ import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.protocol.ProtocolManager; import org.apache.gossip.transport.TransportManager; import org.apache.gossip.utils.ReflectionUtils; -import org.apache.log4j.Logger; -import java.io.File; -import java.net.URI; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; +@Slf4j +public class GossipManager { -public abstract class GossipManager { - public static final Logger LOGGER = Logger.getLogger(GossipManager.class); - // this mapper is used for ring and user-data persistence only. NOT messages. public static final ObjectMapper metdataObjectMapper = new ObjectMapper() { + @Serial private static final long serialVersionUID = 1L; { enableDefaultTyping(); @@ -69,10 +70,6 @@ public abstract class GossipManager { private final LocalMember me; private final GossipSettings settings; private final AtomicBoolean gossipServiceRunning; - - private TransportManager transportManager; - private ProtocolManager protocolManager; - private final GossipCore gossipCore; private final DataReaper dataReaper; private final Clock clock; @@ -81,9 +78,10 @@ public abstract class GossipManager { private final RingStatePersister ringState; private final UserDataPersister userDataState; private final GossipMemberStateRefresher memberStateRefresher; - private final MessageHandler messageHandler; private final LockManager lockManager; + private TransportManager transportManager; + private ProtocolManager protocolManager; public GossipManager(String cluster, URI uri, String id, Map properties, GossipSettings settings, @@ -122,6 +120,21 @@ public abstract class GossipManager { readSavedDataState(); } + public static File buildRingStatePath(GossipManager manager) { + return new File(manager.getSettings().getPathToRingState(), "ringstate." + manager.getMyself().getClusterName() + "." + + manager.getMyself().getId() + ".json"); + } + + public static File buildSharedDataPath(GossipManager manager){ + return new File(manager.getSettings().getPathToDataState(), "shareddata." + + manager.getMyself().getClusterName() + "." + manager.getMyself().getId() + ".json"); + } + + public static File buildPerNodeDataPath(GossipManager manager) { + return new File(manager.getSettings().getPathToDataState(), "pernodedata." + + manager.getMyself().getClusterName() + "." + manager.getMyself().getId() + ".json"); + } + public MessageHandler getMessageHandler() { return messageHandler; } @@ -144,7 +157,7 @@ public abstract class GossipManager { .filter(entry -> GossipState.DOWN.equals(entry.getValue())) .map(Entry::getKey).collect(Collectors.toList())); } - + /** * * @return a read only list of members found in the UP state @@ -166,26 +179,26 @@ public abstract class GossipManager { * thread and start the receiver thread. */ public void init() { - + // protocol manager and transport managers are specified in settings. // construct them here via reflection. - + protocolManager = ReflectionUtils.constructWithReflection( settings.getProtocolManagerClass(), new Class[] { GossipSettings.class, String.class, MetricRegistry.class }, new Object[] { settings, me.getId(), this.getRegistry() } ); - + transportManager = ReflectionUtils.constructWithReflection( settings.getTransportManagerClass(), new Class[] { GossipManager.class, GossipCore.class}, new Object[] { this, gossipCore } ); - + // start processing gossip messages. transportManager.startEndpoint(); transportManager.startActiveGossiper(); - + dataReaper.init(); if (settings.isPersistRingState()) { scheduledServiced.scheduleAtFixedRate(ringState, 60, 60, TimeUnit.SECONDS); @@ -194,9 +207,9 @@ public abstract class GossipManager { scheduledServiced.scheduleAtFixedRate(userDataState, 60, 60, TimeUnit.SECONDS); } memberStateRefresher.init(); - LOGGER.debug("The GossipManager is started."); + log.debug("The GossipManager is started."); } - + private void readSavedRingState() { if (settings.isPersistRingState()) { for (LocalMember l : ringState.readFromDisk()) { @@ -238,7 +251,7 @@ public abstract class GossipManager { try { scheduledServiced.awaitTermination(1, TimeUnit.SECONDS); } catch (InterruptedException e) { - LOGGER.error(e); + log.error("Error!", e); } scheduledServiced.shutdownNow(); } @@ -331,34 +344,19 @@ public abstract class GossipManager { public Clock getClock() { return clock; } - - public MetricRegistry getRegistry() { - return registry; - } - - public ProtocolManager getProtocolManager() { - return protocolManager; - } - - public TransportManager getTransportManager() { - return transportManager; - } // todo: consider making these path methods part of GossipSettings - public static File buildRingStatePath(GossipManager manager) { - return new File(manager.getSettings().getPathToRingState(), "ringstate." + manager.getMyself().getClusterName() + "." - + manager.getMyself().getId() + ".json"); + public MetricRegistry getRegistry() { + return registry; } - public static File buildSharedDataPath(GossipManager manager){ - return new File(manager.getSettings().getPathToDataState(), "shareddata." - + manager.getMyself().getClusterName() + "." + manager.getMyself().getId() + ".json"); + public ProtocolManager getProtocolManager() { + return protocolManager; } - public static File buildPerNodeDataPath(GossipManager manager) { - return new File(manager.getSettings().getPathToDataState(), "pernodedata." - + manager.getMyself().getClusterName() + "." + manager.getMyself().getId() + ".json"); + public TransportManager getTransportManager() { + return transportManager; } public void registerPerNodeDataSubscriber(UpdateNodeDataEventHandler handler){ diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/GossipManagerBuilder.java b/gossip-base/src/main/java/org/apache/gossip/manager/GossipManagerBuilder.java index f3ca23a..eec835a 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/GossipManagerBuilder.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/GossipManagerBuilder.java @@ -46,7 +46,7 @@ public class GossipManagerBuilder { private List gossipMembers; private GossipListener listener; private MetricRegistry registry; - private Map properties; + private Map properties; private MessageHandler messageHandler; private ManagerBuilder() {} @@ -61,8 +61,8 @@ public class GossipManagerBuilder { this.cluster = cluster; return this; } - - public ManagerBuilder properties(Map properties) { + + public ManagerBuilder properties(Map properties) { this.properties = properties; return this; } @@ -76,7 +76,7 @@ public class GossipManagerBuilder { this.settings = settings; return this; } - + public ManagerBuilder startupSettings(StartupSettings startupSettings) { this.cluster = startupSettings.getCluster(); this.id = startupSettings.getId(); @@ -95,13 +95,13 @@ public class GossipManagerBuilder { this.listener = listener; return this; } - + public ManagerBuilder registry(MetricRegistry registry) { this.registry = registry; return this; } - public ManagerBuilder uri(URI uri){ + public ManagerBuilder uri(URI uri) { this.uri = uri; return this; } @@ -116,24 +116,32 @@ public class GossipManagerBuilder { checkArgument(cluster != null, "You must specify a cluster name"); checkArgument(settings != null, "You must specify gossip settings"); checkArgument(uri != null, "You must specify a uri"); - if (registry == null){ + if (registry == null) { registry = new MetricRegistry(); } - if (properties == null){ - properties = new HashMap(); + if (properties == null) { + properties = new HashMap(); } - if (listener == null){ - listener((a,b) -> {}); + if (listener == null) { + listener((a, b) -> {}); } if (gossipMembers == null) { gossipMembers = new ArrayList<>(); } - + if (messageHandler == null) { messageHandler = MessageHandlerFactory.defaultHandler(); } - return new GossipManager(cluster, uri, id, properties, settings, gossipMembers, listener, registry, messageHandler) {} ; + return new GossipManager( + cluster, + uri, + id, + properties, + settings, + gossipMembers, + listener, + registry, + messageHandler) {}; } } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/GossipMemberStateRefresher.java b/gossip-base/src/main/java/org/apache/gossip/manager/GossipMemberStateRefresher.java index 652bf5c..b79bfd8 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/GossipMemberStateRefresher.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/GossipMemberStateRefresher.java @@ -18,22 +18,21 @@ package org.apache.gossip.manager; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.*; +import java.util.function.BiFunction; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.GossipSettings; import org.apache.gossip.LocalMember; import org.apache.gossip.event.GossipListener; import org.apache.gossip.event.GossipState; import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.ShutdownMessage; -import org.apache.log4j.Logger; - -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.*; -import java.util.function.BiFunction; +@Slf4j public class GossipMemberStateRefresher { - public static final Logger LOGGER = Logger.getLogger(GossipMemberStateRefresher.class); private final Map members; private final GossipSettings settings; @@ -66,7 +65,7 @@ public class GossipMemberStateRefresher { try { runOnce(); } catch (RuntimeException ex) { - LOGGER.warn("scheduled state had exception", ex); + log.warn("scheduled state had exception", ex); } } @@ -144,13 +143,13 @@ public class GossipMemberStateRefresher { try { scheduledExecutor.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { - LOGGER.debug("Issue during shutdown", e); + log.debug("Issue during shutdown", e); } listenerExecutor.shutdown(); try { listenerExecutor.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { - LOGGER.debug("Issue during shutdown", e); + log.debug("Issue during shutdown", e); } listenerExecutor.shutdownNow(); } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/RingStatePersister.java b/gossip-base/src/main/java/org/apache/gossip/manager/RingStatePersister.java index 5334ad4..7cc1fdd 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/RingStatePersister.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/RingStatePersister.java @@ -17,6 +17,7 @@ */ package org.apache.gossip.manager; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -24,14 +25,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.NavigableSet; - -import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.LocalMember; -import org.apache.log4j.Logger; +@Slf4j public class RingStatePersister implements Runnable { - private static final Logger LOGGER = Logger.getLogger(RingStatePersister.class); private final File path; // NOTE: this is a different instance than what gets used for message marshalling. private final ObjectMapper objectMapper; @@ -53,7 +52,7 @@ public class RingStatePersister implements Runnable { try (FileOutputStream fos = new FileOutputStream(path)){ objectMapper.writeValue(fos, i); } catch (IOException e) { - LOGGER.debug(e); + log.error("Error!", e); } } @@ -65,7 +64,7 @@ public class RingStatePersister implements Runnable { try (FileInputStream fos = new FileInputStream(path)){ return objectMapper.readValue(fos, ArrayList.class); } catch (IOException e) { - LOGGER.debug(e); + log.error("Error", e); } return new ArrayList<>(); } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/SimpleActiveGossiper.java b/gossip-base/src/main/java/org/apache/gossip/manager/SimpleActiveGossiper.java index 7d498b4..382aecd 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/SimpleActiveGossiper.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/SimpleActiveGossiper.java @@ -25,50 +25,60 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.LocalMember; import com.codahale.metrics.MetricRegistry; -/** - * Base implementation gossips randomly to live nodes periodically gossips to dead ones - * - */ +/** Base implementation gossips randomly to live nodes periodically gossips to dead ones */ +@Slf4j public class SimpleActiveGossiper extends AbstractActiveGossiper { - private ScheduledExecutorService scheduledExecutorService; private final BlockingQueue workQueue; + private ScheduledExecutorService scheduledExecutorService; private ThreadPoolExecutor threadService; - - public SimpleActiveGossiper(GossipManager gossipManager, GossipCore gossipCore, - MetricRegistry registry) { + + public SimpleActiveGossiper( + GossipManager gossipManager, GossipCore gossipCore, MetricRegistry registry) { super(gossipManager, gossipCore, registry); scheduledExecutorService = Executors.newScheduledThreadPool(2); workQueue = new ArrayBlockingQueue(1024); - threadService = new ThreadPoolExecutor(1, 30, 1, TimeUnit.SECONDS, workQueue, - new ThreadPoolExecutor.DiscardOldestPolicy()); + threadService = + new ThreadPoolExecutor( + 1, 30, 1, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.DiscardOldestPolicy()); } @Override public void init() { super.init(); - scheduledExecutorService.scheduleAtFixedRate(() -> { - threadService.execute(() -> { - sendToALiveMember(); - }); - }, 0, gossipManager.getSettings().getGossipInterval(), TimeUnit.MILLISECONDS); - scheduledExecutorService.scheduleAtFixedRate(() -> { - sendToDeadMember(); - }, 0, gossipManager.getSettings().getGossipInterval(), TimeUnit.MILLISECONDS); scheduledExecutorService.scheduleAtFixedRate( - () -> sendPerNodeData(gossipManager.getMyself(), - selectPartner(gossipManager.getLiveMembers())), - 0, gossipManager.getSettings().getGossipInterval(), TimeUnit.MILLISECONDS); + () -> { + threadService.execute(this::sendToALiveMember); + }, + 0, + gossipManager.getSettings().getGossipInterval(), + TimeUnit.MILLISECONDS); scheduledExecutorService.scheduleAtFixedRate( - () -> sendSharedData(gossipManager.getMyself(), - selectPartner(gossipManager.getLiveMembers())), - 0, gossipManager.getSettings().getGossipInterval(), TimeUnit.MILLISECONDS); + this::sendToDeadMember, + 0, + gossipManager.getSettings().getGossipInterval(), + TimeUnit.MILLISECONDS); + scheduledExecutorService.scheduleAtFixedRate( + () -> + sendPerNodeData( + gossipManager.getMyself(), selectPartner(gossipManager.getLiveMembers())), + 0, + gossipManager.getSettings().getGossipInterval(), + TimeUnit.MILLISECONDS); + scheduledExecutorService.scheduleAtFixedRate( + () -> + sendSharedData( + gossipManager.getMyself(), selectPartner(gossipManager.getLiveMembers())), + 0, + gossipManager.getSettings().getGossipInterval(), + TimeUnit.MILLISECONDS); } - + @Override public void shutdown() { super.shutdown(); @@ -76,31 +86,29 @@ public class SimpleActiveGossiper extends AbstractActiveGossiper { try { scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { - LOGGER.debug("Issue during shutdown", e); + log.debug("Issue during shutdown", e); } sendShutdownMessage(); threadService.shutdown(); try { threadService.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { - LOGGER.debug("Issue during shutdown", e); + log.debug("Issue during shutdown", e); } } - protected void sendToALiveMember(){ + protected void sendToALiveMember() { LocalMember member = selectPartner(gossipManager.getLiveMembers()); sendMembershipList(gossipManager.getMyself(), member); } - - protected void sendToDeadMember(){ + + protected void sendToDeadMember() { LocalMember member = selectPartner(gossipManager.getDeadMembers()); sendMembershipList(gossipManager.getMyself(), member); } - - /** - * sends an optimistic shutdown message to several clusters nodes - */ - protected void sendShutdownMessage(){ + + /** sends an optimistic shutdown message to several clusters nodes */ + protected void sendShutdownMessage() { List l = gossipManager.getLiveMembers(); int sendTo = l.size() < 3 ? 1 : l.size() / 2; for (int i = 0; i < sendTo; i++) { diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/SystemClock.java b/gossip-base/src/main/java/org/apache/gossip/manager/SystemClock.java index 04a7080..aa678e9 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/SystemClock.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/SystemClock.java @@ -28,5 +28,4 @@ public class SystemClock implements Clock { public long nanoTime() { return System.nanoTime(); } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/UserDataPersister.java b/gossip-base/src/main/java/org/apache/gossip/manager/UserDataPersister.java index 28c3151..2569747 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/UserDataPersister.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/UserDataPersister.java @@ -14,7 +14,7 @@ * 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; @@ -24,71 +24,70 @@ import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.java.Log; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.SharedDataMessage; -import org.apache.log4j.Logger; +@Slf4j public class UserDataPersister implements Runnable { - - private static final Logger LOGGER = Logger.getLogger(UserDataPersister.class); - private final GossipCore gossipCore; - + + private final GossipCore gossipCore; + private final File perNodePath; private final File sharedPath; private final ObjectMapper objectMapper; - + UserDataPersister(GossipCore gossipCore, File perNodePath, File sharedPath) { this.gossipCore = gossipCore; this.objectMapper = GossipManager.metdataObjectMapper; this.perNodePath = perNodePath; this.sharedPath = sharedPath; } - + @SuppressWarnings("unchecked") - ConcurrentHashMap> readPerNodeFromDisk(){ + ConcurrentHashMap> readPerNodeFromDisk() { if (!perNodePath.exists()) { return new ConcurrentHashMap>(); } - try (FileInputStream fos = new FileInputStream(perNodePath)){ + try (FileInputStream fos = new FileInputStream(perNodePath)) { return objectMapper.readValue(fos, ConcurrentHashMap.class); } catch (IOException e) { - LOGGER.debug(e); + log.error("Error!", e); } return new ConcurrentHashMap>(); } - - void writePerNodeToDisk(){ - try (FileOutputStream fos = new FileOutputStream(perNodePath)){ + + void writePerNodeToDisk() { + try (FileOutputStream fos = new FileOutputStream(perNodePath)) { objectMapper.writeValue(fos, gossipCore.getPerNodeData()); } catch (IOException e) { - LOGGER.warn(e); + log.error("Error!", e); } } - - void writeSharedToDisk(){ - try (FileOutputStream fos = new FileOutputStream(sharedPath)){ + + void writeSharedToDisk() { + try (FileOutputStream fos = new FileOutputStream(sharedPath)) { objectMapper.writeValue(fos, gossipCore.getSharedData()); } catch (IOException e) { - LOGGER.warn(e); + log.error("Error!", e); } } @SuppressWarnings("unchecked") - ConcurrentHashMap readSharedDataFromDisk(){ + ConcurrentHashMap readSharedDataFromDisk() { if (!sharedPath.exists()) { return new ConcurrentHashMap<>(); } - try (FileInputStream fos = new FileInputStream(sharedPath)){ + try (FileInputStream fos = new FileInputStream(sharedPath)) { return objectMapper.readValue(fos, ConcurrentHashMap.class); } catch (IOException e) { - LOGGER.debug(e); + log.error("Error!", e); } - return new ConcurrentHashMap(); + return new ConcurrentHashMap<>(); } - - /** - * Writes all pernode and shared data to disk - */ + + /** Writes all pernode and shared data to disk */ @Override public void run() { writePerNodeToDisk(); diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ActiveGossipMessageHandler.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ActiveGossipMessageHandler.java index e89179b..2dfeb59 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ActiveGossipMessageHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ActiveGossipMessageHandler.java @@ -17,6 +17,11 @@ */ package org.apache.gossip.manager.handlers; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.Member; import org.apache.gossip.RemoteMember; import org.apache.gossip.manager.GossipCore; @@ -26,11 +31,7 @@ import org.apache.gossip.udp.UdpActiveGossipMessage; import org.apache.gossip.udp.UdpActiveGossipOk; import org.apache.gossip.udp.UdpNotAMemberFault; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; - +@Slf4j public class ActiveGossipMessageHandler implements MessageHandler { /** @@ -49,7 +50,7 @@ public class ActiveGossipMessageHandler implements MessageHandler { try { u = new URI(activeGossipMessage.getMembers().get(i).getUri()); } catch (URISyntaxException e) { - GossipCore.LOGGER.debug("Gossip message with faulty URI", e); + log.debug("Gossip message with faulty URI", e); continue; } RemoteMember member = new RemoteMember( @@ -66,7 +67,7 @@ public class ActiveGossipMessageHandler implements MessageHandler { f.setException("Not a member of this cluster " + i); f.setUriFrom(activeGossipMessage.getUriFrom()); f.setUuid(activeGossipMessage.getUuid()); - GossipCore.LOGGER.warn(f); + log.warn("Warn", f); gossipCore.sendOneWay(f, member.getUri()); continue; } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/MessageHandler.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/MessageHandler.java index 5af9b14..4e12143 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/MessageHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/MessageHandler.java @@ -29,4 +29,4 @@ public interface MessageHandler { * @return boolean indicating success. */ boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base); -} \ No newline at end of file +} diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/MessageHandlerFactory.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/MessageHandlerFactory.java index abce76d..229c580 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/MessageHandlerFactory.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/MessageHandlerFactory.java @@ -18,40 +18,35 @@ package org.apache.gossip.manager.handlers; -import org.apache.gossip.manager.GossipCore; -import org.apache.gossip.manager.GossipManager; -import org.apache.gossip.model.*; - import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Stream; +import org.apache.gossip.model.*; public class MessageHandlerFactory { public static MessageHandler defaultHandler() { return concurrentHandler( - new TypedMessageHandler(Response.class, new ResponseHandler()), - new TypedMessageHandler(ShutdownMessage.class, new ShutdownMessageHandler()), - new TypedMessageHandler(PerNodeDataMessage.class, new PerNodeDataMessageHandler()), - new TypedMessageHandler(SharedDataMessage.class, new SharedDataMessageHandler()), - new TypedMessageHandler(ActiveGossipMessage.class, new ActiveGossipMessageHandler()), - new TypedMessageHandler(PerNodeDataBulkMessage.class, new PerNodeDataBulkMessageHandler()), - new TypedMessageHandler(SharedDataBulkMessage.class, new SharedDataBulkMessageHandler()) - ); + new TypedMessageHandlerWrapper(Response.class, new ResponseHandler()), + new TypedMessageHandlerWrapper(ShutdownMessage.class, new ShutdownMessageHandler()), + new TypedMessageHandlerWrapper(PerNodeDataMessage.class, new PerNodeDataMessageHandler()), + new TypedMessageHandlerWrapper(SharedDataMessage.class, new SharedDataMessageHandler()), + new TypedMessageHandlerWrapper(ActiveGossipMessage.class, new ActiveGossipMessageHandler()), + new TypedMessageHandlerWrapper( + PerNodeDataBulkMessage.class, new PerNodeDataBulkMessageHandler()), + new TypedMessageHandlerWrapper( + SharedDataBulkMessage.class, new SharedDataBulkMessageHandler())); } public static MessageHandler concurrentHandler(MessageHandler... handlers) { - if (handlers == null) - throw new NullPointerException("handlers cannot be null"); - if (Arrays.asList(handlers).stream().filter(i -> i != null).count() != handlers.length) { + if (handlers == null) throw new NullPointerException("handlers cannot be null"); + if (Arrays.stream(handlers).filter(Objects::nonNull).count() != handlers.length) { throw new NullPointerException("found at least one null handler"); } - return new MessageHandler() { - @Override public boolean invoke(GossipCore gossipCore, GossipManager gossipManager, - Base base) { - // return true if at least one of the component handlers return true. - return Arrays.asList(handlers).stream() - .filter((mi) -> mi.invoke(gossipCore, gossipManager, base)).count() > 0; - } + return (gossipCore, gossipManager, base) -> { + // return true if at least one of the component handlers return true. + return Stream.of(handlers).filter((mi) -> mi.invoke(gossipCore, gossipManager, base)).count() + > 0; }; } } - diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/PerNodeDataBulkMessageHandler.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/PerNodeDataBulkMessageHandler.java index 37024e9..d0f1b0f 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/PerNodeDataBulkMessageHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/PerNodeDataBulkMessageHandler.java @@ -24,7 +24,7 @@ import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.udp.UdpPerNodeDataBulkMessage; public class PerNodeDataBulkMessageHandler implements MessageHandler { - + /** * @param gossipCore context. * @param gossipManager context. @@ -34,8 +34,7 @@ public class PerNodeDataBulkMessageHandler implements MessageHandler { @Override public boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) { UdpPerNodeDataBulkMessage udpMessage = (UdpPerNodeDataBulkMessage) base; - for (PerNodeDataMessage dataMsg: udpMessage.getMessages()) - gossipCore.addPerNodeData(dataMsg); + for (PerNodeDataMessage dataMsg : udpMessage.getMessages()) gossipCore.addPerNodeData(dataMsg); return true; } } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ResponseHandler.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ResponseHandler.java index 1070ff7..206fcda 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ResponseHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ResponseHandler.java @@ -23,7 +23,7 @@ import org.apache.gossip.model.Base; import org.apache.gossip.udp.Trackable; public class ResponseHandler implements MessageHandler { - + /** * @param gossipCore context. * @param gossipManager context. diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/SharedDataBulkMessageHandler.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/SharedDataBulkMessageHandler.java index a062f95..b6cffc6 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/SharedDataBulkMessageHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/SharedDataBulkMessageHandler.java @@ -23,8 +23,8 @@ import org.apache.gossip.model.Base; import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.udp.UdpSharedDataBulkMessage; -public class SharedDataBulkMessageHandler implements MessageHandler{ - +public class SharedDataBulkMessageHandler implements MessageHandler { + /** * @param gossipCore context. * @param gossipManager context. @@ -34,8 +34,7 @@ public class SharedDataBulkMessageHandler implements MessageHandler{ @Override public boolean invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) { UdpSharedDataBulkMessage udpMessage = (UdpSharedDataBulkMessage) base; - for (SharedDataMessage dataMsg: udpMessage.getMessages()) - gossipCore.addSharedData(dataMsg); + for (SharedDataMessage dataMsg : udpMessage.getMessages()) gossipCore.addSharedData(dataMsg); return true; } } diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/SharedDataMessageHandler.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/SharedDataMessageHandler.java index 3fe3033..4961eb3 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/SharedDataMessageHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/SharedDataMessageHandler.java @@ -22,8 +22,8 @@ import org.apache.gossip.manager.GossipManager; import org.apache.gossip.model.Base; import org.apache.gossip.udp.UdpSharedDataMessage; -public class SharedDataMessageHandler implements MessageHandler{ - +public class SharedDataMessageHandler implements MessageHandler { + /** * @param gossipCore context. * @param gossipManager context. diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ShutdownMessageHandler.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ShutdownMessageHandler.java index 40e4c07..205011d 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ShutdownMessageHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/ShutdownMessageHandler.java @@ -24,7 +24,7 @@ import org.apache.gossip.model.PerNodeDataMessage; import org.apache.gossip.model.ShutdownMessage; public class ShutdownMessageHandler implements MessageHandler { - + /** * @param gossipCore context. * @param gossipManager context. diff --git a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/TypedMessageHandler.java b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/TypedMessageHandlerWrapper.java similarity index 86% rename from gossip-base/src/main/java/org/apache/gossip/manager/handlers/TypedMessageHandler.java rename to gossip-base/src/main/java/org/apache/gossip/manager/handlers/TypedMessageHandlerWrapper.java index b40461d..b15529a 100644 --- a/gossip-base/src/main/java/org/apache/gossip/manager/handlers/TypedMessageHandler.java +++ b/gossip-base/src/main/java/org/apache/gossip/manager/handlers/TypedMessageHandlerWrapper.java @@ -21,11 +21,11 @@ import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.model.Base; -public class TypedMessageHandler implements MessageHandler { - final private Class messageClass; - final private MessageHandler messageHandler; +public class TypedMessageHandlerWrapper implements MessageHandler { + private final Class messageClass; + private final MessageHandler messageHandler; - public TypedMessageHandler(Class messageClass, MessageHandler messageHandler) { + public TypedMessageHandlerWrapper(Class messageClass, MessageHandler messageHandler) { if (messageClass == null || messageHandler == null) { throw new NullPointerException(); } diff --git a/gossip-base/src/main/java/org/apache/gossip/model/ActiveGossipMessage.java b/gossip-base/src/main/java/org/apache/gossip/model/ActiveGossipMessage.java index a3c45b8..bf993dd 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/ActiveGossipMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/ActiveGossipMessage.java @@ -23,10 +23,8 @@ import java.util.List; public class ActiveGossipMessage extends Base { private List members = new ArrayList<>(); - - public ActiveGossipMessage(){ - - } + + public ActiveGossipMessage() {} public List getMembers() { return members; @@ -35,5 +33,4 @@ public class ActiveGossipMessage extends Base { public void setMembers(List members) { this.members = members; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/model/ActiveGossipOk.java b/gossip-base/src/main/java/org/apache/gossip/model/ActiveGossipOk.java index b54bf9a..3c6170c 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/ActiveGossipOk.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/ActiveGossipOk.java @@ -17,6 +17,4 @@ */ package org.apache.gossip.model; -public class ActiveGossipOk extends Response { - -} +public class ActiveGossipOk extends Response {} diff --git a/gossip-base/src/main/java/org/apache/gossip/model/Base.java b/gossip-base/src/main/java/org/apache/gossip/model/Base.java index e9183b0..8bd605d 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/Base.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/Base.java @@ -17,16 +17,14 @@ */ package org.apache.gossip.model; -import org.apache.gossip.udp.UdpActiveGossipMessage; -import org.apache.gossip.udp.UdpActiveGossipOk; -import org.apache.gossip.udp.UdpPerNodeDataBulkMessage; -import org.apache.gossip.udp.UdpNotAMemberFault; -import org.apache.gossip.udp.UdpSharedDataBulkMessage; - -import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; - +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import org.apache.gossip.udp.UdpActiveGossipMessage; +import org.apache.gossip.udp.UdpActiveGossipOk; +import org.apache.gossip.udp.UdpNotAMemberFault; +import org.apache.gossip.udp.UdpPerNodeDataBulkMessage; +import org.apache.gossip.udp.UdpSharedDataBulkMessage; @JsonTypeInfo( use = JsonTypeInfo.Id.CLASS, diff --git a/gossip-base/src/main/java/org/apache/gossip/model/Fault.java b/gossip-base/src/main/java/org/apache/gossip/model/Fault.java index 3ba2508..ae9f3c5 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/Fault.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/Fault.java @@ -21,7 +21,7 @@ public abstract class Fault extends Response { private String exception; - public Fault(){} + public Fault() {} public String getException() { return exception; @@ -35,6 +35,4 @@ public abstract class Fault extends Response { public String toString() { return "Fault [exception=" + exception + "]"; } - } - diff --git a/gossip-base/src/main/java/org/apache/gossip/model/Member.java b/gossip-base/src/main/java/org/apache/gossip/model/Member.java index d86aad8..3bca02c 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/Member.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/Member.java @@ -25,13 +25,11 @@ public class Member { private String uri; private String id; private Long heartbeat; - private Map properties; - - public Member(){ - - } - - public Member(String cluster, String uri, String id, Long heartbeat){ + private Map properties; + + public Member() {} + + public Member(String cluster, String uri, String id, Long heartbeat) { this.cluster = cluster; this.uri = uri; this.id = id; @@ -80,8 +78,16 @@ public class Member { @Override public String toString() { - return "Member [cluster=" + cluster + ", uri=" + uri + ", id=" + id + ", heartbeat=" - + heartbeat + ", properties=" + properties + "]"; + return "Member [cluster=" + + cluster + + ", uri=" + + uri + + ", id=" + + id + + ", heartbeat=" + + heartbeat + + ", properties=" + + properties + + "]"; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/model/Message.java b/gossip-base/src/main/java/org/apache/gossip/model/Message.java index f6ed813..671b728 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/Message.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/Message.java @@ -17,6 +17,4 @@ */ package org.apache.gossip.model; -public class Message extends Base { - -} +public class Message extends Base {} diff --git a/gossip-base/src/main/java/org/apache/gossip/model/NotAMemberFault.java b/gossip-base/src/main/java/org/apache/gossip/model/NotAMemberFault.java index 21ffb07..ad8a960 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/NotAMemberFault.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/NotAMemberFault.java @@ -19,11 +19,9 @@ package org.apache.gossip.model; public class NotAMemberFault extends Fault { - public NotAMemberFault(){ - - } - - public NotAMemberFault(String message){ + public NotAMemberFault() {} + + public NotAMemberFault(String message) { this.setException(message); } } diff --git a/gossip-base/src/main/java/org/apache/gossip/model/PerNodeDataBulkMessage.java b/gossip-base/src/main/java/org/apache/gossip/model/PerNodeDataBulkMessage.java index bb138a5..116dc65 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/PerNodeDataBulkMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/PerNodeDataBulkMessage.java @@ -32,8 +32,10 @@ public class PerNodeDataBulkMessage extends Base { return messages; } - @Override public String toString() { - return "GossipDataBulkMessage[" + messages.stream().map(Object::toString) - .collect(Collectors.joining(",")) + "]"; + @Override + public String toString() { + return "GossipDataBulkMessage[" + + messages.stream().map(Object::toString).collect(Collectors.joining(",")) + + "]"; } } diff --git a/gossip-base/src/main/java/org/apache/gossip/model/PerNodeDataMessage.java b/gossip-base/src/main/java/org/apache/gossip/model/PerNodeDataMessage.java index 2394e76..59f6385 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/PerNodeDataMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/PerNodeDataMessage.java @@ -31,30 +31,39 @@ public class PerNodeDataMessage extends Base { public String getNodeId() { return nodeId; } + public void setNodeId(String nodeId) { this.nodeId = nodeId; } + public String getKey() { return key; } + public void setKey(String key) { this.key = key; } + public Object getPayload() { return payload; } + public void setPayload(Object payload) { this.payload = payload; } + public Long getTimestamp() { return timestamp; } + public void setTimestamp(Long timestamp) { this.timestamp = timestamp; } + public Long getExpireAt() { return expireAt; } + public void setExpireAt(Long expireAt) { this.expireAt = expireAt; } @@ -69,11 +78,18 @@ public class PerNodeDataMessage extends Base { @Override public String toString() { - return "GossipDataMessage [nodeId=" + nodeId + ", key=" + key + ", payload=" + payload - + ", timestamp=" + timestamp + ", expireAt=" + expireAt - + ", replicable=" + replicable + "]"; + return "GossipDataMessage [nodeId=" + + nodeId + + ", key=" + + key + + ", payload=" + + payload + + ", timestamp=" + + timestamp + + ", expireAt=" + + expireAt + + ", replicable=" + + replicable + + "]"; } - - - } diff --git a/gossip-base/src/main/java/org/apache/gossip/model/Response.java b/gossip-base/src/main/java/org/apache/gossip/model/Response.java index b3eef77..926d5b5 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/Response.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/Response.java @@ -17,6 +17,4 @@ */ package org.apache.gossip.model; -public abstract class Response extends Base { - -} +public abstract class Response extends Base {} diff --git a/gossip-base/src/main/java/org/apache/gossip/model/SharedDataBulkMessage.java b/gossip-base/src/main/java/org/apache/gossip/model/SharedDataBulkMessage.java index 7b67430..5f31e32 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/SharedDataBulkMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/SharedDataBulkMessage.java @@ -32,8 +32,10 @@ public class SharedDataBulkMessage extends Base { return messages; } - @Override public String toString() { - return "SharedGossipDataBulkMessage[" + messages.stream().map(Object::toString) - .collect(Collectors.joining(",")) + "]"; + @Override + public String toString() { + return "SharedGossipDataBulkMessage[" + + messages.stream().map(Object::toString).collect(Collectors.joining(",")) + + "]"; } } diff --git a/gossip-base/src/main/java/org/apache/gossip/model/SharedDataMessage.java b/gossip-base/src/main/java/org/apache/gossip/model/SharedDataMessage.java index e148189..55a36a3 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/SharedDataMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/SharedDataMessage.java @@ -17,7 +17,6 @@ */ package org.apache.gossip.model; -import org.apache.gossip.replication.AllReplicable; import org.apache.gossip.replication.Replicable; public class SharedDataMessage extends Base { diff --git a/gossip-base/src/main/java/org/apache/gossip/model/ShutdownMessage.java b/gossip-base/src/main/java/org/apache/gossip/model/ShutdownMessage.java index 4bca508..ba4c43f 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/ShutdownMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/ShutdownMessage.java @@ -22,10 +22,8 @@ public class ShutdownMessage extends Message { public static final String PER_NODE_KEY = "gossipcore.shutdowmessage"; private long shutdownAtNanos; private String nodeId; - - public ShutdownMessage(){ - - } + + public ShutdownMessage() {} public String getNodeId() { return nodeId; @@ -47,5 +45,4 @@ public class ShutdownMessage extends Message { public String toString() { return "ShutdownMessage [shutdownAtNanos=" + shutdownAtNanos + ", nodeId=" + nodeId + "]"; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/model/SignedPayload.java b/gossip-base/src/main/java/org/apache/gossip/model/SignedPayload.java index 9ffbcf1..750d3f7 100644 --- a/gossip-base/src/main/java/org/apache/gossip/model/SignedPayload.java +++ b/gossip-base/src/main/java/org/apache/gossip/model/SignedPayload.java @@ -17,20 +17,23 @@ */ package org.apache.gossip.model; -public class SignedPayload extends Base{ - private byte [] data; - private byte [] signature; +public class SignedPayload extends Base { + private byte[] data; + private byte[] signature; + public byte[] getData() { return data; } + public void setData(byte[] data) { this.data = data; } + public byte[] getSignature() { return signature; } + public void setSignature(byte[] signature) { this.signature = signature; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/protocol/ProtocolManager.java b/gossip-base/src/main/java/org/apache/gossip/protocol/ProtocolManager.java index 0f553c7..a8e4e42 100644 --- a/gossip-base/src/main/java/org/apache/gossip/protocol/ProtocolManager.java +++ b/gossip-base/src/main/java/org/apache/gossip/protocol/ProtocolManager.java @@ -17,9 +17,8 @@ */ package org.apache.gossip.protocol; -import org.apache.gossip.model.Base; - import java.io.IOException; +import org.apache.gossip.model.Base; /** interface for managing message marshaling. */ public interface ProtocolManager { diff --git a/gossip-base/src/main/java/org/apache/gossip/replication/AllReplicable.java b/gossip-base/src/main/java/org/apache/gossip/replication/AllReplicable.java index 573fd25..3699900 100644 --- a/gossip-base/src/main/java/org/apache/gossip/replication/AllReplicable.java +++ b/gossip-base/src/main/java/org/apache/gossip/replication/AllReplicable.java @@ -28,7 +28,7 @@ import org.apache.gossip.model.Base; * @see Replicable */ public class AllReplicable implements Replicable { - + @Override public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) { return true; diff --git a/gossip-base/src/main/java/org/apache/gossip/replication/BlackListReplicable.java b/gossip-base/src/main/java/org/apache/gossip/replication/BlackListReplicable.java index 33e1706..a43bd36 100644 --- a/gossip-base/src/main/java/org/apache/gossip/replication/BlackListReplicable.java +++ b/gossip-base/src/main/java/org/apache/gossip/replication/BlackListReplicable.java @@ -30,9 +30,9 @@ import java.util.List; * @see Replicable */ public class BlackListReplicable implements Replicable { - + private final List blackListMembers; - + public BlackListReplicable(List blackListMembers) { if (blackListMembers == null) { this.blackListMembers = new ArrayList<>(); diff --git a/gossip-base/src/main/java/org/apache/gossip/replication/DataCenterReplicable.java b/gossip-base/src/main/java/org/apache/gossip/replication/DataCenterReplicable.java index 1067c49..60ebf65 100644 --- a/gossip-base/src/main/java/org/apache/gossip/replication/DataCenterReplicable.java +++ b/gossip-base/src/main/java/org/apache/gossip/replication/DataCenterReplicable.java @@ -28,19 +28,21 @@ import org.apache.gossip.model.Base; * @see Replicable */ public class DataCenterReplicable implements Replicable { - + @Override public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) { if (!me.getProperties().containsKey(DatacenterRackAwareActiveGossiper.DATACENTER)) { // replicate to others if I am not belong to any data center return true; - } else if (!destination.getProperties() - .containsKey(DatacenterRackAwareActiveGossiper.DATACENTER)) { + } else if (!destination + .getProperties() + .containsKey(DatacenterRackAwareActiveGossiper.DATACENTER)) { // Do not replicate if the destination data center is not defined return false; } else { - return me.getProperties().get(DatacenterRackAwareActiveGossiper.DATACENTER) - .equals(destination.getProperties().get(DatacenterRackAwareActiveGossiper.DATACENTER)); + return me.getProperties() + .get(DatacenterRackAwareActiveGossiper.DATACENTER) + .equals(destination.getProperties().get(DatacenterRackAwareActiveGossiper.DATACENTER)); } } } diff --git a/gossip-base/src/main/java/org/apache/gossip/replication/NotReplicable.java b/gossip-base/src/main/java/org/apache/gossip/replication/NotReplicable.java index c3fa538..6eac0ee 100644 --- a/gossip-base/src/main/java/org/apache/gossip/replication/NotReplicable.java +++ b/gossip-base/src/main/java/org/apache/gossip/replication/NotReplicable.java @@ -27,7 +27,7 @@ import org.apache.gossip.model.Base; * @see Replicable */ public class NotReplicable implements Replicable { - + @Override public boolean shouldReplicate(LocalMember me, LocalMember destination, T message) { return false; diff --git a/gossip-base/src/main/java/org/apache/gossip/replication/Replicable.java b/gossip-base/src/main/java/org/apache/gossip/replication/Replicable.java index 68098df..f6bb7ee 100644 --- a/gossip-base/src/main/java/org/apache/gossip/replication/Replicable.java +++ b/gossip-base/src/main/java/org/apache/gossip/replication/Replicable.java @@ -21,14 +21,15 @@ import org.apache.gossip.LocalMember; import org.apache.gossip.model.Base; /** - * This interface is used to determine whether a data item needs to be replicated to - * another gossip member. + * This interface is used to determine whether a data item needs to be replicated to another gossip + * member. * * @param A subtype of the class {@link org.apache.gossip.model.Base} which uses this interface */ public interface Replicable { /** * Test for a given data item needs to be replicated. + * * @param me node that the data item is going to transmit from. * @param destination target node to replicate. * @param message this parameter is currently ignored diff --git a/gossip-base/src/main/java/org/apache/gossip/replication/WhiteListReplicable.java b/gossip-base/src/main/java/org/apache/gossip/replication/WhiteListReplicable.java index 299d929..5d1b43d 100644 --- a/gossip-base/src/main/java/org/apache/gossip/replication/WhiteListReplicable.java +++ b/gossip-base/src/main/java/org/apache/gossip/replication/WhiteListReplicable.java @@ -17,11 +17,10 @@ */ package org.apache.gossip.replication; -import org.apache.gossip.LocalMember; -import org.apache.gossip.model.Base; - import java.util.ArrayList; import java.util.List; +import org.apache.gossip.LocalMember; +import org.apache.gossip.model.Base; /** * Replicable implementation which replicates data to given set of nodes. diff --git a/gossip-base/src/main/java/org/apache/gossip/secure/KeyTool.java b/gossip-base/src/main/java/org/apache/gossip/secure/KeyTool.java index 69f4e72..8926d8c 100644 --- a/gossip-base/src/main/java/org/apache/gossip/secure/KeyTool.java +++ b/gossip-base/src/main/java/org/apache/gossip/secure/KeyTool.java @@ -30,8 +30,8 @@ import java.security.SecureRandom; public class KeyTool { - public static void generatePubandPrivateKeyFiles(String path, String id) - throws NoSuchAlgorithmException, NoSuchProviderException, IOException{ + public static void generatePubandPrivateKeyFiles(String path, String id) + throws NoSuchAlgorithmException, NoSuchProviderException, IOException { SecureRandom r = new SecureRandom(); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN"); keyGen.initialize(1024, r); @@ -49,9 +49,9 @@ public class KeyTool { sigfos.close(); } } - - public static void main (String [] args) throws - NoSuchAlgorithmException, NoSuchProviderException, IOException{ + + public static void main(String[] args) + throws NoSuchAlgorithmException, NoSuchProviderException, IOException { generatePubandPrivateKeyFiles(args[0], args[1]); } } diff --git a/gossip-base/src/main/java/org/apache/gossip/transport/AbstractTransportManager.java b/gossip-base/src/main/java/org/apache/gossip/transport/AbstractTransportManager.java index 82b0dfb..941e3b2 100644 --- a/gossip-base/src/main/java/org/apache/gossip/transport/AbstractTransportManager.java +++ b/gossip-base/src/main/java/org/apache/gossip/transport/AbstractTransportManager.java @@ -18,27 +18,25 @@ package org.apache.gossip.transport; import com.codahale.metrics.MetricRegistry; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.manager.AbstractActiveGossiper; import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.utils.ReflectionUtils; -import org.apache.log4j.Logger; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; /** * Manage the protcol threads (active and passive gossipers). */ +@Slf4j public abstract class AbstractTransportManager implements TransportManager { - - public static final Logger LOGGER = Logger.getLogger(AbstractTransportManager.class); - - private final ExecutorService gossipThreadExecutor; - private final AbstractActiveGossiper activeGossipThread; + protected final GossipManager gossipManager; protected final GossipCore gossipCore; + private final ExecutorService gossipThreadExecutor; + private final AbstractActiveGossiper activeGossipThread; public AbstractTransportManager(GossipManager gossipManager, GossipCore gossipCore) { this.gossipManager = gossipManager; @@ -65,10 +63,10 @@ public abstract class AbstractTransportManager implements TransportManager { boolean result = gossipThreadExecutor.awaitTermination(10, TimeUnit.MILLISECONDS); if (!result) { // common when blocking patterns are used to read data from a socket. - LOGGER.warn("executor shutdown timed out"); + log.warn("executor shutdown timed out"); } } catch (InterruptedException e) { - LOGGER.error(e); + log.error("Error!", e); } gossipThreadExecutor.shutdownNow(); } diff --git a/gossip-base/src/main/java/org/apache/gossip/transport/TransportManager.java b/gossip-base/src/main/java/org/apache/gossip/transport/TransportManager.java index 99354d1..dd1205a 100644 --- a/gossip-base/src/main/java/org/apache/gossip/transport/TransportManager.java +++ b/gossip-base/src/main/java/org/apache/gossip/transport/TransportManager.java @@ -22,19 +22,25 @@ import java.net.URI; /** interface for manager that sends and receives messages that have already been serialized. */ public interface TransportManager { - - /** starts the active gossip thread responsible for reaching out to remote nodes. Not related to `startEndpoint()` */ + + /** + * starts the active gossip thread responsible for reaching out to remote nodes. Not related to + * `startEndpoint()` + */ void startActiveGossiper(); - - /** starts the passive gossip thread that receives messages from remote nodes. Not related to `startActiveGossiper()` */ + + /** + * starts the passive gossip thread that receives messages from remote nodes. Not related to + * `startActiveGossiper()` + */ void startEndpoint(); - + /** attempts to shutdown all threads. */ void shutdown(); - + /** sends a payload to an endpoint. */ void send(URI endpoint, byte[] buf) throws IOException; - + /** gets the next payload being sent to this node */ byte[] read() throws IOException; } diff --git a/gossip-base/src/main/java/org/apache/gossip/udp/Trackable.java b/gossip-base/src/main/java/org/apache/gossip/udp/Trackable.java index 9ecc7f2..5b9e93f 100644 --- a/gossip-base/src/main/java/org/apache/gossip/udp/Trackable.java +++ b/gossip-base/src/main/java/org/apache/gossip/udp/Trackable.java @@ -20,11 +20,10 @@ package org.apache.gossip.udp; public interface Trackable { String getUriFrom(); - + void setUriFrom(String uriFrom); - + String getUuid(); - + void setUuid(String uuid); - } diff --git a/gossip-base/src/main/java/org/apache/gossip/udp/UdpActiveGossipMessage.java b/gossip-base/src/main/java/org/apache/gossip/udp/UdpActiveGossipMessage.java index b6e8101..b077007 100644 --- a/gossip-base/src/main/java/org/apache/gossip/udp/UdpActiveGossipMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/udp/UdpActiveGossipMessage.java @@ -23,27 +23,31 @@ public class UdpActiveGossipMessage extends ActiveGossipMessage implements Track private String uriFrom; private String uuid; - + public String getUriFrom() { return uriFrom; } - + public void setUriFrom(String uriFrom) { this.uriFrom = uriFrom; } - + public String getUuid() { return uuid; } - + public void setUuid(String uuid) { this.uuid = uuid; } @Override public String toString() { - return "UdpActiveGossipMessage [uriFrom=" + uriFrom + ", uuid=" + uuid + ", getMembers()=" - + getMembers() + "]"; + return "UdpActiveGossipMessage [uriFrom=" + + uriFrom + + ", uuid=" + + uuid + + ", getMembers()=" + + getMembers() + + "]"; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/udp/UdpActiveGossipOk.java b/gossip-base/src/main/java/org/apache/gossip/udp/UdpActiveGossipOk.java index b70bb69..a224409 100644 --- a/gossip-base/src/main/java/org/apache/gossip/udp/UdpActiveGossipOk.java +++ b/gossip-base/src/main/java/org/apache/gossip/udp/UdpActiveGossipOk.java @@ -21,24 +21,22 @@ import org.apache.gossip.model.ActiveGossipOk; public class UdpActiveGossipOk extends ActiveGossipOk implements Trackable { - private String uriFrom; private String uuid; - + public String getUriFrom() { return uriFrom; } - + public void setUriFrom(String uriFrom) { this.uriFrom = uriFrom; } - + public String getUuid() { return uuid; } - + public void setUuid(String uuid) { this.uuid = uuid; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/udp/UdpNotAMemberFault.java b/gossip-base/src/main/java/org/apache/gossip/udp/UdpNotAMemberFault.java index 7afcb87..551907c 100644 --- a/gossip-base/src/main/java/org/apache/gossip/udp/UdpNotAMemberFault.java +++ b/gossip-base/src/main/java/org/apache/gossip/udp/UdpNotAMemberFault.java @@ -19,28 +19,25 @@ package org.apache.gossip.udp; import org.apache.gossip.model.NotAMemberFault; -public class UdpNotAMemberFault extends NotAMemberFault implements Trackable{ +public class UdpNotAMemberFault extends NotAMemberFault implements Trackable { - public UdpNotAMemberFault(){ - - } private String uriFrom; private String uuid; - + public UdpNotAMemberFault() {} + public String getUriFrom() { return uriFrom; } - + public void setUriFrom(String uriFrom) { this.uriFrom = uriFrom; } - + public String getUuid() { return uuid; } - + public void setUuid(String uuid) { this.uuid = uuid; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/udp/UdpPerNodeDataBulkMessage.java b/gossip-base/src/main/java/org/apache/gossip/udp/UdpPerNodeDataBulkMessage.java index 99eb1e5..aedf8c4 100644 --- a/gossip-base/src/main/java/org/apache/gossip/udp/UdpPerNodeDataBulkMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/udp/UdpPerNodeDataBulkMessage.java @@ -23,27 +23,31 @@ public class UdpPerNodeDataBulkMessage extends PerNodeDataBulkMessage implements private String uriFrom; private String uuid; - + public String getUriFrom() { return uriFrom; } - + public void setUriFrom(String uriFrom) { this.uriFrom = uriFrom; } - + public String getUuid() { return uuid; } - + public void setUuid(String uuid) { this.uuid = uuid; } @Override public String toString() { - return "UdpGossipDataMessage [uriFrom=" + uriFrom + ", uuid=" + uuid - + ", messages=[" + super.toString() + "] ]"; + return "UdpGossipDataMessage [uriFrom=" + + uriFrom + + ", uuid=" + + uuid + + ", messages=[" + + super.toString() + + "] ]"; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/udp/UdpPerNodeDataMessage.java b/gossip-base/src/main/java/org/apache/gossip/udp/UdpPerNodeDataMessage.java index 9ba1e85..d75c342 100644 --- a/gossip-base/src/main/java/org/apache/gossip/udp/UdpPerNodeDataMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/udp/UdpPerNodeDataMessage.java @@ -23,27 +23,31 @@ public class UdpPerNodeDataMessage extends PerNodeDataMessage implements Trackab private String uriFrom; private String uuid; - + public String getUriFrom() { return uriFrom; } - + public void setUriFrom(String uriFrom) { this.uriFrom = uriFrom; } - + public String getUuid() { return uuid; } - + public void setUuid(String uuid) { this.uuid = uuid; } @Override public String toString() { - return "UdpGossipDataMessage [uriFrom=" + uriFrom + ", uuid=" + uuid - + ", getReplicable()=" + getReplicable() + "]"; + return "UdpGossipDataMessage [uriFrom=" + + uriFrom + + ", uuid=" + + uuid + + ", getReplicable()=" + + getReplicable() + + "]"; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/udp/UdpSharedDataBulkMessage.java b/gossip-base/src/main/java/org/apache/gossip/udp/UdpSharedDataBulkMessage.java index 8dc8be1..d1f5ef6 100644 --- a/gossip-base/src/main/java/org/apache/gossip/udp/UdpSharedDataBulkMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/udp/UdpSharedDataBulkMessage.java @@ -23,27 +23,32 @@ public class UdpSharedDataBulkMessage extends SharedDataBulkMessage implements T private String uriFrom; private String uuid; - + public String getUriFrom() { return uriFrom; } - + public void setUriFrom(String uriFrom) { this.uriFrom = uriFrom; } - + public String getUuid() { return uuid; } - + public void setUuid(String uuid) { this.uuid = uuid; } @Override public String toString() { - return "UdpSharedGossipDataMessage [uriFrom=" + uriFrom + ", uuid=" + uuid + ", getNodeId()=" - + ", messages=[" + super.toString() + "] ]"; + return "UdpSharedGossipDataMessage [uriFrom=" + + uriFrom + + ", uuid=" + + uuid + + ", getNodeId()=" + + ", messages=[" + + super.toString() + + "] ]"; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/udp/UdpSharedDataMessage.java b/gossip-base/src/main/java/org/apache/gossip/udp/UdpSharedDataMessage.java index 0059bdb..95a0e62 100644 --- a/gossip-base/src/main/java/org/apache/gossip/udp/UdpSharedDataMessage.java +++ b/gossip-base/src/main/java/org/apache/gossip/udp/UdpSharedDataMessage.java @@ -23,29 +23,41 @@ public class UdpSharedDataMessage extends SharedDataMessage implements Trackable private String uriFrom; private String uuid; - + public String getUriFrom() { return uriFrom; } - + public void setUriFrom(String uriFrom) { this.uriFrom = uriFrom; } - + public String getUuid() { return uuid; } - + public void setUuid(String uuid) { this.uuid = uuid; } @Override public String toString() { - return "UdpSharedGossipDataMessage [uriFrom=" + uriFrom + ", uuid=" + uuid + ", getNodeId()=" - + getNodeId() + ", getKey()=" + getKey() + ", getPayload()=" + getPayload() - + ", getTimestamp()=" + getTimestamp() + ", getExpireAt()=" + getExpireAt() - + ", getReplicable()=" + getReplicable() + "]"; + return "UdpSharedGossipDataMessage [uriFrom=" + + uriFrom + + ", uuid=" + + uuid + + ", getNodeId()=" + + getNodeId() + + ", getKey()=" + + getKey() + + ", getPayload()=" + + getPayload() + + ", getTimestamp()=" + + getTimestamp() + + ", getExpireAt()=" + + getExpireAt() + + ", getReplicable()=" + + getReplicable() + + "]"; } - } diff --git a/gossip-base/src/main/java/org/apache/gossip/utils/ReflectionUtils.java b/gossip-base/src/main/java/org/apache/gossip/utils/ReflectionUtils.java index 2ae4eb1..9427351 100644 --- a/gossip-base/src/main/java/org/apache/gossip/utils/ReflectionUtils.java +++ b/gossip-base/src/main/java/org/apache/gossip/utils/ReflectionUtils.java @@ -23,8 +23,9 @@ import java.lang.reflect.InvocationTargetException; public class ReflectionUtils { /** - * Create an instance of a thing. This method essentially makes code more readable by handing the various exception - * trapping. + * Create an instance of a thing. This method essentially makes code more readable by handing the + * various exception trapping. + * * @param className * @param constructorTypes * @param constructorArgs @@ -32,20 +33,23 @@ public class ReflectionUtils { * @return constructed instance of a thing. */ @SuppressWarnings("unchecked") - public static T constructWithReflection(String className, Class[] constructorTypes, Object[] constructorArgs) { + public static T constructWithReflection( + String className, Class[] constructorTypes, Object[] constructorArgs) { try { Constructor c = Class.forName(className).getConstructor(constructorTypes); c.setAccessible(true); return (T) c.newInstance(constructorArgs); } catch (InvocationTargetException e) { // catch ITE and throw the target if it is a RTE. - if (e.getTargetException() != null && RuntimeException.class.isAssignableFrom(e.getTargetException().getClass())) { + if (e.getTargetException() != null + && RuntimeException.class.isAssignableFrom(e.getTargetException().getClass())) { throw (RuntimeException) e.getTargetException(); } else { throw new RuntimeException(e); } } catch (ReflectiveOperationException others) { - // Note: No class in the above list should be a descendent of RuntimeException. Otherwise, we're just wrapping + // Note: No class in the above list should be a descendent of RuntimeException. Otherwise, + // we're just wrapping // and making stack traces confusing. throw new RuntimeException(others); } diff --git a/gossip-base/src/main/resources/log4j.properties b/gossip-base/src/main/resources/log4j.properties index e2a60e1..e3bcd5d 100644 --- a/gossip-base/src/main/resources/log4j.properties +++ b/gossip-base/src/main/resources/log4j.properties @@ -9,12 +9,9 @@ # 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 diff --git a/gossip-base/src/test/java/org/apache/gossip/AbstractIntegrationBase.java b/gossip-base/src/test/java/org/apache/gossip/AbstractIntegrationBase.java index d074706..d967a09 100644 --- a/gossip-base/src/test/java/org/apache/gossip/AbstractIntegrationBase.java +++ b/gossip-base/src/test/java/org/apache/gossip/AbstractIntegrationBase.java @@ -31,14 +31,14 @@ import org.junit.Before; public abstract class AbstractIntegrationBase { - List nodes = new ArrayList<>(); - - public void register(GossipManager manager){ + List nodes = new ArrayList<>(); + + public void register(GossipManager manager) { nodes.add(manager); } public void generateStandardNodes(final int memberCount) throws URISyntaxException { - if(nodes.size() > 0){ + if (nodes.size() > 0) { after(); nodes.clear(); } @@ -55,24 +55,30 @@ public abstract class AbstractIntegrationBase { for (int i = 1; i < memberCount + 1; ++i) { URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i)); - GossipManager gossipService = GossipManagerBuilder.newBuilder().cluster(cluster).uri(uri) - .id(i + "").gossipMembers(startupMembers).gossipSettings(settings).build(); + GossipManager gossipService = + GossipManagerBuilder.newBuilder() + .cluster(cluster) + .uri(uri) + .id(i + "") + .gossipMembers(startupMembers) + .gossipSettings(settings) + .build(); gossipService.init(); register(gossipService); } } + @Before - public void before(){ + public void before() { nodes = new ArrayList<>(); } - + @After - public void after(){ - for (GossipManager node: nodes){ - if (node !=null){ + public void after() { + for (GossipManager node : nodes) { + if (node != null) { node.shutdown(); } } } - } diff --git a/gossip-base/src/test/java/org/apache/gossip/MemberTest.java b/gossip-base/src/test/java/org/apache/gossip/MemberTest.java index 5f0d18a..d33ff56 100644 --- a/gossip-base/src/test/java/org/apache/gossip/MemberTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/MemberTest.java @@ -20,21 +20,31 @@ package org.apache.gossip; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; - -import org.junit.Assert; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; -@RunWith(JUnitPlatform.class) public class MemberTest { @Test public void testHashCodeFromGossip40() throws URISyntaxException { - Assert.assertNotEquals( - new LocalMember("mycluster", new URI("udp://4.4.4.4:1000"), "myid", 1, new HashMap(), 10, 5, "exponential") - .hashCode(), - new LocalMember("mycluster", new URI("udp://4.4.4.5:1005"), "yourid", 11, new HashMap(), 11, 6, "exponential") - .hashCode()); + Assertions.assertNotEquals(new LocalMember( + "mycluster", + new URI("udp://4.4.4.4:1000"), + "myid", + 1, + new HashMap<>(), + 10, + 5, + "exponential") + .hashCode(), new LocalMember( + "mycluster", + new URI("udp://4.4.4.5:1005"), + "yourid", + 11, + new HashMap<>(), + 11, + 6, + "exponential") + .hashCode()); } } 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 index 3434c17..5fdc8fe 100644 --- a/gossip-base/src/test/java/org/apache/gossip/accrual/FailureDetectorTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/accrual/FailureDetectorTest.java @@ -17,24 +17,15 @@ */ 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; +import org.apache.gossip.GossipSettings; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; -@RunWith(JUnitPlatform.class) public class FailureDetectorTest { - @FunctionalInterface - interface TriConsumer { - void accept(A a, B b, C c); - } - static final Double failureThreshold = new GossipSettings().getConvictThreshold(); List generateTimeList(int begin, int end, int step) { @@ -52,8 +43,8 @@ public class FailureDetectorTest { public void normalDistribution() { FailureDetector fd = new FailureDetector(1, 1000, "normal"); List values = generateTimeList(0, 10000, 100); - Double deltaSum = 0.0; - Integer deltaCount = 0; + double deltaSum = 0.0; + int deltaCount = 0; for (int i = 0; i < values.size() - 1; i++) { fd.recordHeartbeat(values.get(i)); if (i != 0) { @@ -64,21 +55,23 @@ public class FailureDetectorTest { 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); + Assertions.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); + Assertions.assertEquals(fd.computePhiMeasure(lastRecorded + Math.round(deltaSum / deltaCount)), + -Math.log10(0.5), + 0.1); } @Test public void checkMinimumSamples() { - Integer minimumSamples = 5; + int 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)); + Assertions.assertNull(fd.computePhiMeasure(100)); fd.recordHeartbeat(i); } - Assert.assertNotNull(fd.computePhiMeasure(100)); + Assertions.assertNotNull(fd.computePhiMeasure(100)); } @Test @@ -86,28 +79,33 @@ public class FailureDetectorTest { final FailureDetector fd = new FailureDetector(5, 1000, "normal"); TriConsumer checkAlive = (begin, end, step) -> { List 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); + for (Integer time : times) { + Double current = fd.computePhiMeasure(time); + if (current != null) { + Assertions.assertTrue(current < failureThreshold); + } + fd.recordHeartbeat(time); } - fd.recordHeartbeat(times.get(i)); - } }; TriConsumer checkDeadMonotonic = (begin, end, step) -> { List 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); + for (Integer time : times) { + Double current = fd.computePhiMeasure(time); + if (current != null && prev != null) { + Assertions.assertTrue(current >= prev); + } + prev = current; } - prev = current; - } }; checkAlive.accept(0, 20000, 100); checkDeadMonotonic.accept(20000, 20500, 5); } + + @FunctionalInterface + interface TriConsumer { + void accept(A a, B b, C c); + } } diff --git a/gossip-base/src/test/java/org/apache/gossip/crdt/AddRemoveStringSetTest.java b/gossip-base/src/test/java/org/apache/gossip/crdt/AddRemoveStringSetTest.java index 6dac9df..4cc8b44 100644 --- a/gossip-base/src/test/java/org/apache/gossip/crdt/AddRemoveStringSetTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/crdt/AddRemoveStringSetTest.java @@ -39,16 +39,17 @@ import java.util.stream.Stream; */ @Ignore -public abstract class AddRemoveStringSetTest, SetType>> { +public abstract class AddRemoveStringSetTest< + SetType extends CrdtAddRemoveSet, SetType>> { + + private Set sampleSet; abstract SetType construct(Set set); abstract SetType construct(); - private Set sampleSet; - @Before - public void setup(){ + public void setup() { sampleSet = new HashSet<>(); sampleSet.add("4"); sampleSet.add("5"); @@ -56,24 +57,25 @@ public abstract class AddRemoveStringSetTest hashSet = new HashSet<>(); SetType set = construct(); - for (int it = 0; it < 40; it++){ + for (int it = 0; it < 40; it++) { SetType newSet; - if (it % 5 == 1){ - //deleting existing - String forDelete = hashSet.stream().skip((long) (hashSet.size() * Math.random())).findFirst().get(); + if (it % 5 == 1) { + // deleting existing + String forDelete = + hashSet.stream().skip((long) (hashSet.size() * Math.random())).findFirst().get(); newSet = set.remove(forDelete); Assert.assertEquals(set.value(), hashSet); // check old version is immutable hashSet.remove(forDelete); } else { - //adding + // adding String forAdd = String.valueOf((int) (10000 * Math.random())); newSet = set.add(forAdd); Assert.assertEquals(set.value(), hashSet); // check old version is immutable @@ -85,7 +87,7 @@ public abstract class AddRemoveStringSetTest hashSet1 = new HashSet<>(), hashSet2 = new HashSet<>(); SetType set1 = construct(), set2 = construct(); - for (int it = 0; it < 100; it++){ + for (int it = 0; it < 100; it++) { String forAdd = String.valueOf((int) (10000 * Math.random())); - if (it % 2 == 0){ + if (it % 2 == 0) { hashSet1.add(forAdd); set1 = set1.add(forAdd); } else { @@ -125,12 +128,13 @@ public abstract class AddRemoveStringSetTest mergedSet = Stream.concat(hashSet1.stream(), hashSet2.stream()).collect(Collectors.toSet()); + Set mergedSet = + Stream.concat(hashSet1.stream(), hashSet2.stream()).collect(Collectors.toSet()); Assert.assertEquals(set1.merge(set2).value(), mergedSet); } @Test - public void abstractOptimizeTest(){ + public void abstractOptimizeTest() { Assert.assertEquals(construct(sampleSet).value(), sampleSet); Assert.assertEquals(construct(sampleSet).optimize().value(), sampleSet); } 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 index 3a134af..7189468 100644 --- a/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlyCounterTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlyCounterTest.java @@ -17,11 +17,10 @@ */ package org.apache.gossip.crdt; -import org.junit.Assert; -import org.junit.Test; - import java.util.HashMap; import java.util.Map; +import org.junit.Assert; +import org.junit.Test; public class GrowOnlyCounterTest { 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 index d4f12b6..b39356e 100644 --- a/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlySetTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/crdt/GrowOnlySetTest.java @@ -27,12 +27,13 @@ public class GrowOnlySetTest { @SuppressWarnings("rawtypes") @Test - public void mergeTest(){ + public void mergeTest() { ConcurrentHashMap a = new ConcurrentHashMap<>(); GrowOnlySet gset = new GrowOnlySet<>(Arrays.asList("a", "b")); Assert.assertEquals(gset, a.merge("a", gset, new CrdtBiFunctionMerge())); GrowOnlySet over = new GrowOnlySet<>(Arrays.asList("b", "d")); - Assert.assertEquals(new GrowOnlySet<>(Arrays.asList("a", "b", "d")), - a.merge("a", over, CrdtBiFunctionMerge::applyStatic)); + Assert.assertEquals( + new GrowOnlySet<>(Arrays.asList("a", "b", "d")), + a.merge("a", over, CrdtBiFunctionMerge::applyStatic)); } } diff --git a/gossip-base/src/test/java/org/apache/gossip/crdt/LwwSetTest.java b/gossip-base/src/test/java/org/apache/gossip/crdt/LwwSetTest.java index c4da83d..cf2372f 100644 --- a/gossip-base/src/test/java/org/apache/gossip/crdt/LwwSetTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/crdt/LwwSetTest.java @@ -28,18 +28,18 @@ import java.util.Map; import java.util.Set; public class LwwSetTest extends AddRemoveStringSetTest> { - static private Clock clock = new SystemClock(); + private static Clock clock = new SystemClock(); - LwwSet construct(Set set){ + LwwSet construct(Set set) { return new LwwSet<>(set); } - LwwSet construct(){ + LwwSet construct() { return new LwwSet<>(); } @Test - public void valueTest(){ + public void valueTest() { Map map = new HashMap<>(); map.put('a', new LwwSet.Timestamps(1, 0)); map.put('b', new LwwSet.Timestamps(1, 2)); @@ -52,14 +52,15 @@ public class LwwSetTest extends AddRemoveStringSetTest> { } @Test - public void fakeTimeMergeTest(){ - // try to create LWWSet with time from future (simulate other process with its own clock) and validate result + public void fakeTimeMergeTest() { + // try to create LWWSet with time from future (simulate other process with its own clock) and + // validate result // check remove from the future Map map = new HashMap<>(); map.put(25, new LwwSet.Timestamps(clock.nanoTime(), Long.MAX_VALUE)); LwwSet lww = new LwwSet<>(map); Assert.assertEquals(lww, new LwwSet()); - //create new LWWSet with element 25, and merge with other LWW which has remove in future + // create new LWWSet with element 25, and merge with other LWW which has remove in future Assert.assertEquals(new LwwSet<>(25).merge(lww), new LwwSet()); // add in future diff --git a/gossip-base/src/test/java/org/apache/gossip/crdt/MaxChangeSetTest.java b/gossip-base/src/test/java/org/apache/gossip/crdt/MaxChangeSetTest.java index 3828747..d2a9ce6 100644 --- a/gossip-base/src/test/java/org/apache/gossip/crdt/MaxChangeSetTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/crdt/MaxChangeSetTest.java @@ -17,13 +17,12 @@ */ package org.apache.gossip.crdt; -import org.junit.Assert; -import org.junit.Test; - import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.junit.Assert; +import org.junit.Test; public class MaxChangeSetTest extends AddRemoveStringSetTest> { MaxChangeSet construct(Set set){ 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 index 8b21360..be7f605 100644 --- a/gossip-base/src/test/java/org/apache/gossip/crdt/OrSetTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/crdt/OrSetTest.java @@ -17,13 +17,12 @@ */ package org.apache.gossip.crdt; -import org.junit.Assert; -import org.junit.Test; - import java.util.Arrays; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import org.junit.Assert; +import org.junit.Test; public class OrSetTest extends AddRemoveStringSetTest> { OrSet construct(){ diff --git a/gossip-base/src/test/java/org/apache/gossip/crdt/PNCounterTest.java b/gossip-base/src/test/java/org/apache/gossip/crdt/PNCounterTest.java index 8128cde..1ce0bb8 100644 --- a/gossip-base/src/test/java/org/apache/gossip/crdt/PNCounterTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/crdt/PNCounterTest.java @@ -133,5 +133,4 @@ public class PNCounterTest { counter2 = counter2.merge(counter3); Assert.assertEquals(1, (long) counter3.value()); } - } diff --git a/gossip-base/src/test/java/org/apache/gossip/crdt/TwoPhaseSetTest.java b/gossip-base/src/test/java/org/apache/gossip/crdt/TwoPhaseSetTest.java index 3af1920..8ac5d0b 100644 --- a/gossip-base/src/test/java/org/apache/gossip/crdt/TwoPhaseSetTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/crdt/TwoPhaseSetTest.java @@ -30,7 +30,7 @@ public class TwoPhaseSetTest { private Set sampleSet; @Before - public void setup(){ + public void setup() { sampleSet = new HashSet<>(); sampleSet.add("a"); sampleSet.add("b"); @@ -38,12 +38,12 @@ public class TwoPhaseSetTest { } @Test - public void setConstructorTest(){ + public void setConstructorTest() { Assert.assertEquals(new TwoPhaseSet<>(sampleSet).value(), sampleSet); } @Test - public void valueTest(){ + public void valueTest() { Set added = new HashSet<>(); added.add('a'); added.add('b'); @@ -53,7 +53,7 @@ public class TwoPhaseSetTest { } @Test - public void optimizeTest(){ + public void optimizeTest() { TwoPhaseSet set = new TwoPhaseSet<>(sampleSet); set = set.remove("b"); Assert.assertEquals(set.optimize(), set); @@ -62,7 +62,7 @@ public class TwoPhaseSetTest { } @Test - public void immutabilityTest(){ + public void immutabilityTest() { TwoPhaseSet set = new TwoPhaseSet<>(sampleSet); TwoPhaseSet newSet = set.remove("b"); Assert.assertNotEquals(set, newSet); @@ -70,12 +70,13 @@ public class TwoPhaseSetTest { } @Test - public void removeMissingAddExistingLimitsTest(){ - BiConsumer, TwoPhaseSet> checkInternals = (f, s) -> { - Assert.assertEquals(s, f); - Assert.assertEquals(s.getRemoved(), f.getRemoved()); - Assert.assertEquals(s.getAdded(), f.getAdded()); - }; + public void removeMissingAddExistingLimitsTest() { + BiConsumer, TwoPhaseSet> checkInternals = + (f, s) -> { + Assert.assertEquals(s, f); + Assert.assertEquals(s.getRemoved(), f.getRemoved()); + Assert.assertEquals(s.getAdded(), f.getAdded()); + }; TwoPhaseSet set = new TwoPhaseSet<>(sampleSet); // remove missing checkInternals.accept(set, set.remove("e")); @@ -83,11 +84,13 @@ public class TwoPhaseSetTest { checkInternals.accept(set, set.add("a")); // limits TwoPhaseSet newSet = set.remove("a"); // allow this remove - Assert.assertEquals(newSet.add("a"), new TwoPhaseSet<>("b", "d")); // discard this add, "a" was added and removed + Assert.assertEquals( + newSet.add("a"), + new TwoPhaseSet<>("b", "d")); // discard this add, "a" was added and removed } @Test - public void mergeTest(){ + public void mergeTest() { TwoPhaseSet f = new TwoPhaseSet<>(sampleSet); TwoPhaseSet s = new TwoPhaseSet<>("a", "c"); s = s.remove("a"); diff --git a/gossip-base/src/test/java/org/apache/gossip/event/data/DataEventManagerTest.java b/gossip-base/src/test/java/org/apache/gossip/event/data/DataEventManagerTest.java index d9d778f..e75bcf7 100644 --- a/gossip-base/src/test/java/org/apache/gossip/event/data/DataEventManagerTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/event/data/DataEventManagerTest.java @@ -21,39 +21,35 @@ import com.codahale.metrics.MetricRegistry; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; -@RunWith(JUnitPlatform.class) public class DataEventManagerTest { - + private static Semaphore semaphore; private String receivedNodeId; private String receivedKey; private Object receivedNewValue; private Object receivedOldValue; - + @BeforeClass public static void setup() { semaphore = new Semaphore(0); } - + @Test public void perNodeDataEventHandlerAddRemoveTest() { DataEventManager eventManager = new DataEventManager(new MetricRegistry()); - - UpdateNodeDataEventHandler nodeDataEventHandler = (nodeId, key, oldValue, newValue) -> { - }; - + + UpdateNodeDataEventHandler nodeDataEventHandler = (nodeId, key, oldValue, newValue) -> {}; + eventManager.registerPerNodeDataSubscriber(nodeDataEventHandler); Assert.assertEquals(1, eventManager.getPerNodeSubscribersSize()); eventManager.unregisterPerNodeDataSubscriber(nodeDataEventHandler); Assert.assertEquals(0, eventManager.getPerNodeSubscribersSize()); } - + // Test whether the per node data events are fired for matching key @Test public void perNodeDataEventHandlerTest() throws InterruptedException { @@ -61,106 +57,105 @@ public class DataEventManagerTest { resetData(); // A new subscriber "Juliet" is like to notified when per node data change for the key "Romeo" - UpdateNodeDataEventHandler juliet = (nodeId, key, oldValue, newValue) -> { - if(!key.equals("Romeo")) return; - receivedNodeId = nodeId; - receivedKey = key; - receivedNewValue = newValue; - receivedOldValue = oldValue; - semaphore.release(); - }; + UpdateNodeDataEventHandler juliet = + (nodeId, key, oldValue, newValue) -> { + if (!key.equals("Romeo")) return; + receivedNodeId = nodeId; + receivedKey = key; + receivedNewValue = newValue; + receivedOldValue = oldValue; + semaphore.release(); + }; // Juliet register with eventManager eventManager.registerPerNodeDataSubscriber(juliet); // Romeo is going to sleep after having dinner eventManager.notifyPerNodeData("Montague", "Romeo", "sleeping", "eating"); - + // Juliet should notified semaphore.tryAcquire(2, TimeUnit.SECONDS); Assert.assertEquals("Montague", receivedNodeId); Assert.assertEquals("Romeo", receivedKey); Assert.assertEquals("sleeping", receivedNewValue); Assert.assertEquals("eating", receivedOldValue); - + eventManager.unregisterPerNodeDataSubscriber(juliet); } - + @Test public void sharedDataEventHandlerAddRemoveTest() { DataEventManager eventManager = new DataEventManager(new MetricRegistry()); - - UpdateSharedDataEventHandler sharedDataEventHandler = (key, oldValue, newValue) -> { - - }; + + UpdateSharedDataEventHandler sharedDataEventHandler = (key, oldValue, newValue) -> {}; + eventManager.registerSharedDataSubscriber(sharedDataEventHandler); Assert.assertEquals(1, eventManager.getSharedDataSubscribersSize()); eventManager.unregisterSharedDataSubscriber(sharedDataEventHandler); Assert.assertEquals(0, eventManager.getSharedDataSubscribersSize()); - } - + // Test whether the shared data events are fired @Test public void sharedDataEventHandlerTest() throws InterruptedException { DataEventManager eventManager = new DataEventManager(new MetricRegistry()); resetData(); - + // A new subscriber "Alice" is like to notified when shared data change for the key "technology" - UpdateSharedDataEventHandler alice = (key, oldValue, newValue) -> { - if(!key.equals("technology")) return; - receivedKey = key; - receivedNewValue = newValue; - receivedOldValue = oldValue; - semaphore.release(); - }; + UpdateSharedDataEventHandler alice = + (key, oldValue, newValue) -> { + if (!key.equals("technology")) return; + receivedKey = key; + receivedNewValue = newValue; + receivedOldValue = oldValue; + semaphore.release(); + }; // Alice register with eventManager eventManager.registerSharedDataSubscriber(alice); - + // technology key get changed eventManager.notifySharedData("technology", "Java has lambda", "Java is fast"); - + // Alice should notified semaphore.tryAcquire(2, TimeUnit.SECONDS); Assert.assertEquals("technology", receivedKey); Assert.assertEquals("Java has lambda", receivedNewValue); Assert.assertEquals("Java is fast", receivedOldValue); - + eventManager.unregisterSharedDataSubscriber(alice); } - + // Test the MetricRegistry @Test public void metricRegistryTest() { MetricRegistry registry = new MetricRegistry(); - + DataEventManager eventManager = new DataEventManager(registry); - - UpdateNodeDataEventHandler nodeDataEventHandler = (nodeId, key, oldValue, newValue) -> { - }; - - UpdateSharedDataEventHandler sharedDataEventHandler = (key, oldValue, newValue) -> { - }; - + + UpdateNodeDataEventHandler nodeDataEventHandler = (nodeId, key, oldValue, newValue) -> {}; + + UpdateSharedDataEventHandler sharedDataEventHandler = (key, oldValue, newValue) -> {}; + eventManager.registerPerNodeDataSubscriber(nodeDataEventHandler); eventManager.registerSharedDataSubscriber(sharedDataEventHandler); - - Assert.assertEquals(1, - registry.getGauges().get(DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_SIZE).getValue()); - Assert.assertEquals(0, - registry.getGauges().get(DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE) - .getValue()); - Assert.assertEquals(1, - registry.getGauges().get(DataEventConstants.SHARED_DATA_SUBSCRIBERS_SIZE).getValue()); - Assert.assertEquals(0, - registry.getGauges().get(DataEventConstants.SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE) - .getValue()); - + + Assert.assertEquals( + 1, registry.getGauges().get(DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_SIZE).getValue()); + Assert.assertEquals( + 0, + registry + .getGauges() + .get(DataEventConstants.PER_NODE_DATA_SUBSCRIBERS_QUEUE_SIZE) + .getValue()); + Assert.assertEquals( + 1, registry.getGauges().get(DataEventConstants.SHARED_DATA_SUBSCRIBERS_SIZE).getValue()); + Assert.assertEquals( + 0, + registry.getGauges().get(DataEventConstants.SHARED_DATA_SUBSCRIBERS_QUEUE_SIZE).getValue()); } - + private void resetData() { receivedNodeId = null; receivedKey = null; receivedNewValue = null; receivedOldValue = null; } - } diff --git a/gossip-base/src/test/java/org/apache/gossip/lock/vote/MajorityVoteTest.java b/gossip-base/src/test/java/org/apache/gossip/lock/vote/MajorityVoteTest.java index c558444..e7b1bb6 100644 --- a/gossip-base/src/test/java/org/apache/gossip/lock/vote/MajorityVoteTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/lock/vote/MajorityVoteTest.java @@ -19,14 +19,11 @@ package org.apache.gossip.lock.vote; import org.junit.Assert; import org.junit.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -@RunWith(JUnitPlatform.class) public class MajorityVoteTest { @Test @@ -45,7 +42,6 @@ public class MajorityVoteTest { Assert.assertTrue(result.value().get("1").getVotes().get("2").getVoteValue()); Assert.assertTrue(!result.value().get("3").getVotes().get("4").getVoteValue()); - } @Test @@ -64,7 +60,6 @@ public class MajorityVoteTest { Assert.assertTrue(result.value().get("1").getVotes().get("2").getVoteValue()); Assert.assertTrue(!result.value().get("1").getVotes().get("4").getVoteValue()); - } @Test @@ -75,8 +70,8 @@ public class MajorityVoteTest { MajorityVote first = new MajorityVote(voteCandidateMap1); Map voteCandidateMap2 = new HashMap<>(); - VoteCandidate candidateB = new VoteCandidate("1", "key1", - generateVotes(2, 4, true, false, true)); + VoteCandidate candidateB = + new VoteCandidate("1", "key1", generateVotes(2, 4, true, false, true)); voteCandidateMap2.put("1", candidateB); MajorityVote second = new MajorityVote(voteCandidateMap2); @@ -92,10 +87,10 @@ public class MajorityVoteTest { } for (int i = startingNodeId; i <= endNodeId; i++) { String nodeId = i + ""; - voteMap.put(nodeId, new Vote(nodeId, votes[i - startingNodeId], false, new ArrayList<>(), - new ArrayList<>())); + voteMap.put( + nodeId, + new Vote(nodeId, votes[i - startingNodeId], false, new ArrayList<>(), new ArrayList<>())); } return voteMap; } - } 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 index 1a9d43b..157f603 100644 --- a/gossip-base/src/test/java/org/apache/gossip/manager/DataReaperTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/manager/DataReaperTest.java @@ -34,7 +34,7 @@ public class DataReaperTest { String myId = "4"; String key = "key"; String value = "a"; - + @Test public void testReaperOneShot() { GossipSettings settings = new GossipSettings(); @@ -42,8 +42,14 @@ public class DataReaperTest { settings.setPersistDataState(false); settings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager"); settings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager"); - GossipManager gm = GossipManagerBuilder.newBuilder().cluster("abc").gossipSettings(settings) - .id(myId).uri(URI.create("udp://localhost:6000")).registry(registry).build(); + 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)); @@ -54,18 +60,20 @@ public class DataReaperTest { gm.shutdown(); } - private void assertDataIsAtCorrectValue(GossipManager gm){ + 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( + 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()); + Assert.assertEquals( + 1, registry.getGauges().get(GossipCoreConstants.SHARED_DATA_SIZE).getValue()); } - - private void assertDataIsRemoved(GossipManager gm){ + + 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); @@ -74,7 +82,7 @@ public class DataReaperTest { m.setTimestamp(System.currentTimeMillis()); return m; } - + private SharedDataMessage sharedDatum(String key, String value) { SharedDataMessage m = new SharedDataMessage(); m.setExpireAt(System.currentTimeMillis() + 5L); @@ -83,7 +91,7 @@ public class DataReaperTest { m.setTimestamp(System.currentTimeMillis()); return m; } - + @Test public void testHigherTimestampWins() { String myId = "4"; @@ -92,8 +100,14 @@ public class DataReaperTest { GossipSettings settings = new GossipSettings(); settings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager"); settings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager"); - GossipManager gm = GossipManagerBuilder.newBuilder().cluster("abc").gossipSettings(settings) - .id(myId).uri(URI.create("udp://localhost:7000")).registry(registry).build(); + 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"); @@ -104,5 +118,4 @@ public class DataReaperTest { Assert.assertEquals(value, gm.findPerNodeGossipData(myId, key).getPayload()); gm.shutdown(); } - } 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 index bc0b46a..c057962 100644 --- a/gossip-base/src/test/java/org/apache/gossip/manager/GossipManagerBuilderTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/manager/GossipManagerBuilderTest.java @@ -17,97 +17,108 @@ */ 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.MessageHandler; -import org.apache.gossip.manager.handlers.ResponseHandler; -import org.apache.gossip.manager.handlers.TypedMessageHandler; -import org.junit.Assert; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; +import static org.junit.jupiter.api.Assertions.*; -import javax.xml.ws.Response; +import com.codahale.metrics.MetricRegistry; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import org.apache.gossip.GossipSettings; +import org.apache.gossip.LocalMember; +import org.apache.gossip.Member; +import org.apache.gossip.manager.handlers.MessageHandler; +import org.apache.gossip.manager.handlers.ResponseHandler; +import org.apache.gossip.manager.handlers.TypedMessageHandlerWrapper; +import org.apache.gossip.model.Response; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -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 { private GossipManagerBuilder.ManagerBuilder builder; - + @BeforeEach public void setup() throws Exception { - builder = GossipManagerBuilder.newBuilder() - .id("id") - .cluster("aCluster") - .uri(new URI("udp://localhost:2000")) - .gossipSettings(new GossipSettings()); + builder = + GossipManagerBuilder.newBuilder() + .id("id") + .cluster("aCluster") + .uri(new URI("udp://localhost:2000")) + .gossipSettings(new GossipSettings()); } - + @Test public void idShouldNotBeNull() { - expectThrows(IllegalArgumentException.class,() -> { - GossipManagerBuilder.newBuilder().cluster("aCluster").build(); - }); + assertThrows( + IllegalArgumentException.class, + () -> { + GossipManagerBuilder.newBuilder().cluster("aCluster").build(); + }); } @Test public void clusterShouldNotBeNull() { - expectThrows(IllegalArgumentException.class,() -> { + assertThrows( + IllegalArgumentException.class, + () -> { GossipManagerBuilder.newBuilder().id("id").build(); - }); + }); } @Test public void settingsShouldNotBeNull() { - expectThrows(IllegalArgumentException.class,() -> { + assertThrows( + IllegalArgumentException.class, + () -> { GossipManagerBuilder.newBuilder().id("id").cluster("aCluster").build(); - }); + }); } - + @Test - public void createMembersListIfNull() throws URISyntaxException { - GossipManager gossipManager = builder.gossipMembers(null).registry(new MetricRegistry()).build(); + public void createMembersListIfNull() { + GossipManager gossipManager = + builder.gossipMembers(null).registry(new MetricRegistry()).build(); assertNotNull(gossipManager.getLiveMembers()); } @Test - public void createDefaultMessageHandlerIfNull() throws URISyntaxException { - GossipManager gossipManager = builder.messageHandler(null).registry(new MetricRegistry()).build(); + public void createDefaultMessageHandlerIfNull() { + GossipManager gossipManager = + builder.messageHandler(null).registry(new MetricRegistry()).build(); assertNotNull(gossipManager.getMessageHandler()); } @Test - public void testMessageHandlerKeeping() throws URISyntaxException { - MessageHandler mi = new TypedMessageHandler(Response.class, new ResponseHandler()); + public void testMessageHandlerKeeping() { + MessageHandler mi = new TypedMessageHandlerWrapper(Response.class, new ResponseHandler()); GossipManager gossipManager = builder.messageHandler(mi).registry(new MetricRegistry()).build(); assertNotNull(gossipManager.getMessageHandler()); - Assert.assertEquals(gossipManager.getMessageHandler(), mi); + assertEquals(gossipManager.getMessageHandler(), mi); } @Test public void useMemberListIfProvided() throws URISyntaxException { - LocalMember member = new LocalMember( - "aCluster", new URI("udp://localhost:2000"), "aGossipMember", - System.nanoTime(), new HashMap(), 1000, 1, "exponential"); + LocalMember member = + new LocalMember( + "aCluster", + new URI("udp://localhost:2000"), + "aGossipMember", + System.nanoTime(), + new HashMap(), + 1000, + 1, + "exponential"); List memberList = new ArrayList<>(); memberList.add(member); - GossipManager gossipManager = builder - .uri(new URI("udp://localhost:8000")) - .gossipMembers(memberList).registry(new MetricRegistry()).build(); + GossipManager gossipManager = + builder + .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 +} 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 index ebe0e2c..a9e2fd3 100644 --- a/gossip-base/src/test/java/org/apache/gossip/manager/RingPersistenceTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/manager/RingPersistenceTest.java @@ -30,35 +30,42 @@ import org.junit.Test; public class RingPersistenceTest { @Test - public void givenThatRingIsPersisted() throws UnknownHostException, InterruptedException, URISyntaxException { + 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() + + 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(); + 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 GossipManager.buildRingStatePath(gossipService); } - - private void aNewInstanceGetsRingInfo(GossipSettings settings) throws UnknownHostException, InterruptedException, URISyntaxException { - GossipManager gossipService2 = GossipManagerBuilder.newBuilder() + + 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(); + .gossipSettings(settings) + .build(); Assert.assertEquals(2, gossipService2.getMembers().size()); } - } 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 index e1e1127..6aa1e15 100644 --- a/gossip-base/src/test/java/org/apache/gossip/manager/UserDataPersistenceTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/manager/UserDataPersistenceTest.java @@ -32,44 +32,50 @@ import org.junit.Test; public class UserDataPersistenceTest { String nodeId = "1"; - - private GossipManager sameService() throws URISyntaxException { + + private GossipManager sameService() throws URISyntaxException { GossipSettings settings = new GossipSettings(); settings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager"); settings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager"); return GossipManagerBuilder.newBuilder() - .cluster("a") - .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1))) - .id(nodeId) - .gossipSettings(settings).build(); + .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 + 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> l = gossipService.getUserDataState().readPerNodeFromDisk(); + { // read the raw data and confirm + ConcurrentHashMap> l = + gossipService.getUserDataState().readPerNodeFromDisk(); Assert.assertEquals("red", ((AToothpick) l.get(nodeId).get("a").getPayload()).getColor()); } { - ConcurrentHashMap l = - gossipService.getUserDataState().readSharedDataFromDisk(); + ConcurrentHashMap 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 + { // 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()); + Assert.assertEquals( + "red", + ((AToothpick) gossipService.findPerNodeGossipData(nodeId, "a").getPayload()).getColor()); + Assert.assertEquals( + "blue", ((AToothpick) gossipService.findSharedGossipData("a").getPayload()).getColor()); File f = GossipManager.buildSharedDataPath(gossipService); File g = GossipManager.buildPerNodeDataPath(gossipService); gossipService.shutdown(); @@ -77,8 +83,8 @@ public class UserDataPersistenceTest { g.delete(); } } - - public PerNodeDataMessage getToothpick(){ + + public PerNodeDataMessage getToothpick() { AToothpick a = new AToothpick(); a.setColor("red"); PerNodeDataMessage d = new PerNodeDataMessage(); @@ -88,8 +94,8 @@ public class UserDataPersistenceTest { d.setTimestamp(System.currentTimeMillis()); return d; } - - public SharedDataMessage getAnotherToothpick(){ + + public SharedDataMessage getAnotherToothpick() { AToothpick a = new AToothpick(); a.setColor("blue"); SharedDataMessage d = new SharedDataMessage(); @@ -99,18 +105,18 @@ public class UserDataPersistenceTest { d.setTimestamp(System.currentTimeMillis()); return d; } - + public static class AToothpick { private String color; - public AToothpick(){ - - } + + public AToothpick() {} + public String getColor() { return color; } + public void setColor(String color) { this.color = color; } - } } diff --git a/gossip-base/src/test/java/org/apache/gossip/manager/handlers/MessageHandlerTest.java b/gossip-base/src/test/java/org/apache/gossip/manager/handlers/MessageHandlerTest.java index 42b9353..344ca3b 100644 --- a/gossip-base/src/test/java/org/apache/gossip/manager/handlers/MessageHandlerTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/manager/handlers/MessageHandlerTest.java @@ -26,12 +26,126 @@ import org.junit.Assert; import org.junit.Test; public class MessageHandlerTest { - private class FakeMessage extends Base { - public FakeMessage() { - } + @Test + public void testSimpleHandler() { + MessageHandler mi = new TypedMessageHandlerWrapper(FakeMessage.class, new DummyMessageHandler()); + Assert.assertTrue(mi.invoke(null, null, new FakeMessage())); + Assert.assertFalse(mi.invoke(null, null, new ActiveGossipMessage())); } - private class FakeMessageData extends Base { + @Test(expected = NullPointerException.class) + public void testSimpleHandlerNullClassConstructor() { + new TypedMessageHandlerWrapper(null, new DummyMessageHandler()); + } + + @Test(expected = NullPointerException.class) + public void testSimpleHandlerNullHandlerConstructor() { + new TypedMessageHandlerWrapper(FakeMessage.class, null); + } + + @Test + public void testCallCountSimpleHandler() { + DummyMessageHandler h = new DummyMessageHandler(); + MessageHandler mi = new TypedMessageHandlerWrapper(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) + @SuppressWarnings("all") + public void cantAddNullHandler() { + MessageHandler handler = MessageHandlerFactory.concurrentHandler(); + } + + @Test(expected = NullPointerException.class) + public void cantAddNullHandler2() { + MessageHandlerFactory.concurrentHandler( + new TypedMessageHandlerWrapper(FakeMessage.class, new DummyMessageHandler()), + null, + new TypedMessageHandlerWrapper(FakeMessage.class, new DummyMessageHandler())); + } + + @Test + public void testMessageHandlerCombiner() { + // Empty combiner - false result + MessageHandler mi = MessageHandlerFactory.concurrentHandler((gossipCore, gossipManager, base) -> false); + Assert.assertFalse(mi.invoke(null, null, new Base())); + + DummyMessageHandler h = new DummyMessageHandler(); + mi = + MessageHandlerFactory.concurrentHandler( + new TypedMessageHandlerWrapper(FakeMessage.class, h), + new TypedMessageHandlerWrapper(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 = MessageHandlerFactory.concurrentHandler(mi, new TypedMessageHandlerWrapper(FakeMessage.class, h)); + Assert.assertTrue(mi.invoke(null, null, new FakeMessage())); + Assert.assertEquals(5, h.counter); + } + + @Test + public void testMessageHandlerCombiner2levels() { + DummyMessageHandler messageHandler = new DummyMessageHandler(); + + MessageHandler mi1 = + MessageHandlerFactory.concurrentHandler( + new TypedMessageHandlerWrapper(FakeMessage.class, messageHandler), + new TypedMessageHandlerWrapper(FakeMessage.class, messageHandler)); + + MessageHandler mi2 = + MessageHandlerFactory.concurrentHandler( + new TypedMessageHandlerWrapper(FakeMessage.class, messageHandler), + new TypedMessageHandlerWrapper(FakeMessage.class, messageHandler)); + + MessageHandler mi = MessageHandlerFactory.concurrentHandler(mi1, mi2); + + Assert.assertTrue(mi.invoke(null, null, new FakeMessage())); + Assert.assertEquals(4, messageHandler.counter); + } + + @Test + public void testMessageHandlerCombinerDataShipping() { + MessageHandler mi = MessageHandlerFactory.concurrentHandler(); + FakeMessageDataHandler h = new FakeMessageDataHandler(); + mi = + MessageHandlerFactory.concurrentHandler( + mi, new TypedMessageHandlerWrapper(FakeMessageData.class, h)); + + Assert.assertTrue(mi.invoke(null, null, new FakeMessageData(101))); + Assert.assertEquals(101, h.data); + } + + @Test + public void testCombiningDefaultHandler() { + MessageHandler mi = + MessageHandlerFactory.concurrentHandler( + MessageHandlerFactory.defaultHandler(), + new TypedMessageHandlerWrapper(FakeMessage.class, new DummyMessageHandler())); + // UdpSharedGossipDataMessage with null gossipCore -> exception + boolean thrown = false; + try { + mi.invoke(null, null, new UdpSharedDataMessage()); + } catch (NullPointerException e) { + thrown = true; + } + Assert.assertTrue(thrown); + // skips FakeMessage and FakeHandler works ok + Assert.assertTrue(mi.invoke(null, null, new FakeMessage())); + } + + private static class FakeMessage extends Base { + public FakeMessage() {} + } + + private static class FakeMessageData extends Base { public int data; public FakeMessageData(int data) { @@ -39,7 +153,7 @@ public class MessageHandlerTest { } } - private class FakeMessageDataHandler implements MessageHandler { + private static class FakeMessageDataHandler implements MessageHandler { public int data; public FakeMessageDataHandler() { @@ -52,10 +166,10 @@ public class MessageHandlerTest { } } - private class FakeMessageHandler implements MessageHandler { + private static class DummyMessageHandler implements MessageHandler { public int counter; - public FakeMessageHandler() { + public DummyMessageHandler() { counter = 0; } @@ -64,119 +178,4 @@ public class MessageHandlerTest { return true; } } - - @Test - public void testSimpleHandler() { - MessageHandler mi = new TypedMessageHandler(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 testSimpleHandlerNullClassConstructor() { - new TypedMessageHandler(null, new FakeMessageHandler()); - } - - @Test(expected = NullPointerException.class) - public void testSimpleHandlerNullHandlerConstructor() { - new TypedMessageHandler(FakeMessage.class, null); - } - - @Test - public void testCallCountSimpleHandler() { - FakeMessageHandler h = new FakeMessageHandler(); - MessageHandler mi = new TypedMessageHandler(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) - @SuppressWarnings("all") - public void cantAddNullHandler() { - MessageHandler handler = MessageHandlerFactory.concurrentHandler(null); - } - - @Test(expected = NullPointerException.class) - public void cantAddNullHandler2() { - MessageHandlerFactory.concurrentHandler( - new TypedMessageHandler(FakeMessage.class, new FakeMessageHandler()), - null, - new TypedMessageHandler(FakeMessage.class, new FakeMessageHandler()) - ); - } - - @Test - public void testMessageHandlerCombiner() { - //Empty combiner - false result - MessageHandler mi = MessageHandlerFactory.concurrentHandler(); - Assert.assertFalse(mi.invoke(null, null, new Base())); - - FakeMessageHandler h = new FakeMessageHandler(); - mi = MessageHandlerFactory.concurrentHandler( - new TypedMessageHandler(FakeMessage.class, h), - new TypedMessageHandler(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 = MessageHandlerFactory.concurrentHandler(mi, new TypedMessageHandler(FakeMessage.class, h)); - Assert.assertTrue(mi.invoke(null, null, new FakeMessage())); - Assert.assertEquals(5, h.counter); - } - - @Test - public void testMessageHandlerCombiner2levels() { - FakeMessageHandler h = new FakeMessageHandler(); - - MessageHandler mi1 = MessageHandlerFactory.concurrentHandler( - new TypedMessageHandler(FakeMessage.class, h), - new TypedMessageHandler(FakeMessage.class, h) - ); - - MessageHandler mi2 = MessageHandlerFactory.concurrentHandler( - new TypedMessageHandler(FakeMessage.class, h), - new TypedMessageHandler(FakeMessage.class, h) - ); - - MessageHandler mi = MessageHandlerFactory.concurrentHandler(mi1, mi2); - - Assert.assertTrue(mi.invoke(null, null, new FakeMessage())); - Assert.assertEquals(4, h.counter); - } - - @Test - public void testMessageHandlerCombinerDataShipping() { - MessageHandler mi = MessageHandlerFactory.concurrentHandler(); - FakeMessageDataHandler h = new FakeMessageDataHandler(); - mi = MessageHandlerFactory.concurrentHandler(mi, new TypedMessageHandler(FakeMessageData.class, h)); - - Assert.assertTrue(mi.invoke(null, null, new FakeMessageData(101))); - Assert.assertEquals(101, h.data); - } - - @Test - public void testCombiningDefaultHandler() { - MessageHandler mi = MessageHandlerFactory.concurrentHandler( - MessageHandlerFactory.defaultHandler(), - new TypedMessageHandler(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); - //skips FakeMessage and FakeHandler works ok - Assert.assertTrue(mi.invoke(null, null, new FakeMessage())); - } - } diff --git a/gossip-base/src/test/java/org/apache/gossip/protocol/UnitTestProtocolManager.java b/gossip-base/src/test/java/org/apache/gossip/protocol/UnitTestProtocolManager.java index 3d52c4a..cb99e39 100644 --- a/gossip-base/src/test/java/org/apache/gossip/protocol/UnitTestProtocolManager.java +++ b/gossip-base/src/test/java/org/apache/gossip/protocol/UnitTestProtocolManager.java @@ -20,13 +20,12 @@ package org.apache.gossip.protocol; import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; -import org.apache.gossip.GossipSettings; -import org.apache.gossip.manager.PassiveGossipConstants; -import org.apache.gossip.model.Base; - import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.apache.gossip.GossipSettings; +import org.apache.gossip.manager.PassiveGossipConstants; +import org.apache.gossip.model.Base; // doesn't serialize anything besides longs. Uses a static lookup table to read and write objects. public class UnitTestProtocolManager implements ProtocolManager { diff --git a/gossip-base/src/test/java/org/apache/gossip/replication/DataReplicationTest.java b/gossip-base/src/test/java/org/apache/gossip/replication/DataReplicationTest.java index dd073a8..be00613 100644 --- a/gossip-base/src/test/java/org/apache/gossip/replication/DataReplicationTest.java +++ b/gossip-base/src/test/java/org/apache/gossip/replication/DataReplicationTest.java @@ -17,24 +17,42 @@ */ package org.apache.gossip.replication; -import org.apache.gossip.LocalMember; -import org.apache.gossip.manager.DatacenterRackAwareActiveGossiper; -import org.apache.gossip.model.SharedDataMessage; -import org.junit.Assert; -import org.junit.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; - import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.gossip.LocalMember; +import org.apache.gossip.manager.DatacenterRackAwareActiveGossiper; +import org.apache.gossip.model.SharedDataMessage; +import org.junit.Assert; +import org.junit.Test; -@RunWith(JUnitPlatform.class) public class DataReplicationTest { + private static SharedDataMessage getSharedNodeData(String key, String value, + Replicable replicable) { + SharedDataMessage g = new SharedDataMessage(); + g.setExpireAt(Long.MAX_VALUE); + g.setKey(key); + g.setPayload(value); + g.setTimestamp(System.currentTimeMillis()); + g.setReplicable(replicable); + return g; + } + + private static LocalMember getLocalMember(URI uri, String id){ + return new LocalMember("cluster1", uri, id, 0, null, 1, 0, ""); + } + + private static LocalMember getLocalMemberDc(URI uri, String id, String dataCenter, String rack){ + Map props = new HashMap<>(); + props.put(DatacenterRackAwareActiveGossiper.DATACENTER, dataCenter); + props.put(DatacenterRackAwareActiveGossiper.RACK, rack); + return new LocalMember("cluster1", uri, id, 0, props, 1, 0, ""); + } + @Test public void dataReplicateAllTest() throws URISyntaxException { SharedDataMessage message = getSharedNodeData("public","public", new AllReplicable<>()); @@ -65,7 +83,7 @@ public class DataReplicationTest { SharedDataMessage message = getSharedNodeData("whiteList", "Only allow some nodes", new WhiteListReplicable<>(whiteList)); LocalMember me = getLocalMember(new URI("udp://127.0.0.1:8004"),"4"); - + // data should replicate to node 1 and 2 but not 3 Assert.assertEquals(true, message.getReplicable().shouldReplicate(me, memberList.get(0), message)); @@ -102,7 +120,7 @@ public class DataReplicationTest { List blackList = new ArrayList<>(); blackList.add(memberList.get(0)); blackList.add(memberList.get(1)); - + SharedDataMessage message = getSharedNodeData("blackList", "Disallow some nodes", new BlackListReplicable<>(blackList)); LocalMember me = getLocalMember(new URI("udp://127.0.0.1:8004"),"4"); @@ -115,27 +133,27 @@ public class DataReplicationTest { Assert.assertEquals(true, message.getReplicable().shouldReplicate(me, memberList.get(2), message)); } - + @Test public void dataReplicateBlackListNullTest() throws URISyntaxException { - + List memberList = new ArrayList<>(); memberList.add(getLocalMember(new URI("udp://127.0.0.1:8001"),"1")); memberList.add(getLocalMember(new URI("udp://127.0.0.1:8002"),"2")); - + SharedDataMessage message = getSharedNodeData("blackList", "Disallow some nodes", new BlackListReplicable<>(null)); - + // data should replicate if no blacklist specified Assert.assertEquals(true, message.getReplicable().shouldReplicate(memberList.get(0), memberList.get(1), message)); Assert.assertEquals(true, message.getReplicable().shouldReplicate(memberList.get(1), memberList.get(0), message)); } - + @Test public void dataReplicateDataCenterTest() throws URISyntaxException { - + List memberListDc1 = new ArrayList<>(); List memberListDc2 = new ArrayList<>(); @@ -156,17 +174,17 @@ public class DataReplicationTest { .shouldReplicate(memberListDc1.get(0), memberListDc1.get(1), message)); Assert.assertEquals(true, message.getReplicable() .shouldReplicate(memberListDc2.get(0), memberListDc2.get(1), message)); - + // data should not replicate to data center 2 Assert.assertEquals(false, message.getReplicable() .shouldReplicate(memberListDc1.get(0), memberListDc2.get(0), message)); Assert.assertEquals(false, message.getReplicable() .shouldReplicate(memberListDc1.get(1), memberListDc2.get(1), message)); } - + @Test public void dataReplicateDataCenterUnknownDataCenterTest() throws URISyntaxException { - + List memberListDc1 = new ArrayList<>(); memberListDc1 .add(getLocalMemberDc(new URI("udp://10.0.0.1:8000"), "1", "DataCenter1", "Rack1")); @@ -174,7 +192,7 @@ public class DataReplicationTest { Map properties = new HashMap<>(); LocalMember unknownDc = new LocalMember("cluster1", new URI("udp://10.0.1.2:8000"), "12", 0, properties, 1, 0, ""); - + SharedDataMessage message = getSharedNodeData("datacenter1","I am in data center 1 rack 1", new DataCenterReplicable<>()); // data should not replicate from dc1 to unknown node @@ -185,26 +203,4 @@ public class DataReplicationTest { .shouldReplicate(unknownDc, memberListDc1.get(0), message)); } - - private static SharedDataMessage getSharedNodeData(String key, String value, - Replicable replicable) { - SharedDataMessage g = new SharedDataMessage(); - g.setExpireAt(Long.MAX_VALUE); - g.setKey(key); - g.setPayload(value); - g.setTimestamp(System.currentTimeMillis()); - g.setReplicable(replicable); - return g; - } - - private static LocalMember getLocalMember(URI uri, String id){ - return new LocalMember("cluster1", uri, id, 0, null, 1, 0, ""); - } - - private static LocalMember getLocalMemberDc(URI uri, String id, String dataCenter, String rack){ - Map props = new HashMap<>(); - props.put(DatacenterRackAwareActiveGossiper.DATACENTER, dataCenter); - props.put(DatacenterRackAwareActiveGossiper.RACK, rack); - return new LocalMember("cluster1", uri, id, 0, props, 1, 0, ""); - } } diff --git a/gossip-base/src/test/java/org/apache/gossip/transport/UnitTestTransportManager.java b/gossip-base/src/test/java/org/apache/gossip/transport/UnitTestTransportManager.java index 206bc62..85e2bc3 100644 --- a/gossip-base/src/test/java/org/apache/gossip/transport/UnitTestTransportManager.java +++ b/gossip-base/src/test/java/org/apache/gossip/transport/UnitTestTransportManager.java @@ -29,13 +29,13 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; /** Only use in unit tests! */ -public class UnitTestTransportManager extends AbstractTransportManager { - +public class UnitTestTransportManager extends AbstractTransportManager { + private static final Map allManagers = new ConcurrentHashMap<>(); - + private final URI localEndpoint; private BlockingQueue buffers = new ArrayBlockingQueue(1000); - + public UnitTestTransportManager(GossipManager gossipManager, GossipCore gossipCore) { super(gossipManager, gossipCore); localEndpoint = gossipManager.getMyself().getUri(); diff --git a/gossip-base/src/test/resources/log4j.properties b/gossip-base/src/test/resources/log4j.properties index e2a60e1..e3bcd5d 100644 --- a/gossip-base/src/test/resources/log4j.properties +++ b/gossip-base/src/test/resources/log4j.properties @@ -9,12 +9,9 @@ # 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 diff --git a/gossip-examples/README.md b/gossip-examples/README.md index aae7b88..4151849 100644 --- a/gossip-examples/README.md +++ b/gossip-examples/README.md @@ -1,13 +1,17 @@ Running the Examples =================================================== -Apache Gossip is designed to run as library used by others. That is, it in intended as a feature to be embedded in other code. +Apache Gossip is designed to run as library used by others. That is, it in intended as a feature to be embedded in other +code. -These examples illustrate some simple cases of the invocation of Gossip from an "thin" application layer, to illustrate various -features of the library. +These examples illustrate some simple cases of the invocation of Gossip from an "thin" application layer, to illustrate +various +features of the library. For additional information see: -* This [YouTube video](https://www.youtube.com/watch?v=bZXZrp7yBkw&t=39s) illustrating and illuminating the first example. + +* This [YouTube video](https://www.youtube.com/watch?v=bZXZrp7yBkw&t=39s) illustrating and illuminating the first + example. * This [YouTube video](https://www.youtube.com/watch?v=SqkJs0QDRdk) illustrating and illuminating the second example. * A [general description of the Gossip Protocol](https://en.wikipedia.org/wiki/Gossip_protocol) @@ -16,21 +20,24 @@ Initial setup - Preconditions These instructions assume that you are using a Unix-like command line interface; translate as necessary. Prior to running these examples you will need to have your environment set up to run java and Maven -commands: +commands: + * install java 8 - [https://java.com/](https://java.com/), and * install Maven - [https://maven.apache.org/install.html](https://maven.apache.org/install.html) Then, you will need a local copy of the code. The simplest is to download the project to a local folder: + * browse to [https://github.com/apache/incubator-gossip](https://github.com/apache/incubator-gossip) * click on the "Clone of Download" button * click on the "Download ZIP" option * unzip the file to in a convenient location -In what follows, we will call the resulting project folder **incubator-gossip**. + In what follows, we will call the resulting project folder **incubator-gossip**. As an alternative, you can also [clone](https://help.github.com/articles/cloning-a-repository/) the GitHub repository. Lastly, you will need to use Maven to build and install the necessary dependencies: + ``` cd incubator-gossip mvn install -DskipTests @@ -41,22 +48,26 @@ When all that is finished are you ready to start running the first example... Running org.apache.gossip.examples.StandAloneNode ------------------------------------------------- -This first example illustrates the basic, underlying, communication layer the sets up and maintains a gossip network cluster. +This first example illustrates the basic, underlying, communication layer the sets up and maintains a gossip network +cluster. In the [YouTube video](https://www.youtube.com/watch?v=bZXZrp7yBkw&t=39s) there is a description of -the architecture and a demonstration of running of this example. While the video was created with an earlier version of the system, +the architecture and a demonstration of running of this example. While the video was created with an earlier version of +the system, these instructions will get you going on that example. To run this example from the code (in a clone or download of the archive) simply change your working directory to the gossip-examples module and run the application in maven. Specifically, after cloning or downloading the repository: + ``` cd incubator-gossip/gossip-examples mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneNode -Dexec.args="udp://localhost:10000 0 udp://localhost:10000 0" ``` This sets up a single StandAloneNode that starts out listening to itself. The arguments are: + 1. The URI (host and port) for the node - **udp://localhost:10000** 2. The id for the node - **0** 3. The URI for a "seed" node - **udp://localhost:10000** @@ -64,40 +75,52 @@ This sets up a single StandAloneNode that starts out listening to itself. The ar Note. To stop the the example, simply kill the process (control-C, for example). -In this application, the output uses a "terminal escape sequence" that clears the +In this application, the output uses a "terminal escape sequence" that clears the terminal display and resets the cursor to the upper left corner. -if, for some reason, this is not working in your case, you can add the (optional) flag '-s' to the args in the +if, for some reason, this is not working in your case, you can add the (optional) flag '-s' to the args in the command line, to suppress this "clear screen" behavior. That is: + ``` cd incubator-gossip/gossip-examples mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneNode -Dexec.args="-s udp://localhost:10000 0 udp://localhost:10000 0" ``` -Normally, you would set up nodes in a network on separate hosts, but in this case, illustrating the basic communications in gossip, -we are just running all the nodes on the same host, localhost. The seed node will generally be one of the other nodes in the +Normally, you would set up nodes in a network on separate hosts, but in this case, illustrating the basic communications +in gossip, +we are just running all the nodes on the same host, localhost. The seed node will generally be one of the other nodes in +the network: enough information for this node to (eventually) acquire the list of all nodes in its cluster. -You will see that this gossip node prints out two list of know other nodes, live and dead. The live nodes are nodes assumed to be active and -connected, the dead nodes are nodes that have "gone missing" long enough to be assumed dormant or disconnected. See details in the video. +You will see that this gossip node prints out two list of know other nodes, live and dead. The live nodes are nodes +assumed to be active and +connected, the dead nodes are nodes that have "gone missing" long enough to be assumed dormant or disconnected. See +details in the video. -With only a single node running in this cluster, there are no other nodes detected, so both the live and dead lists are empty. +With only a single node running in this cluster, there are no other nodes detected, so both the live and dead lists are +empty. -Then, in a separate terminal window, cd to the same folder and enter the the same run command with the first two arguments +Then, in a separate terminal window, cd to the same folder and enter the the same run command with the first two +arguments changed to reflect the fact that this is a different node + 1. host/port for the node - **udp://localhost:10001** 2. id for the node - **1** That is: + ``` cd incubator-gossip/gossip-examples mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneNode -Dexec.args="udp://localhost:10001 1 udp://localhost:10000 0" ``` -Now, because the "seed node" is the first node that we started, this second node is listening to the first node, -and they exchange list of known nodes. And start listening to each other, so that in short order they both have a list of live notes +Now, because the "seed node" is the first node that we started, this second node is listening to the first node, +and they exchange list of known nodes. And start listening to each other, so that in short order they both have a list +of live notes with one member, the other live node in the cluster. -Finally, in yet another terminal window, cd to the same folder and enter the the same run command with the first two arguments changed to +Finally, in yet another terminal window, cd to the same folder and enter the the same run command with the first two +arguments changed to + 1. host/port for the node - **udp://localhost:10002** 2. id for the node - **2** @@ -108,97 +131,127 @@ mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneNode -Dexec. Now the lists of live nodes for the cluster converge to reflect each node's connections to the other two nodes. -To see a node moved to the dead list. Kill the process in one of the running terminals: enter control-c in the terminal window. -Then the live-dead list of the two remaining nodes will converge to show one node live and one node dead. -Start the missing node again, and it will again appear in the live list. -Note, that it does not matter which node goes dormant, every live node (eventually) communicates with some other +To see a node moved to the dead list. Kill the process in one of the running terminals: enter control-c in the terminal +window. +Then the live-dead list of the two remaining nodes will converge to show one node live and one node dead. +Start the missing node again, and it will again appear in the live list. +Note, that it does not matter which node goes dormant, every live node (eventually) communicates with some other live node in the cluster and gets the necessary updated status information. -If you read the code, you will see that it defines a cluster (name = 'mycluster') and a number of other setup details. See the video for +If you read the code, you will see that it defines a cluster (name = 'mycluster') and a number of other setup details. +See the video for a more complete description of the setup and for a more details description of the interactions among the nodes. -Also note, that the process of running these nodes produces a set of JSON files recording node state (in the 'base' directory from where the node -running). This enables a quicker startup as failed nodes recover. In this example, to recover a node that you have killed, +Also note, that the process of running these nodes produces a set of JSON files recording node state (in the 'base' +directory from where the node +running). This enables a quicker startup as failed nodes recover. In this example, to recover a node that you have +killed, using control-c, simply re-issue the command to run the node. Running org.apache.gossip.examples.StandAloneNodeCrdtOrSet ---------------------------------------------------------- -This second example illustrates the using the data layer to share structured information: a shared representation of a set -of strings, and a shared counter. The objects representing those shared values are special cases of a Conflict-free Replicated -Data Type (hence, CRDT). +This second example illustrates the using the data layer to share structured information: a shared representation of a +set +of strings, and a shared counter. The objects representing those shared values are special cases of a Conflict-free +Replicated +Data Type (hence, CRDT). -Here is the problem that is solved by these CRDT objects: since each node in a cluster can message any other node in the cluster -in any order, the messages that reflect the content of data structure can arrive in any order. For example, one node may add an object -to the set and send that modified set to another node that removes that object and sends that message to a third node. If the first node -also sends a message to the third node (with the object in the set), the third node could receive conflicting information. But the CRDT +Here is the problem that is solved by these CRDT objects: since each node in a cluster can message any other node in the +cluster +in any order, the messages that reflect the content of data structure can arrive in any order. For example, one node may +add an object +to the set and send that modified set to another node that removes that object and sends that message to a third node. +If the first node +also sends a message to the third node (with the object in the set), the third node could receive conflicting +information. But the CRDT data structures always contain enough information to resolve the conflict. -As with the first demo there is a You Tube video that illustrates the problem and shows how it is resolved and illustrates the running +As with the first demo there is a You Tube video that illustrates the problem and shows how it is resolved and +illustrates the running example: [https://www.youtube.com/watch?v=SqkJs0QDRdk](https://www.youtube.com/watch?v=SqkJs0QDRdk) . -Again, we will run three instances of the example, to illustrate the actions of the nodes in the cluster. +Again, we will run three instances of the example, to illustrate the actions of the nodes in the cluster. The arguments to the application are identical to those in the -first example. The difference in this example is that each node will read "commands" the change the local state of its information. Which we +first example. The difference in this example is that each node will read "commands" the change the local state of its +information. Which we will illustrate shortly. But first, lets get the three nodes running: In the first terminal window: + ``` cd incubator-gossip/gossip-examples mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneNodeCrdtOrSet -Dexec.args="udp://localhost:10000 0 udp://localhost:10000 0" ``` In the second terminal window: + ``` cd incubator-gossip/gossip-examples mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneNodeCrdtOrSet -Dexec.args="udp://localhost:10001 1 udp://localhost:10000 0" ``` In the third terminal window: + ``` cd incubator-gossip/gossip-examples mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneNodeCrdtOrSet -Dexec.args="udp://localhost:10002 2 udp://localhost:10000 0" ``` -Now, at any of the terminal windows, you can type a command from the following set of commands to change the data that is stored locally. -Note, while you are typing, the terminal output continues, forcing you to type blind, but when you hit the return, to end +Now, at any of the terminal windows, you can type a command from the following set of commands to change the data that +is stored locally. +Note, while you are typing, the terminal output continues, forcing you to type blind, but when you hit the return, to +end the input line, the input will be briefly displayed before scrolling off the screen. -When you type one of these commands, you can then watch the propagation of that data through the cluster. The commands are: +When you type one of these commands, you can then watch the propagation of that data through the cluster. The commands +are: + ``` a string r string g number ``` -* **a** is the 'add' command; it adds the string to the shared set - you should see the set displayed with the new value, - eventually, at all nodes. -* **r** is the 'remove' command; it removes the string from the set (if it exists in the set) - you should see the - value eventually leave the set at all nodes -* **g** is the "global increment" command; it assume that it's argument is a number and adds that number to an accumulator. - Eventually, the accumulator at all nodes will settle to the same value. -The CRDT representations of these values assure that all nodes will reach the same end state for the resulting value regardless of the order +* **a** is the 'add' command; it adds the string to the shared set - you should see the set displayed with the new + value, + eventually, at all nodes. +* **r** is the 'remove' command; it removes the string from the set (if it exists in the set) - you should see the + value eventually leave the set at all nodes +* **g** is the "global increment" command; it assume that it's argument is a number and adds that number to an + accumulator. + Eventually, the accumulator at all nodes will settle to the same value. + +The CRDT representations of these values assure that all nodes will reach the same end state for the resulting value +regardless of the order of arrival of information from other nodes in the cluster. -As an augmentation to the video, this [wikipedia article](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type), -describing various CRDT representations and their usefulness, as well as some information about interesting applications. +As an augmentation to the video, +this [wikipedia article](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type), +describing various CRDT representations and their usefulness, as well as some information about interesting +applications. Running org.apache.gossip.examples.StandAloneDatacenterAndRack -------------------------------------------------------------- -This final example illustrates more fine grained control over the expected "responsiveness" of nodes in the cluster. +This final example illustrates more fine grained control over the expected "responsiveness" of nodes in the cluster. -Apache gossip is designed as a library intended to be embedded in applications which to take advantage of the gossip-protocol +Apache gossip is designed as a library intended to be embedded in applications which to take advantage of the +gossip-protocol for peer-to-peer communications. The effectiveness of communications among nodes in a gossip cluster can be tuned -to the expected latency of message transmission and expected responsiveness of other nodes in the network. This example illustrates -one model of this type of control: a "data center and rack" model of node distribution. In this model, nodes that are in the same -'data center' (perhaps on a different 'rack') are assumed to have very lower latency and high fidelity of communications. +to the expected latency of message transmission and expected responsiveness of other nodes in the network. This example +illustrates +one model of this type of control: a "data center and rack" model of node distribution. In this model, nodes that are in +the same +'data center' (perhaps on a different 'rack') are assumed to have very lower latency and high fidelity of +communications. While, nodes in different data centers are assumed to require more time to communicate, and be subject to -a higher rate of communication failure, so communications can be tuned to tolerate more variation in latency and success of +a higher rate of communication failure, so communications can be tuned to tolerate more variation in latency and success +of transmission, but this result in a longer "settle" time. -Accordingly, the application in this example has a couple of extra arguments, a data center id, and a rack id. +Accordingly, the application in this example has a couple of extra arguments, a data center id, and a rack id. To start the first node (in the first terminal window), type the following: @@ -206,7 +259,9 @@ To start the first node (in the first terminal window), type the following: cd incubator-gossip/gossip-examples mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneDatacenterAndRack -Dexec.args="udp://localhost:10000 0 udp://localhost:10000 0 1 2" ``` + The first four arguments are the same as in the other two examples, and the last two arguments are the new arguments: + 1. The URI (host and port) for the node - **udp://localhost:10000** 2. The id for the node - **0** 3. The URI for a "seed" node - **udp://localhost:10000** @@ -214,8 +269,10 @@ The first four arguments are the same as in the other two examples, and the last 5. The data center id - **1** 6. The rack id - **2** -Lets then, set up two additional nodes (each in a separate terminal window), one in the same data center on a different rack, -and the other in a different data center. +Lets then, set up two additional nodes (each in a separate terminal window), one in the same data center on a different +rack, +and the other in a different data center. + ``` cd incubator-gossip/gossip-examples mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneDatacenterAndRack -Dexec.args="udp://localhost:10001 1 udp://localhost:10000 0 1 3" @@ -227,10 +284,12 @@ mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.StandAloneDatacenterAn ``` Now, the application running in the first terminal window, is identified as running in data center 1 and on rack 2; -the application in the second terminal window is running in the same data center in a different rack (data center 1, rack 3). -While, the application in the third terminal is running in a different data center (data center 2). +the application in the second terminal window is running in the same data center in a different rack (data center 1, +rack 3). +While, the application in the third terminal is running in a different data center (data center 2). -If you stop the node in the first terminal window (control-c) you will observe that the process in the third terminal window +If you stop the node in the first terminal window (control-c) you will observe that the process in the third terminal +window takes longer to settle to the correct state then the process in the second terminal window, because it is expecting a greater latency in message transmission and is (therefore) more tolerant to delays (and drops) in messaging, taking it longer to detect that the killed process is "off line". @@ -240,7 +299,8 @@ Final Notes That concludes the description of running the examples. -This project is an Apache [incubator project](http://incubator.apache.org/projects/gossip.html). -The [official web site](http://gossip.incubator.apache.org/community/) has much additional information: -see especially 'get involved' under 'community'. Enjoy, and please let us know if you are finding this library helpful in any way. +This project is an Apache [incubator project](http://incubator.apache.org/projects/gossip.html). +The [official web site](http://gossip.incubator.apache.org/community/) has much additional information: +see especially 'get involved' under 'community'. Enjoy, and please let us know if you are finding this library helpful +in any way. diff --git a/gossip-examples/pom.xml b/gossip-examples/pom.xml index 2246eba..0e584a6 100644 --- a/gossip-examples/pom.xml +++ b/gossip-examples/pom.xml @@ -9,37 +9,37 @@ 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. --> - - 4.0.0 + + 4.0.0 - - org.apache.gossip - gossip-parent - 0.1.3-incubating-SNAPSHOT - + + org.apache.gossip + gossip-parent + 0.1.3-incubating-SNAPSHOT + - Gossip Examples - gossip-examples + Gossip Examples + gossip-examples - 0.1.3-incubating-SNAPSHOT + 0.1.3-incubating-SNAPSHOT - - - org.apache.gossip - gossip-base - ${project.version} - - - org.apache.gossip - gossip-protocol-jackson - ${project.version} - - - org.apache.gossip - gossip-transport-udp - ${project.version} - - + + + org.apache.gossip + gossip-base + ${project.version} + + + org.apache.gossip + gossip-protocol-jackson + ${project.version} + + + org.apache.gossip + gossip-transport-udp + ${project.version} + + \ No newline at end of file diff --git a/gossip-examples/src/main/java/org/apache/gossip/examples/RunStandardExamples.java b/gossip-examples/src/main/java/org/apache/gossip/examples/RunStandardExamples.java index 21861bb..cb4fe5d 100644 --- a/gossip-examples/src/main/java/org/apache/gossip/examples/RunStandardExamples.java +++ b/gossip-examples/src/main/java/org/apache/gossip/examples/RunStandardExamples.java @@ -94,12 +94,16 @@ public class RunStandardExamples { private static String usage() { return "Select and run (usually in a seperate terminal window) \n" - + "one of the the standard Examples,\n" + " 1. StandAloneNode\n" - + " 2. StandAloneNodeCrdtOrSet\n" + " 3. StandAlonePNCounter\n" - + " 4. StandAloneDatacenterAndRack\n" + "(See README.md in this modules)\n" + "\n" - + "Usage: mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.RunStandardExamples -Dexec.args=\"s c\"\n" - + "where...\n" + " s - int - the example number from above\n" - + " c - int - the channel number: 0, 1, or 2\n"; + + "one of the the standard Examples,\n" + + " 1. StandAloneNode\n" + + " 2. StandAloneNodeCrdtOrSet\n" + + " 3. StandAlonePNCounter\n" + + " 4. StandAloneDatacenterAndRack\n" + + "(See README.md in this modules)\n" + + "\n" + + "Usage: mvn exec:java -Dexec.mainClass=org.apache.gossip.examples.RunStandardExamples -Dexec.args=\"s c\"\n" + + "where...\n" + + " s - int - the example number from above\n" + + " c - int - the channel number: 0, 1, or 2\n"; } - } diff --git a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneDatacenterAndRack.java b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneDatacenterAndRack.java index 2336e87..5c2b6a7 100644 --- a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneDatacenterAndRack.java +++ b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneDatacenterAndRack.java @@ -32,17 +32,17 @@ import org.apache.gossip.manager.GossipManagerBuilder; public class StandAloneDatacenterAndRack extends StandAloneExampleBase { + StandAloneDatacenterAndRack(String[] args) { + args = super.checkArgsForClearFlag(args); + initGossipManager(args); + } + public static void main(String[] args) throws InterruptedException, IOException { StandAloneDatacenterAndRack example = new StandAloneDatacenterAndRack(args); boolean willRead = true; example.exec(willRead); } - StandAloneDatacenterAndRack(String[] args) { - args = super.checkArgsForClearFlag(args); - initGossipManager(args); - } - void initGossipManager(String[] args) { GossipSettings s = new GossipSettings(); s.setWindowSize(1000); @@ -55,11 +55,16 @@ public class StandAloneDatacenterAndRack extends StandAloneExampleBase { Map props = new HashMap<>(); props.put(DatacenterRackAwareActiveGossiper.DATACENTER, args[4]); props.put(DatacenterRackAwareActiveGossiper.RACK, args[5]); - GossipManager manager = GossipManagerBuilder.newBuilder().cluster("mycluster") - .uri(URI.create(args[0])).id(args[1]).gossipSettings(s) + GossipManager manager = + GossipManagerBuilder.newBuilder() + .cluster("mycluster") + .uri(URI.create(args[0])) + .id(args[1]) + .gossipSettings(s) .gossipMembers( - Arrays.asList(new RemoteMember("mycluster", URI.create(args[2]), args[3]))) - .properties(props).build(); + Arrays.asList(new RemoteMember("mycluster", URI.create(args[2]), args[3]))) + .properties(props) + .build(); manager.init(); setGossipService(manager); } @@ -68,5 +73,4 @@ public class StandAloneDatacenterAndRack extends StandAloneExampleBase { void printValues(GossipManager gossipService) { return; } - } diff --git a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneExampleBase.java b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneExampleBase.java index 02c2ee7..1fe2b19 100644 --- a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneExampleBase.java +++ b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneExampleBase.java @@ -90,18 +90,20 @@ abstract class StandAloneExampleBase { } private void startMonitorLoop(GossipManager gossipService) { - new Thread(() -> { - while (true) { - optionallyClearTerminal(); - printLiveMembers(gossipService); - printDeadMambers(gossipService); - printValues(gossipService); - try { - Thread.sleep(2000); - } catch (Exception ignore) { - } - } - }).start(); + new Thread( + () -> { + while (true) { + optionallyClearTerminal(); + printLiveMembers(gossipService); + printDeadMambers(gossipService); + printValues(gossipService); + try { + Thread.sleep(2000); + } catch (Exception ignore) { + } + } + }) + .start(); } private void printLiveMembers(GossipManager gossipService) { @@ -143,11 +145,16 @@ abstract class StandAloneExampleBase { GossipSettings s = new GossipSettings(); s.setWindowSize(1000); s.setGossipInterval(100); - GossipManager gossipService = GossipManagerBuilder.newBuilder().cluster("mycluster") - .uri(URI.create(args[0])).id(args[1]) - .gossipMembers(Collections - .singletonList(new RemoteMember("mycluster", URI.create(args[2]), args[3]))) - .gossipSettings(s).build(); + GossipManager gossipService = + GossipManagerBuilder.newBuilder() + .cluster("mycluster") + .uri(URI.create(args[0])) + .id(args[1]) + .gossipMembers( + Collections.singletonList( + new RemoteMember("mycluster", URI.create(args[2]), args[3]))) + .gossipSettings(s) + .build(); setGossipService(gossipService); } @@ -158,5 +165,4 @@ abstract class StandAloneExampleBase { GossipManager getGossipManager() { return this.gossipService; } - } diff --git a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneNode.java b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneNode.java index 953e784..35b1946 100644 --- a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneNode.java +++ b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneNode.java @@ -18,23 +18,22 @@ package org.apache.gossip.examples; import java.io.IOException; - import org.apache.gossip.manager.GossipManager; public class StandAloneNode extends StandAloneExampleBase { private static boolean WILL_READ = false; - public static void main(String[] args) throws InterruptedException, IOException { - StandAloneNode example = new StandAloneNode(args); - example.exec(WILL_READ); - } - StandAloneNode(String[] args) { args = super.checkArgsForClearFlag(args); super.initGossipManager(args); } + public static void main(String[] args) throws InterruptedException, IOException { + StandAloneNode example = new StandAloneNode(args); + example.exec(WILL_READ); + } + @Override void printValues(GossipManager gossipService) { } diff --git a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneNodeCrdtOrSet.java b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneNodeCrdtOrSet.java index a184bc4..8d7c06b 100644 --- a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneNodeCrdtOrSet.java +++ b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAloneNodeCrdtOrSet.java @@ -30,25 +30,76 @@ public class StandAloneNodeCrdtOrSet extends StandAloneExampleBase { private static final String INDEX_KEY_FOR_COUNTER = "def"; + StandAloneNodeCrdtOrSet(String[] args) { + args = super.checkArgsForClearFlag(args); + super.initGossipManager(args); + } + public static void main(String[] args) throws InterruptedException, IOException { StandAloneNodeCrdtOrSet example = new StandAloneNodeCrdtOrSet(args); boolean willRead = true; example.exec(willRead); } - StandAloneNodeCrdtOrSet(String[] args) { - args = super.checkArgsForClearFlag(args); - super.initGossipManager(args); + private static void listen(String val, GossipManager gossipManager) { + gossipManager.registerSharedDataSubscriber( + (key, oldValue, newValue) -> { + if (key.equals(val)) { + System.out.println( + "Event Handler fired for key = '" + key + "'! " + oldValue + " " + newValue); + } + }); + } + + private static void gcount(String val, GossipManager gossipManager) { + GrowOnlyCounter c = (GrowOnlyCounter) gossipManager.findCrdt(INDEX_KEY_FOR_COUNTER); + Long l = Long.valueOf(val); + if (c == null) { + c = new GrowOnlyCounter(new GrowOnlyCounter.Builder(gossipManager).increment((l))); + } else { + c = new GrowOnlyCounter(c, new GrowOnlyCounter.Builder(gossipManager).increment((l))); + } + SharedDataMessage m = new SharedDataMessage(); + m.setExpireAt(Long.MAX_VALUE); + m.setKey(INDEX_KEY_FOR_COUNTER); + m.setPayload(c); + m.setTimestamp(System.currentTimeMillis()); + gossipManager.merge(m); + } + + private static void removeData(String val, GossipManager gossipService) { + @SuppressWarnings("unchecked") + OrSet s = (OrSet) gossipService.findCrdt(INDEX_KEY_FOR_SET); + SharedDataMessage m = new SharedDataMessage(); + m.setExpireAt(Long.MAX_VALUE); + m.setKey(INDEX_KEY_FOR_SET); + m.setPayload(new OrSet(s, new OrSet.Builder().remove(val))); + m.setTimestamp(System.currentTimeMillis()); + gossipService.merge(m); + } + + private static void addData(String val, GossipManager gossipService) { + SharedDataMessage m = new SharedDataMessage(); + m.setExpireAt(Long.MAX_VALUE); + m.setKey(INDEX_KEY_FOR_SET); + m.setPayload(new OrSet(val)); + m.setTimestamp(System.currentTimeMillis()); + gossipService.merge(m); } void printValues(GossipManager gossipService) { System.out.println("Last Input: " + getLastInput()); - System.out.println("---------- Or Set " + (gossipService.findCrdt(INDEX_KEY_FOR_SET) == null - ? "" : gossipService.findCrdt(INDEX_KEY_FOR_SET).value())); + System.out.println( + "---------- Or Set " + + (gossipService.findCrdt(INDEX_KEY_FOR_SET) == null + ? "" + : gossipService.findCrdt(INDEX_KEY_FOR_SET).value())); System.out.println("********** " + gossipService.findCrdt(INDEX_KEY_FOR_SET)); System.out.println( - "^^^^^^^^^^ Grow Only Counter" + (gossipService.findCrdt(INDEX_KEY_FOR_COUNTER) == null - ? "" : gossipService.findCrdt(INDEX_KEY_FOR_COUNTER).value())); + "^^^^^^^^^^ Grow Only Counter" + + (gossipService.findCrdt(INDEX_KEY_FOR_COUNTER) == null + ? "" + : gossipService.findCrdt(INDEX_KEY_FOR_COUNTER).value())); System.out.println("$$$$$$$$$$ " + gossipService.findCrdt(INDEX_KEY_FOR_COUNTER)); } @@ -88,50 +139,4 @@ public class StandAloneNodeCrdtOrSet extends StandAloneExampleBase { } return (l >= 0); } - - private static void listen(String val, GossipManager gossipManager) { - gossipManager.registerSharedDataSubscriber((key, oldValue, newValue) -> { - if (key.equals(val)) { - System.out.println( - "Event Handler fired for key = '" + key + "'! " + oldValue + " " + newValue); - } - }); - } - - private static void gcount(String val, GossipManager gossipManager) { - GrowOnlyCounter c = (GrowOnlyCounter) gossipManager.findCrdt(INDEX_KEY_FOR_COUNTER); - Long l = Long.valueOf(val); - if (c == null) { - c = new GrowOnlyCounter(new GrowOnlyCounter.Builder(gossipManager).increment((l))); - } else { - c = new GrowOnlyCounter(c, new GrowOnlyCounter.Builder(gossipManager).increment((l))); - } - SharedDataMessage m = new SharedDataMessage(); - m.setExpireAt(Long.MAX_VALUE); - m.setKey(INDEX_KEY_FOR_COUNTER); - m.setPayload(c); - m.setTimestamp(System.currentTimeMillis()); - gossipManager.merge(m); - } - - private static void removeData(String val, GossipManager gossipService) { - @SuppressWarnings("unchecked") - OrSet s = (OrSet) gossipService.findCrdt(INDEX_KEY_FOR_SET); - SharedDataMessage m = new SharedDataMessage(); - m.setExpireAt(Long.MAX_VALUE); - m.setKey(INDEX_KEY_FOR_SET); - m.setPayload(new OrSet(s, new OrSet.Builder().remove(val))); - m.setTimestamp(System.currentTimeMillis()); - gossipService.merge(m); - } - - private static void addData(String val, GossipManager gossipService) { - SharedDataMessage m = new SharedDataMessage(); - m.setExpireAt(Long.MAX_VALUE); - m.setKey(INDEX_KEY_FOR_SET); - m.setPayload(new OrSet(val)); - m.setTimestamp(System.currentTimeMillis()); - gossipService.merge(m); - } - } diff --git a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAlonePNCounter.java b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAlonePNCounter.java index 23e949b..444a9a5 100644 --- a/gossip-examples/src/main/java/org/apache/gossip/examples/StandAlonePNCounter.java +++ b/gossip-examples/src/main/java/org/apache/gossip/examples/StandAlonePNCounter.java @@ -25,21 +25,24 @@ import org.apache.gossip.model.SharedDataMessage; public class StandAlonePNCounter extends StandAloneExampleBase { + StandAlonePNCounter(String[] args) { + args = super.checkArgsForClearFlag(args); + super.initGossipManager(args); + } + public static void main(String[] args) throws InterruptedException, IOException { StandAlonePNCounter example = new StandAlonePNCounter(args); boolean willRead = true; example.exec(willRead); } - StandAlonePNCounter(String[] args) { - args = super.checkArgsForClearFlag(args); - super.initGossipManager(args); - } - void printValues(GossipManager gossipService) { System.out.println("Last Input: " + getLastInput()); - System.out.println("---------- " + (gossipService.findCrdt("myPNCounter") == null ? "" - : gossipService.findCrdt("myPNCounter").value())); + System.out.println( + "---------- " + + (gossipService.findCrdt("myPNCounter") == null + ? "" + : gossipService.findCrdt("myPNCounter").value())); System.out.println("********** " + gossipService.findCrdt("myPNCounter")); } @@ -94,5 +97,4 @@ public class StandAlonePNCounter extends StandAloneExampleBase { m.setTimestamp(System.currentTimeMillis()); gossipManager.merge(m); } - -} \ No newline at end of file +} diff --git a/gossip-itest/pom.xml b/gossip-itest/pom.xml index 6067732..92a007b 100644 --- a/gossip-itest/pom.xml +++ b/gossip-itest/pom.xml @@ -16,73 +16,44 @@ See the License for the specific language governing permissions and limitations under the License. --> - - 4.0.0 + 4.0.0 - - org.apache.gossip - gossip-parent + + org.apache.gossip + gossip-parent + 0.1.3-incubating-SNAPSHOT + ../pom.xml + + + Gossip Itest + gossip-itest 0.1.3-incubating-SNAPSHOT - ../pom.xml - - - Gossip itest - gossip-itest - 0.1.3-incubating-SNAPSHOT - - - - org.apache.gossip - gossip-base - ${project.version} - - - org.apache.gossip - gossip-base - ${project.version} - test-jar - test - - - org.apache.gossip - gossip-protocol-jackson - ${project.version} - - - org.apache.gossip - gossip-transport-udp - ${project.version} - - - - - - maven-compiler-plugin - 3.1 - - ${java.version} - ${java.version} - - - - maven-surefire-plugin - 2.19.1 - - - ${project.build.directory} - - - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - - - - - + + + org.apache.gossip + gossip-base + ${project.version} + + + org.apache.gossip + gossip-base + ${project.version} + test-jar + test + + + org.apache.gossip + gossip-protocol-jackson + ${project.version} + + + org.apache.gossip + gossip-transport-udp + ${project.version} + + diff --git a/gossip-itest/src/test/java/org/apache/gossip/DataTest.java b/gossip-itest/src/test/java/org/apache/gossip/DataTest.java index c16174f..3a12390 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/DataTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/DataTest.java @@ -18,6 +18,18 @@ 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.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.function.Function; import org.apache.gossip.crdt.CrdtAddRemoveSet; import org.apache.gossip.crdt.GrowOnlyCounter; import org.apache.gossip.crdt.GrowOnlySet; @@ -34,25 +46,11 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import java.util.function.Function; - public class DataTest { + private static final List clients = new ArrayList<>(); private final String gCounterKey = "crdtgc"; private final String pnCounterKey = "crdtpn"; - private static final List clients = new ArrayList<>(); - @BeforeClass public static void initializeMembers() throws InterruptedException, UnknownHostException, URISyntaxException{ final int clusterMembers = 2; diff --git a/gossip-itest/src/test/java/org/apache/gossip/IdAndPropertyTest.java b/gossip-itest/src/test/java/org/apache/gossip/IdAndPropertyTest.java index 7f550de..e2455d1 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/IdAndPropertyTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/IdAndPropertyTest.java @@ -25,22 +25,20 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeUnit; import org.apache.gossip.manager.DatacenterRackAwareActiveGossiper; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManagerBuilder; import org.junit.jupiter.api.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import io.teknek.tunit.TUnit; -@RunWith(JUnitPlatform.class) public class IdAndPropertyTest extends AbstractIntegrationBase { @Test - public void testDatacenterRackGossiper() throws URISyntaxException, UnknownHostException, InterruptedException { + public void testDatacenterRackGossiper() + throws URISyntaxException, UnknownHostException, InterruptedException { GossipSettings settings = new GossipSettings(); settings.setActiveGossipClass(DatacenterRackAwareActiveGossiper.class.getName()); List startupMembers = new ArrayList<>(); @@ -48,44 +46,59 @@ public class IdAndPropertyTest extends AbstractIntegrationBase { x.put("a", "b"); x.put("datacenter", "dc1"); x.put("rack", "rack1"); - GossipManager gossipService1 = GossipManagerBuilder.newBuilder() + GossipManager gossipService1 = + GossipManagerBuilder.newBuilder() .cluster("a") .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0))) .id("0") .properties(x) .gossipMembers(startupMembers) - .gossipSettings(settings).build(); + .gossipSettings(settings) + .build(); gossipService1.init(); register(gossipService1); - + Map y = new HashMap<>(); y.put("a", "c"); y.put("datacenter", "dc2"); y.put("rack", "rack2"); - GossipManager gossipService2 = GossipManagerBuilder.newBuilder().cluster("a") - .uri( new URI("udp://" + "127.0.0.1" + ":" + (29000 + 10))) + GossipManager gossipService2 = + GossipManagerBuilder.newBuilder() + .cluster("a") + .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 10))) .id("1") .properties(y) - .gossipMembers(Arrays.asList(new RemoteMember("a", - new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0)), "0"))) - .gossipSettings(settings).build(); + .gossipMembers( + Arrays.asList( + new RemoteMember( + "a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0)), "0"))) + .gossipSettings(settings) + .build(); gossipService2.init(); register(gossipService2); - - TUnit.assertThat(() -> { - String value = ""; - try { - value = gossipService1.getLiveMembers().get(0).getProperties().get("a"); - } catch (RuntimeException e){ } - return value; - }).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo("c"); - - TUnit.assertThat(() -> { - String value = ""; - try { - value = gossipService2.getLiveMembers().get(0).getProperties().get("a"); - } catch (RuntimeException e){ } - return value; - }).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo("b"); + + TUnit.assertThat( + () -> { + String value = ""; + try { + value = gossipService1.getLiveMembers().get(0).getProperties().get("a"); + } catch (RuntimeException e) { + } + return value; + }) + .afterWaitingAtMost(10, TimeUnit.SECONDS) + .isEqualTo("c"); + + TUnit.assertThat( + () -> { + String value = ""; + try { + value = gossipService2.getLiveMembers().get(0).getProperties().get("a"); + } catch (RuntimeException e) { + } + return value; + }) + .afterWaitingAtMost(10, TimeUnit.SECONDS) + .isEqualTo("b"); } } diff --git a/gossip-itest/src/test/java/org/apache/gossip/PerNodeDataEventTest.java b/gossip-itest/src/test/java/org/apache/gossip/PerNodeDataEventTest.java index cc269f9..7ccf733 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/PerNodeDataEventTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/PerNodeDataEventTest.java @@ -35,7 +35,7 @@ import java.util.concurrent.TimeUnit; @RunWith(Parameterized.class) public class PerNodeDataEventTest extends AbstractIntegrationBase { - + private String receivedKey = ""; private String receivingNodeId = ""; private Object receivingNodeDataNewValue = ""; @@ -51,14 +51,12 @@ public class PerNodeDataEventTest extends AbstractIntegrationBase { @Parameterized.Parameters(name = "{index} bulkTransfer={1}") public static Collection data() { - return Arrays.asList(new Object[][]{ - {50000, false}, {55000, true} - }); + return Arrays.asList(new Object[][] {{50000, false}, {55000, true}}); } @Test public void perNodeDataEventTest() - throws InterruptedException, UnknownHostException, URISyntaxException { + throws InterruptedException, UnknownHostException, URISyntaxException { GossipSettings settings = new GossipSettings(); settings.setPersistRingState(false); settings.setPersistDataState(false); @@ -74,42 +72,54 @@ public class PerNodeDataEventTest extends AbstractIntegrationBase { final int clusterMembers = 2; 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 + "").gossipMembers(startupMembers).gossipSettings(settings).build(); + GossipManager gossipService = + GossipManagerBuilder.newBuilder() + .cluster(cluster) + .uri(uri) + .id(i + "") + .gossipMembers(startupMembers) + .gossipSettings(settings) + .build(); clients.add(gossipService); gossipService.init(); register(gossipService); } - + // check whether the members are discovered - TUnit.assertThat(() -> { - int total = 0; - for (int i = 0; i < clusterMembers; ++i) { - total += clients.get(i).getLiveMembers().size(); - } - return total; - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(2); - + TUnit.assertThat( + () -> { + int total = 0; + for (int i = 0; i < clusterMembers; ++i) { + total += clients.get(i).getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo(2); + // Adding new data to Node 1 clients.get(0).gossipPerNodeData(getPerNodeData("category", "distributed")); - + // Node 2 is interested in data changes for the key "organization" and "category" - clients.get(1).registerPerNodeDataSubscriber((nodeId, key, oldValue, newValue) -> { - if (!key.equals("organization") && !key.equals("category")) return; - receivingNodeId = nodeId; - receivedKey = key; - receivingNodeDataOldValue = oldValue; - receivingNodeDataNewValue = newValue; - lock.release(); - }); - + clients + .get(1) + .registerPerNodeDataSubscriber( + (nodeId, key, oldValue, newValue) -> { + if (!key.equals("organization") && !key.equals("category")) return; + receivingNodeId = nodeId; + receivedKey = key; + receivingNodeDataOldValue = oldValue; + receivingNodeDataNewValue = newValue; + lock.release(); + }); + // Node 2 first time adds Node 1 data lock.tryAcquire(10, TimeUnit.SECONDS); Assert.assertEquals("1", receivingNodeId); Assert.assertEquals("category", receivedKey); Assert.assertEquals(null, receivingNodeDataOldValue); Assert.assertEquals("distributed", receivingNodeDataNewValue); - + // Node 1 adds new per node data clients.get(0).gossipPerNodeData(getPerNodeData("organization", "apache")); // Node 2 adds new data key from Node 1 @@ -118,7 +128,7 @@ public class PerNodeDataEventTest extends AbstractIntegrationBase { Assert.assertEquals("organization", receivedKey); Assert.assertEquals(null, receivingNodeDataOldValue); Assert.assertEquals("apache", receivingNodeDataNewValue); - + // Node 1 updates its value clients.get(0).gossipPerNodeData(getPerNodeData("organization", "apache-gossip")); // Node 2 updates existing value @@ -127,9 +137,8 @@ public class PerNodeDataEventTest extends AbstractIntegrationBase { Assert.assertEquals("organization", receivedKey); Assert.assertEquals("apache", receivingNodeDataOldValue); Assert.assertEquals("apache-gossip", receivingNodeDataNewValue); - } - + private PerNodeDataMessage getPerNodeData(String key, String value) { PerNodeDataMessage g = new PerNodeDataMessage(); g.setExpireAt(Long.MAX_VALUE); @@ -138,5 +147,4 @@ public class PerNodeDataEventTest extends AbstractIntegrationBase { g.setTimestamp(System.currentTimeMillis()); return g; } - } diff --git a/gossip-itest/src/test/java/org/apache/gossip/PerNodeDataReplicationControlTest.java b/gossip-itest/src/test/java/org/apache/gossip/PerNodeDataReplicationControlTest.java index e715410..003d87f 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/PerNodeDataReplicationControlTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/PerNodeDataReplicationControlTest.java @@ -22,12 +22,8 @@ import org.apache.gossip.manager.DatacenterRackAwareActiveGossiper; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManagerBuilder; import org.apache.gossip.model.PerNodeDataMessage; -import org.apache.gossip.model.SharedDataMessage; import org.apache.gossip.replication.*; -import org.junit.Assert; import org.junit.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import java.net.URI; import java.net.URISyntaxException; @@ -35,87 +31,105 @@ import java.net.UnknownHostException; import java.util.*; import java.util.concurrent.TimeUnit; -@RunWith(JUnitPlatform.class) public class PerNodeDataReplicationControlTest extends AbstractIntegrationBase { @Test - public void perNodeDataReplicationTest() - throws InterruptedException, UnknownHostException, URISyntaxException { + public void perNodeDataReplicationTest() throws URISyntaxException { generateStandardNodes(3); // check whether the members are discovered - TUnit.assertThat(() -> { - int total = 0; - for (GossipManager node : nodes) { - total += node.getLiveMembers().size(); - } - return total; - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(2); + TUnit.assertThat( + () -> { + int total = 0; + for (GossipManager node : nodes) { + total += node.getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo(2); // Adding new per node data to Node 1 with default replication (replicate all) - nodes.get(0).gossipPerNodeData(getPerNodeData("public", "I am visible to all", - new AllReplicable<>())); + nodes + .get(0) + .gossipPerNodeData(getPerNodeData("public", "I am visible to all", new AllReplicable<>())); // Adding new per node data to Node 1 with no replication (replicate none) - nodes.get(0).gossipPerNodeData(getPerNodeData("private", "I am private", - new NotReplicable<>())); + nodes + .get(0) + .gossipPerNodeData(getPerNodeData("private", "I am private", new NotReplicable<>())); List whiteList = new ArrayList<>(); whiteList.add(nodes.get(1).getMyself()); // Adding new per node data to Node 1 with white list Node 2 - nodes.get(0).gossipPerNodeData(getPerNodeData("wl", "white list", - new WhiteListReplicable<>(whiteList))); + nodes + .get(0) + .gossipPerNodeData( + getPerNodeData("wl", "white list", new WhiteListReplicable<>(whiteList))); List blackList = new ArrayList<>(); blackList.add(nodes.get(1).getMyself()); // Adding new per node data to Node 1 with black list Node 2 - nodes.get(0).gossipPerNodeData(getPerNodeData("bl", "black list", - new BlackListReplicable<>(blackList))); + nodes + .get(0) + .gossipPerNodeData( + getPerNodeData("bl", "black list", new BlackListReplicable<>(blackList))); // Node 2 and 3 must have the shared data with key 'public' - TUnit.assertThat(() -> { - PerNodeDataMessage message = nodes.get(1).findPerNodeGossipData("1", "public"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("I am visible to all"); + TUnit.assertThat( + () -> { + PerNodeDataMessage message = nodes.get(1).findPerNodeGossipData("1", "public"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("I am visible to all"); - TUnit.assertThat(() -> { - PerNodeDataMessage message = nodes.get(2).findPerNodeGossipData("1", "public"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("I am visible to all"); + TUnit.assertThat( + () -> { + PerNodeDataMessage message = nodes.get(2).findPerNodeGossipData("1", "public"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("I am visible to all"); // Node 2 must have shared data with key wl - TUnit.assertThat(() -> { - PerNodeDataMessage message = nodes.get(1).findPerNodeGossipData("1", "wl"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("white list"); + TUnit.assertThat( + () -> { + PerNodeDataMessage message = nodes.get(1).findPerNodeGossipData("1", "wl"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("white list"); // Node 3 must have shared data with key bl - TUnit.assertThat(() -> { - PerNodeDataMessage message = nodes.get(2).findPerNodeGossipData("1", "bl"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("black list"); - + TUnit.assertThat( + () -> { + PerNodeDataMessage message = nodes.get(2).findPerNodeGossipData("1", "bl"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("black list"); } @Test public void perNodeDataDcReplicationTest() - throws InterruptedException, UnknownHostException, URISyntaxException { + throws InterruptedException, UnknownHostException, URISyntaxException { GossipSettings settings = new GossipSettings(); settings.setPersistRingState(false); @@ -131,57 +145,68 @@ public class PerNodeDataReplicationControlTest extends AbstractIntegrationBase { RemoteMember seeder = new RemoteMember(cluster, URI.create("udp://127.0.0.1:5001"), "1"); // initialize 2 data centers with each having two racks - createDcNode(URI.create("udp://127.0.0.1:5001"), "1", settings, seeder, cluster, - "DataCenter1", "Rack1"); - createDcNode(URI.create("udp://127.0.0.1:5002"), "2", settings, seeder, cluster, - "DataCenter1", "Rack2"); + createDcNode( + URI.create("udp://127.0.0.1:5001"), "1", settings, seeder, cluster, "DataCenter1", "Rack1"); + createDcNode( + URI.create("udp://127.0.0.1:5002"), "2", settings, seeder, cluster, "DataCenter1", "Rack2"); - createDcNode(URI.create("udp://127.0.0.1:5006"), "6", settings, seeder, cluster, - "DataCenter2", "Rack1"); - createDcNode(URI.create("udp://127.0.0.1:5007"), "7", settings, seeder, cluster, - "DataCenter2", "Rack1"); + createDcNode( + URI.create("udp://127.0.0.1:5006"), "6", settings, seeder, cluster, "DataCenter2", "Rack1"); + createDcNode( + URI.create("udp://127.0.0.1:5007"), "7", settings, seeder, cluster, "DataCenter2", "Rack1"); // check whether the members are discovered - TUnit.assertThat(() -> { - int total = 0; - for (int i = 0; i < 4; ++i) { - total += nodes.get(i).getLiveMembers().size(); - } - return total; - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(12); + TUnit.assertThat( + () -> { + int total = 0; + for (int i = 0; i < 4; ++i) { + total += nodes.get(i).getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo(12); // Node 1 has a shared key with 'Dc1Rack1' - nodes.get(0).gossipPerNodeData(getPerNodeData("Dc1Rack1", "I am belong to Dc1", - new DataCenterReplicable<>())); + nodes + .get(0) + .gossipPerNodeData( + getPerNodeData("Dc1Rack1", "I am belong to Dc1", new DataCenterReplicable<>())); // Node 6 has a shared key with 'Dc2Rack1' - nodes.get(2).gossipPerNodeData(getPerNodeData("Dc2Rack1", "I am belong to Dc2", - new DataCenterReplicable<>())); + nodes + .get(2) + .gossipPerNodeData( + getPerNodeData("Dc2Rack1", "I am belong to Dc2", new DataCenterReplicable<>())); // Node 2 must have the shared data with key 'Dc1Rack1' - TUnit.assertThat(() -> { - PerNodeDataMessage message = nodes.get(1).findPerNodeGossipData("1", "Dc1Rack1"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("I am belong to Dc1"); - + TUnit.assertThat( + () -> { + PerNodeDataMessage message = nodes.get(1).findPerNodeGossipData("1", "Dc1Rack1"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("I am belong to Dc1"); // Node 7 must have the shared data with key 'Dc2Rack1' - TUnit.assertThat(() -> { - PerNodeDataMessage message = nodes.get(3).findPerNodeGossipData("6", "Dc2Rack1"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("I am belong to Dc2"); - + TUnit.assertThat( + () -> { + PerNodeDataMessage message = nodes.get(3).findPerNodeGossipData("6", "Dc2Rack1"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("I am belong to Dc2"); } - private PerNodeDataMessage getPerNodeData(String key, String value, - Replicable replicable) { + private PerNodeDataMessage getPerNodeData( + String key, String value, Replicable replicable) { PerNodeDataMessage g = new PerNodeDataMessage(); g.setExpireAt(Long.MAX_VALUE); g.setKey(key); @@ -191,17 +216,28 @@ public class PerNodeDataReplicationControlTest extends AbstractIntegrationBase { return g; } - private void createDcNode(URI uri, String id, GossipSettings settings, RemoteMember seeder, - String cluster, String dataCenter, String rack){ + private void createDcNode( + URI uri, + String id, + GossipSettings settings, + RemoteMember seeder, + String cluster, + String dataCenter, + String rack) { Map props = new HashMap<>(); props.put(DatacenterRackAwareActiveGossiper.DATACENTER, dataCenter); props.put(DatacenterRackAwareActiveGossiper.RACK, rack); - GossipManager dcNode = GossipManagerBuilder.newBuilder().cluster(cluster).uri(uri).id(id) - .gossipSettings(settings).gossipMembers(Arrays.asList(seeder)).properties(props) + GossipManager dcNode = + GossipManagerBuilder.newBuilder() + .cluster(cluster) + .uri(uri) + .id(id) + .gossipSettings(settings) + .gossipMembers(Arrays.asList(seeder)) + .properties(props) .build(); dcNode.init(); register(dcNode); } - } diff --git a/gossip-itest/src/test/java/org/apache/gossip/SharedDataEventTest.java b/gossip-itest/src/test/java/org/apache/gossip/SharedDataEventTest.java index 547cd45..b4a0ac3 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/SharedDataEventTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/SharedDataEventTest.java @@ -18,6 +18,12 @@ package org.apache.gossip; import io.teknek.tunit.TUnit; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.util.*; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; import org.apache.gossip.crdt.GrowOnlyCounter; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManagerBuilder; @@ -27,13 +33,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; -import java.util.*; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - @RunWith(Parameterized.class) public class SharedDataEventTest extends AbstractIntegrationBase { diff --git a/gossip-itest/src/test/java/org/apache/gossip/SharedDataLockTest.java b/gossip-itest/src/test/java/org/apache/gossip/SharedDataLockTest.java index 01dbac0..6081ee4 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/SharedDataLockTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/SharedDataLockTest.java @@ -23,8 +23,6 @@ import org.apache.gossip.manager.GossipManagerBuilder; import org.apache.gossip.model.SharedDataMessage; import org.junit.Assert; import org.junit.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import java.net.URI; import java.net.URISyntaxException; @@ -34,12 +32,11 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; -@RunWith(JUnitPlatform.class) public class SharedDataLockTest extends AbstractIntegrationBase { @Test public void sharedDataLockRandomVoteTest() - throws InterruptedException, UnknownHostException, URISyntaxException { + throws InterruptedException, UnknownHostException, URISyntaxException { GossipSettings settings = new GossipSettings(); settings.setPersistRingState(false); settings.setPersistDataState(false); @@ -54,8 +51,14 @@ public class SharedDataLockTest extends AbstractIntegrationBase { final int clusterMembers = 10; for (int i = 1; i < clusterMembers + 1; ++i) { URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i)); - GossipManager gossipService = GossipManagerBuilder.newBuilder().cluster(cluster).uri(uri) - .id(i + "").gossipMembers(startupMembers).gossipSettings(settings).build(); + GossipManager gossipService = + GossipManagerBuilder.newBuilder() + .cluster(cluster) + .uri(uri) + .id(i + "") + .gossipMembers(startupMembers) + .gossipSettings(settings) + .build(); clients.add(gossipService); gossipService.getLockManager().setNumberOfNodes(clusterMembers); gossipService.init(); @@ -69,34 +72,40 @@ public class SharedDataLockTest extends AbstractIntegrationBase { final AtomicInteger lockFailedCount = new AtomicInteger(0); // Node 1 try to lock on key category - Thread Node1LockingThread = new Thread(() -> { - try { - clients.get(0).acquireSharedDataLock("category"); - lockSuccessCount.incrementAndGet(); - } catch (VoteFailedException ignore) { - lockFailedCount.incrementAndGet(); - } - }); + Thread Node1LockingThread = + new Thread( + () -> { + try { + clients.get(0).acquireSharedDataLock("category"); + lockSuccessCount.incrementAndGet(); + } catch (VoteFailedException ignore) { + lockFailedCount.incrementAndGet(); + } + }); // Node 3 try to lock on key category - Thread Node3LockingThread = new Thread(() -> { - try { - clients.get(2).acquireSharedDataLock("category"); - lockSuccessCount.incrementAndGet(); - } catch (VoteFailedException ignore) { - lockFailedCount.incrementAndGet(); - } - }); + Thread Node3LockingThread = + new Thread( + () -> { + try { + clients.get(2).acquireSharedDataLock("category"); + lockSuccessCount.incrementAndGet(); + } catch (VoteFailedException ignore) { + lockFailedCount.incrementAndGet(); + } + }); // Node 6 try to lock on key category - Thread Node5LockingThread = new Thread(() -> { - try { - clients.get(5).acquireSharedDataLock("category"); - lockSuccessCount.incrementAndGet(); - } catch (VoteFailedException ignore) { - lockFailedCount.incrementAndGet(); - } - }); + Thread Node5LockingThread = + new Thread( + () -> { + try { + clients.get(5).acquireSharedDataLock("category"); + lockSuccessCount.incrementAndGet(); + } catch (VoteFailedException ignore) { + lockFailedCount.incrementAndGet(); + } + }); Node1LockingThread.start(); Node3LockingThread.start(); @@ -110,7 +119,6 @@ public class SharedDataLockTest extends AbstractIntegrationBase { Assert.assertEquals(1, lockSuccessCount.get()); // Other nodes should fail Assert.assertEquals(2, lockFailedCount.get()); - } private SharedDataMessage sharedNodeData(String key, String value) { @@ -121,5 +129,4 @@ public class SharedDataLockTest extends AbstractIntegrationBase { g.setTimestamp(System.currentTimeMillis()); return g; } - } diff --git a/gossip-itest/src/test/java/org/apache/gossip/SharedDataReplicationControlTest.java b/gossip-itest/src/test/java/org/apache/gossip/SharedDataReplicationControlTest.java index 8ce063d..a3ec1d1 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/SharedDataReplicationControlTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/SharedDataReplicationControlTest.java @@ -28,10 +28,7 @@ import org.apache.gossip.replication.DataCenterReplicable; import org.apache.gossip.replication.NotReplicable; import org.apache.gossip.replication.Replicable; import org.apache.gossip.replication.WhiteListReplicable; -import org.junit.Assert; import org.junit.Test; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; import java.net.URI; import java.net.URISyntaxException; @@ -44,84 +41,100 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; -@RunWith(JUnitPlatform.class) public class SharedDataReplicationControlTest extends AbstractIntegrationBase { @Test public void sharedDataReplicationTest() - throws InterruptedException, UnknownHostException, URISyntaxException { + throws URISyntaxException { generateStandardNodes(3); // check whether the members are discovered - TUnit.assertThat(() -> { - int total = 0; - for (GossipManager node : nodes) { - total += node.getLiveMembers().size(); - } - return total; - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(2); + TUnit.assertThat( + () -> { + int total = 0; + for (GossipManager node : nodes) { + total += node.getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo(2); // Adding new shared data to Node 1 with default replication (replicate all) - nodes.get(0).gossipSharedData(sharedNodeData("public", "I am visible to all", - new AllReplicable<>())); + nodes + .get(0) + .gossipSharedData(sharedNodeData("public", "I am visible to all", new AllReplicable<>())); // Adding new shared data to Node 1 with no replication (replicate none) - nodes.get(0).gossipSharedData(sharedNodeData("private", "I am private", - new NotReplicable<>())); + nodes.get(0).gossipSharedData(sharedNodeData("private", "I am private", new NotReplicable<>())); List whiteList = new ArrayList<>(); whiteList.add(nodes.get(1).getMyself()); // Adding new shared data to Node 1 with white list Node 2 - nodes.get(0).gossipSharedData(sharedNodeData("wl", "white list", - new WhiteListReplicable<>(whiteList))); + nodes + .get(0) + .gossipSharedData(sharedNodeData("wl", "white list", new WhiteListReplicable<>(whiteList))); List blackList = new ArrayList<>(); blackList.add(nodes.get(1).getMyself()); // Adding new shared data to Node 1 with black list Node 2 - nodes.get(0).gossipSharedData(sharedNodeData("bl", "black list", - new BlackListReplicable<>(blackList))); + nodes + .get(0) + .gossipSharedData(sharedNodeData("bl", "black list", new BlackListReplicable<>(blackList))); - TUnit.assertThat(() -> { - SharedDataMessage message = nodes.get(1).findSharedGossipData("public"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("I am visible to all"); + TUnit.assertThat( + () -> { + SharedDataMessage message = nodes.get(1).findSharedGossipData("public"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("I am visible to all"); - TUnit.assertThat(() -> { - SharedDataMessage message = nodes.get(2).findSharedGossipData("public"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("I am visible to all"); + TUnit.assertThat( + () -> { + SharedDataMessage message = nodes.get(2).findSharedGossipData("public"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("I am visible to all"); // Node 2 must have shared data with key wl - TUnit.assertThat(() -> { - SharedDataMessage message = nodes.get(1).findSharedGossipData("wl"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("white list"); + TUnit.assertThat( + () -> { + SharedDataMessage message = nodes.get(1).findSharedGossipData("wl"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("white list"); // Node 3 must have shared data with key bl - TUnit.assertThat(() -> { - SharedDataMessage message = nodes.get(2).findSharedGossipData("bl"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("black list"); + TUnit.assertThat( + () -> { + SharedDataMessage message = nodes.get(2).findSharedGossipData("bl"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("black list"); } @Test public void sharedDataDcReplicationTest() - throws InterruptedException, UnknownHostException, URISyntaxException { + throws InterruptedException, UnknownHostException, URISyntaxException { GossipSettings settings = new GossipSettings(); settings.setPersistRingState(false); @@ -137,56 +150,68 @@ public class SharedDataReplicationControlTest extends AbstractIntegrationBase { RemoteMember seeder = new RemoteMember(cluster, URI.create("udp://127.0.0.1:5001"), "1"); // initialize 2 data centers with each having two racks - createDcNode(URI.create("udp://127.0.0.1:5001"), "1", settings, seeder, cluster, - "DataCenter1", "Rack1"); - createDcNode(URI.create("udp://127.0.0.1:5002"), "2", settings, seeder, cluster, - "DataCenter1", "Rack2"); + createDcNode( + URI.create("udp://127.0.0.1:5001"), "1", settings, seeder, cluster, "DataCenter1", "Rack1"); + createDcNode( + URI.create("udp://127.0.0.1:5002"), "2", settings, seeder, cluster, "DataCenter1", "Rack2"); - createDcNode(URI.create("udp://127.0.0.1:5006"), "6", settings, seeder, cluster, - "DataCenter2", "Rack1"); - createDcNode(URI.create("udp://127.0.0.1:5007"), "7", settings, seeder, cluster, - "DataCenter2", "Rack1"); + createDcNode( + URI.create("udp://127.0.0.1:5006"), "6", settings, seeder, cluster, "DataCenter2", "Rack1"); + createDcNode( + URI.create("udp://127.0.0.1:5007"), "7", settings, seeder, cluster, "DataCenter2", "Rack1"); // check whether the members are discovered - TUnit.assertThat(() -> { - int total = 0; - for (int i = 0; i < 4; ++i) { - total += nodes.get(i).getLiveMembers().size(); - } - return total; - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(12); + TUnit.assertThat( + () -> { + int total = 0; + for (int i = 0; i < 4; ++i) { + total += nodes.get(i).getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo(12); // Node 1 has a shared key with 'Dc1Rack1' - nodes.get(0).gossipSharedData(sharedNodeData("Dc1Rack1", "I am belong to Dc1", - new DataCenterReplicable<>())); + nodes + .get(0) + .gossipSharedData( + sharedNodeData("Dc1Rack1", "I am belong to Dc1", new DataCenterReplicable<>())); // Node 6 has a shared key with 'Dc2Rack1' - nodes.get(2).gossipSharedData(sharedNodeData("Dc2Rack1", "I am belong to Dc2", - new DataCenterReplicable<>())); + nodes + .get(2) + .gossipSharedData( + sharedNodeData("Dc2Rack1", "I am belong to Dc2", new DataCenterReplicable<>())); // Node 2 must have the shared data with key 'Dc1Rack1' - TUnit.assertThat(() -> { - SharedDataMessage message = nodes.get(1).findSharedGossipData("Dc1Rack1"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("I am belong to Dc1"); + TUnit.assertThat( + () -> { + SharedDataMessage message = nodes.get(1).findSharedGossipData("Dc1Rack1"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("I am belong to Dc1"); // Node 7 must have the shared data with key 'Dc2Rack1' - TUnit.assertThat(() -> { - SharedDataMessage message = nodes.get(3).findSharedGossipData("Dc2Rack1"); - if(message == null){ - return ""; - }else { - return message.getPayload(); - } - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("I am belong to Dc2"); - + TUnit.assertThat( + () -> { + SharedDataMessage message = nodes.get(3).findSharedGossipData("Dc2Rack1"); + if (message == null) { + return ""; + } else { + return message.getPayload(); + } + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo("I am belong to Dc2"); } - private SharedDataMessage sharedNodeData(String key, String value, - Replicable replicable) { + private SharedDataMessage sharedNodeData( + String key, String value, Replicable replicable) { SharedDataMessage g = new SharedDataMessage(); g.setExpireAt(Long.MAX_VALUE); g.setKey(key); @@ -196,17 +221,28 @@ public class SharedDataReplicationControlTest extends AbstractIntegrationBase { return g; } - private void createDcNode(URI uri, String id, GossipSettings settings, RemoteMember seeder, - String cluster, String dataCenter, String rack){ + private void createDcNode( + URI uri, + String id, + GossipSettings settings, + RemoteMember seeder, + String cluster, + String dataCenter, + String rack) { Map props = new HashMap<>(); props.put(DatacenterRackAwareActiveGossiper.DATACENTER, dataCenter); props.put(DatacenterRackAwareActiveGossiper.RACK, rack); - GossipManager dcNode = GossipManagerBuilder.newBuilder().cluster(cluster).uri(uri).id(id) - .gossipSettings(settings).gossipMembers(Arrays.asList(seeder)).properties(props) + GossipManager dcNode = + GossipManagerBuilder.newBuilder() + .cluster(cluster) + .uri(uri) + .id(id) + .gossipSettings(settings) + .gossipMembers(Arrays.asList(seeder)) + .properties(props) .build(); dcNode.init(); register(dcNode); } - } diff --git a/gossip-itest/src/test/java/org/apache/gossip/ShutdownDeadtimeTest.java b/gossip-itest/src/test/java/org/apache/gossip/ShutdownDeadtimeTest.java index e5c3639..34a87ac 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/ShutdownDeadtimeTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/ShutdownDeadtimeTest.java @@ -18,37 +18,28 @@ 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.Collections; import java.util.List; import java.util.Random; import java.util.UUID; -import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; - +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManagerBuilder; -import org.apache.log4j.Logger; - -import org.junit.platform.runner.JUnitPlatform; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; - -@RunWith(JUnitPlatform.class) +@Slf4j public class ShutdownDeadtimeTest { - private static final Logger log = Logger.getLogger(ShutdownDeadtimeTest.class); - - // Note: this test is floppy depending on the values in GossipSettings (smaller values seem to do harm), and the + // Note: this test is floppy depending on the values in GossipSettings (smaller values seem to do + // harm), and the // sleep that happens after startup. @Test public void DeadNodesDoNotComeAliveAgain() - throws InterruptedException, UnknownHostException, URISyntaxException { + throws InterruptedException, URISyntaxException { GossipSettings settings = new GossipSettings(100, 10000, 1000, 1, 10.0, "normal", false); settings.setPersistRingState(false); settings.setPersistDataState(false); @@ -59,11 +50,13 @@ public class ShutdownDeadtimeTest { URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30300 + i)); startupMembers.add(new RemoteMember(cluster, uri, i + "")); } - final List clients = Collections.synchronizedList(new ArrayList()); + final List clients = + Collections.synchronizedList(new ArrayList()); final int clusterMembers = 5; for (int i = 1; i < clusterMembers + 1; ++i) { URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30300 + i)); - GossipManager gossipService = GossipManagerBuilder.newBuilder() + GossipManager gossipService = + GossipManagerBuilder.newBuilder() .cluster(cluster) .uri(uri) .id(i + "") @@ -72,77 +65,77 @@ public class ShutdownDeadtimeTest { .build(); clients.add(gossipService); gossipService.init(); - Thread.sleep(1000); + Thread.sleep(1000); } - TUnit.assertThat(new Callable() { - 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); + TUnit.assertThat( + () -> { + int total = 0; + for (int i = 0; i < clusterMembers; ++i) { + total += clients.get(i).getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(40, TimeUnit.SECONDS) + .isEqualTo(20); // shutdown one client and verify that one client is lost. Random r = new Random(); int randomClientId = r.nextInt(clusterMembers); log.info("shutting down " + randomClientId); - final int shutdownPort = clients.get(randomClientId).getMyself().getUri() - .getPort(); + final int shutdownPort = clients.get(randomClientId).getMyself().getUri().getPort(); final String shutdownId = clients.get(randomClientId).getMyself().getId(); clients.get(randomClientId).shutdown(); - TUnit.assertThat(new Callable() { - 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(16); + TUnit.assertThat( + () -> { + int total = 0; + for (int i = 0; i < clusterMembers; ++i) { + total += clients.get(i).getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(40, TimeUnit.SECONDS) + .isEqualTo(16); clients.remove(randomClientId); - TUnit.assertThat(new Callable() { - public Integer call() throws Exception { - int total = 0; - for (int i = 0; i < clusterMembers - 1; ++i) { - total += clients.get(i).getDeadMembers().size(); - } - return total; - } - }).afterWaitingAtMost(50, TimeUnit.SECONDS).isEqualTo(4); + TUnit.assertThat( + () -> { + int total = 0; + for (int i = 0; i < clusterMembers - 1; ++i) { + total += clients.get(i).getDeadMembers().size(); + } + return total; + }) + .afterWaitingAtMost(50, TimeUnit.SECONDS) + .isEqualTo(4); URI uri = new URI("udp://" + "127.0.0.1" + ":" + shutdownPort); // start client again - GossipManager gossipService = GossipManagerBuilder.newBuilder() + GossipManager gossipService = + GossipManagerBuilder.newBuilder() .gossipSettings(settings) .cluster(cluster) .uri(uri) - .id(shutdownId+"") + .id(shutdownId) .gossipMembers(startupMembers) .build(); clients.add(gossipService); gossipService.init(); // verify that the client is alive again for every node - TUnit.assertThat(new Callable() { - public Integer call() throws Exception { - int total = 0; - for (int i = 0; i < clusterMembers; ++i) { - total += clients.get(i).getLiveMembers().size(); - } - return total; - } - }).afterWaitingAtMost(60, TimeUnit.SECONDS).isEqualTo(20); + TUnit.assertThat( + () -> { + int total = 0; + for (int i = 0; i < clusterMembers; ++i) { + total += clients.get(i).getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(60, TimeUnit.SECONDS) + .isEqualTo(20); for (int i = 0; i < clusterMembers; ++i) { final int j = i; - new Thread() { - public void run(){ - clients.get(j).shutdown(); - } - }.start(); + new Thread(() -> clients.get(j).shutdown()).start(); } } } diff --git a/gossip-itest/src/test/java/org/apache/gossip/SignedMessageTest.java b/gossip-itest/src/test/java/org/apache/gossip/SignedMessageTest.java index e288cb8..a3b3e7c 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/SignedMessageTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/SignedMessageTest.java @@ -40,22 +40,27 @@ import io.teknek.tunit.TUnit; public class SignedMessageTest extends AbstractIntegrationBase { - private GossipSettings gossiperThatSigns(){ + private GossipSettings gossiperThatSigns() { GossipSettings settings = new GossipSettings(); settings.setPersistRingState(false); settings.setPersistDataState(false); settings.setSignMessages(true); return settings; } - - private GossipSettings gossiperThatSigns(String keysDir){ + + private GossipSettings gossiperThatSigns(String keysDir) { GossipSettings settings = gossiperThatSigns(); settings.setPathToKeyStore(Objects.requireNonNull(keysDir)); return settings; } - + @Test - public void dataTest() throws InterruptedException, URISyntaxException, NoSuchAlgorithmException, NoSuchProviderException, IOException { + public void dataTest() + throws InterruptedException, + URISyntaxException, + NoSuchAlgorithmException, + NoSuchProviderException, + IOException { final String keys = System.getProperty("java.io.tmpdir") + "/keys"; GossipSettings settings = gossiperThatSigns(keys); setup(keys); @@ -68,7 +73,8 @@ public class SignedMessageTest extends AbstractIntegrationBase { final List clients = new ArrayList<>(); for (int i = 1; i < 3; ++i) { URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30000 + i)); - GossipManager gossipService = GossipManagerBuilder.newBuilder() + GossipManager gossipService = + GossipManagerBuilder.newBuilder() .cluster(cluster) .uri(uri) .id(i + "") @@ -82,25 +88,28 @@ public class SignedMessageTest extends AbstractIntegrationBase { assertOnlySignedMessages(clients); cleanup(keys, clients); } - - private void assertTwoAlive(List clients){ - TUnit.assertThat(() -> { - int total = 0; - for (int i = 0; i < clients.size(); ++i) { - total += clients.get(i).getLiveMembers().size(); - } - return total; - }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(2); + + private void assertTwoAlive(List clients) { + TUnit.assertThat( + () -> { + int total = 0; + for (int i = 0; i < clients.size(); ++i) { + total += clients.get(i).getLiveMembers().size(); + } + return total; + }) + .afterWaitingAtMost(20, TimeUnit.SECONDS) + .isEqualTo(2); } - - private void assertOnlySignedMessages(List clients){ - Assert.assertEquals(0, clients.get(0).getRegistry() - .meter(PassiveGossipConstants.UNSIGNED_MESSAGE).getCount()); - Assert.assertTrue(clients.get(0).getRegistry() - .meter(PassiveGossipConstants.SIGNED_MESSAGE).getCount() > 0); + + private void assertOnlySignedMessages(List clients) { + Assert.assertEquals( + 0, clients.get(0).getRegistry().meter(PassiveGossipConstants.UNSIGNED_MESSAGE).getCount()); + Assert.assertTrue( + clients.get(0).getRegistry().meter(PassiveGossipConstants.SIGNED_MESSAGE).getCount() > 0); } - - private void cleanup(String keys, List clients){ + + private void cleanup(String keys, List clients) { new File(keys, "1").delete(); new File(keys, "2").delete(); new File(keys).delete(); @@ -108,8 +117,9 @@ public class SignedMessageTest extends AbstractIntegrationBase { clients.get(i).shutdown(); } } - - private void setup(String keys) throws NoSuchAlgorithmException, NoSuchProviderException, IOException { + + private void setup(String keys) + throws NoSuchAlgorithmException, NoSuchProviderException, IOException { new File(keys).mkdir(); KeyTool.generatePubandPrivateKeyFiles(keys, "1"); KeyTool.generatePubandPrivateKeyFiles(keys, "2"); diff --git a/gossip-itest/src/test/java/org/apache/gossip/StartupSettingsTest.java b/gossip-itest/src/test/java/org/apache/gossip/StartupSettingsTest.java index ea93a90..3eb1851 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/StartupSettingsTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/StartupSettingsTest.java @@ -17,9 +17,9 @@ */ package org.apache.gossip; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManagerBuilder; -import org.apache.log4j.Logger; import org.junit.jupiter.api.Test; @@ -29,61 +29,68 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.UUID; -import org.junit.platform.runner.JUnitPlatform; -import org.junit.runner.RunWith; -/** - * Tests support of using {@code StartupSettings} and thereby reading - * setup config from file. - */ -@RunWith(JUnitPlatform.class) +/** Tests support of using {@code StartupSettings} and thereby reading setup config from file. */ +@Slf4j public class StartupSettingsTest { - private static final Logger log = Logger.getLogger(StartupSettingsTest.class); private static final String CLUSTER = UUID.randomUUID().toString(); @Test - public void testUsingSettingsFile() throws IOException, InterruptedException, URISyntaxException { - File settingsFile = File.createTempFile("gossipTest",".json"); + public void testUsingSettingsFile() throws IOException, URISyntaxException { + File settingsFile = File.createTempFile("gossipTest", ".json"); settingsFile.deleteOnExit(); writeSettingsFile(settingsFile); URI uri = new URI("udp://" + "127.0.0.1" + ":" + 50000); GossipSettings firstGossipSettings = new GossipSettings(); - firstGossipSettings.setTransportManagerClass("org.apache.gossip.transport.UnitTestTransportManager"); - firstGossipSettings.setProtocolManagerClass("org.apache.gossip.protocol.UnitTestProtocolManager"); - GossipManager firstService = GossipManagerBuilder.newBuilder() + firstGossipSettings.setTransportManagerClass( + "org.apache.gossip.transport.UnitTestTransportManager"); + firstGossipSettings.setProtocolManagerClass( + "org.apache.gossip.protocol.UnitTestProtocolManager"); + GossipManager firstService = + GossipManagerBuilder.newBuilder() .cluster(CLUSTER) .uri(uri) .id("1") - .gossipSettings(firstGossipSettings).build(); + .gossipSettings(firstGossipSettings) + .build(); firstService.init(); - GossipManager manager = GossipManagerBuilder.newBuilder() - .startupSettings(StartupSettings.fromJSONFile(settingsFile)).build(); + GossipManager manager = + GossipManagerBuilder.newBuilder() + .startupSettings(StartupSettings.fromJSONFile(settingsFile)) + .build(); manager.init(); firstService.shutdown(); manager.shutdown(); } - private void writeSettingsFile( File target ) throws IOException { + private void writeSettingsFile(File target) throws IOException { String settings = - "[{\n" + // It is odd that this is meant to be in an array, but oh well. - " \"cluster\":\"" + CLUSTER + "\",\n" + - " \"id\":\"" + "2" + "\",\n" + - " \"uri\":\"udp://127.0.0.1:50001\",\n" + - " \"gossip_interval\":1000,\n" + - " \"window_size\":1000,\n" + - " \"minimum_samples\":5,\n" + - " \"cleanup_interval\":10000,\n" + - " \"convict_threshold\":2.6,\n" + - " \"distribution\":\"exponential\",\n" + - " \"transport_manager_class\":\"org.apache.gossip.transport.UnitTestTransportManager\",\n" + - " \"protocol_manager_class\":\"org.apache.gossip.protocol.UnitTestProtocolManager\",\n" + - " \"properties\":{},\n" + - " \"members\":[\n" + - " {\"cluster\": \"" + CLUSTER + "\",\"uri\":\"udp://127.0.0.1:5000\"}\n" + - " ]\n" + - "}]"; + "[{\n" + + // It is odd that this is meant to be in an array, but oh well. + " \"cluster\":\"" + + CLUSTER + + "\",\n" + + " \"id\":\"" + + "2" + + "\",\n" + + " \"uri\":\"udp://127.0.0.1:50001\",\n" + + " \"gossip_interval\":1000,\n" + + " \"window_size\":1000,\n" + + " \"minimum_samples\":5,\n" + + " \"cleanup_interval\":10000,\n" + + " \"convict_threshold\":2.6,\n" + + " \"distribution\":\"exponential\",\n" + + " \"transport_manager_class\":\"org.apache.gossip.transport.UnitTestTransportManager\",\n" + + " \"protocol_manager_class\":\"org.apache.gossip.protocol.UnitTestProtocolManager\",\n" + + " \"properties\":{},\n" + + " \"members\":[\n" + + " {\"cluster\": \"" + + CLUSTER + + "\",\"uri\":\"udp://127.0.0.1:5000\"}\n" + + " ]\n" + + "}]"; - log.info( "Using settings file with contents of:\n---\n" + settings + "\n---" ); + log.info("Using settings file with contents of:\n---\n" + settings + "\n---"); FileOutputStream output = new FileOutputStream(target); output.write(settings.getBytes()); output.close(); diff --git a/gossip-itest/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java b/gossip-itest/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java index eb9abcd..d9f5fa8 100644 --- a/gossip-itest/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java +++ b/gossip-itest/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.gossip; +package org.apache.gossip; import io.teknek.tunit.TUnit; @@ -27,13 +27,10 @@ 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 @@ -53,15 +50,16 @@ public class TenNodeThreeSeedTest { String cluster = UUID.randomUUID().toString(); int seedNodes = 3; List startupMembers = new ArrayList<>(); - for (int i = 1; i < seedNodes+1; ++i) { + 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 clients = new ArrayList<>(); final int clusterMembers = 5; - for (int i = 1; i < clusterMembers+1; ++i) { + for (int i = 1; i < clusterMembers + 1; ++i) { URI uri = new URI("udp://" + "127.0.0.1" + ":" + (base + i)); - GossipManager gossipService = GossipManagerBuilder.newBuilder() + GossipManager gossipService = + GossipManagerBuilder.newBuilder() .cluster(cluster) .uri(uri) .id(i + "") @@ -70,20 +68,24 @@ public class TenNodeThreeSeedTest { .build(); gossipService.init(); clients.add(gossipService); - } - TUnit.assertThat(new Callable (){ - 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); - + } + TUnit.assertThat( + new Callable() { + 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(){ + new Thread() { + public void run() { clients.get(j).shutdown(); } }.start(); diff --git a/gossip-protocol-jackson/pom.xml b/gossip-protocol-jackson/pom.xml index 128a26d..56949d6 100644 --- a/gossip-protocol-jackson/pom.xml +++ b/gossip-protocol-jackson/pom.xml @@ -16,36 +16,36 @@ See the License for the specific language governing permissions and limitations under the License. --> - - 4.0.0 + 4.0.0 - - org.apache.gossip - gossip-parent + + org.apache.gossip + gossip-parent + 0.1.3-incubating-SNAPSHOT + ../pom.xml + + + Gossip Jackson Protocol + gossip-protocol-jackson 0.1.3-incubating-SNAPSHOT - ../pom.xml - - Gossip Jackson Protocol - gossip-protocol-jackson - 0.1.3-incubating-SNAPSHOT + + + org.apache.gossip + gossip-base + ${project.version} + + + org.apache.gossip + gossip-base + ${project.version} + test-jar + test + - - - org.apache.gossip - gossip-base - ${project.version} - - - org.apache.gossip - gossip-base - ${project.version} - test-jar - test - - - + diff --git a/gossip-protocol-jackson/src/main/java/org/apache/gossip/protocol/json/JacksonProtocolManager.java b/gossip-protocol-jackson/src/main/java/org/apache/gossip/protocol/json/JacksonProtocolManager.java index 499c5ee..f3dd3f7 100644 --- a/gossip-protocol-jackson/src/main/java/org/apache/gossip/protocol/json/JacksonProtocolManager.java +++ b/gossip-protocol-jackson/src/main/java/org/apache/gossip/protocol/json/JacksonProtocolManager.java @@ -43,25 +43,25 @@ import java.security.spec.PKCS8EncodedKeySpec; // this class is constructed by reflection in GossipManager. public class JacksonProtocolManager implements ProtocolManager { - + private final ObjectMapper objectMapper; private final PrivateKey privKey; private final Meter signed; private final Meter unsigned; - + /** required for reflection to work! */ public JacksonProtocolManager(GossipSettings settings, String id, MetricRegistry registry) { // set up object mapper. objectMapper = buildObjectMapper(settings); - + // set up message signing. - if (settings.isSignMessages()){ + if (settings.isSignMessages()) { File privateKey = new File(settings.getPathToKeyStore(), id); File publicKey = new File(settings.getPathToKeyStore(), id + ".pub"); - if (!privateKey.exists()){ + if (!privateKey.exists()) { throw new IllegalArgumentException("private key not found " + privateKey); } - if (!publicKey.exists()){ + if (!publicKey.exists()) { throw new IllegalArgumentException("public key not found " + publicKey); } try (FileInputStream keyfis = new FileInputStream(privateKey)) { @@ -77,15 +77,39 @@ public class JacksonProtocolManager implements ProtocolManager { } else { privKey = null; } - + signed = registry.meter(PassiveGossipConstants.SIGNED_MESSAGE); unsigned = registry.meter(PassiveGossipConstants.UNSIGNED_MESSAGE); } + public static ObjectMapper buildObjectMapper(GossipSettings settings) { + ObjectMapper om = new ObjectMapper(); + om.enableDefaultTyping(); + // todo: should be specified in the configuration. + om.registerModule(new CrdtModule()); + om.configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, false); + return om; + } + + private static byte[] sign(byte[] bytes, PrivateKey pk) { + Signature dsa; + try { + dsa = Signature.getInstance("SHA1withDSA", "SUN"); + dsa.initSign(pk); + dsa.update(bytes); + return dsa.sign(); + } catch (NoSuchAlgorithmException + | NoSuchProviderException + | InvalidKeyException + | SignatureException e) { + throw new RuntimeException(e); + } + } + @Override public byte[] write(Base message) throws IOException { byte[] json_bytes; - if (privKey == null){ + if (privKey == null) { json_bytes = objectMapper.writeValueAsBytes(message); } else { SignedPayload p = new SignedPayload(); @@ -99,7 +123,7 @@ public class JacksonProtocolManager implements ProtocolManager { @Override public Base read(byte[] buf) throws IOException { Base activeGossipMessage = objectMapper.readValue(buf, Base.class); - if (activeGossipMessage instanceof SignedPayload){ + if (activeGossipMessage instanceof SignedPayload) { SignedPayload s = (SignedPayload) activeGossipMessage; signed.mark(); return objectMapper.readValue(s.getData(), Base.class); @@ -108,25 +132,4 @@ public class JacksonProtocolManager implements ProtocolManager { return activeGossipMessage; } } - - public static ObjectMapper buildObjectMapper(GossipSettings settings) { - ObjectMapper om = new ObjectMapper(); - om.enableDefaultTyping(); - // todo: should be specified in the configuration. - om.registerModule(new CrdtModule()); - om.configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, false); - return om; - } - - private static byte[] sign(byte [] bytes, PrivateKey pk){ - Signature dsa; - try { - dsa = Signature.getInstance("SHA1withDSA", "SUN"); - dsa.initSign(pk); - dsa.update(bytes); - return dsa.sign(); - } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException | SignatureException e) { - throw new RuntimeException(e); - } - } } diff --git a/gossip-protocol-jackson/src/test/java/org/apache/gossip/protocol/json/JacksonTest.java b/gossip-protocol-jackson/src/test/java/org/apache/gossip/protocol/json/JacksonTest.java index 2a5239c..e37df32 100644 --- a/gossip-protocol-jackson/src/test/java/org/apache/gossip/protocol/json/JacksonTest.java +++ b/gossip-protocol-jackson/src/test/java/org/apache/gossip/protocol/json/JacksonTest.java @@ -20,6 +20,12 @@ package org.apache.gossip.protocol.json; import com.codahale.metrics.MetricRegistry; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import org.apache.gossip.GossipSettings; import org.apache.gossip.Member; import org.apache.gossip.crdt.LwwSet; @@ -29,16 +35,10 @@ import org.apache.gossip.crdt.TwoPhaseSet; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManagerBuilder; import org.apache.gossip.protocol.ProtocolManager; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; -import java.io.IOException; -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 static org.junit.jupiter.api.Assertions.*; public class JacksonTest { @@ -56,64 +56,66 @@ public class JacksonTest { } // formerly of SignedMessageTest. - @Test(expected = IllegalArgumentException.class) - public void ifSignMustHaveKeys() - throws URISyntaxException, UnknownHostException, InterruptedException { + @Test() + public void ifSignMustHaveKeys() throws URISyntaxException { String cluster = UUID.randomUUID().toString(); GossipSettings settings = withSigning(simpleSettings(new GossipSettings())); List startupMembers = new ArrayList<>(); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30000 + 1)); - GossipManager gossipService = GossipManagerBuilder.newBuilder() + GossipManager gossipService = + GossipManagerBuilder.newBuilder() .cluster(cluster) .uri(uri) .id(1 + "") .gossipMembers(startupMembers) .gossipSettings(settings) .build(); - gossipService.init(); + assertThrows(IllegalArgumentException.class, gossipService::init); } @Test - public void jacksonSerialTest() throws InterruptedException, URISyntaxException, IOException { - ObjectMapper objectMapper = JacksonProtocolManager.buildObjectMapper(simpleSettings(new GossipSettings())); + public void jacksonSerialTest() throws IOException { + ObjectMapper objectMapper = + JacksonProtocolManager.buildObjectMapper(simpleSettings(new GossipSettings())); OrSet i = new OrSet(new OrSet.Builder().add(1).remove(1)); String s = objectMapper.writeValueAsString(i); @SuppressWarnings("unchecked") OrSet back = objectMapper.readValue(s, OrSet.class); - Assert.assertEquals(back, i); + Assertions.assertEquals(back, i); } - void jacksonCrdtSeDeTest(Object value, Class cl){ - ObjectMapper objectMapper = JacksonProtocolManager.buildObjectMapper(simpleSettings(new GossipSettings())); + void jacksonCrdtSeDeTest(Object value, Class cl) { + ObjectMapper objectMapper = + JacksonProtocolManager.buildObjectMapper(simpleSettings(new GossipSettings())); try { String valueS = objectMapper.writeValueAsString(value); @SuppressWarnings("unchecked") Object parsedValue = objectMapper.readValue(valueS, cl); - Assert.assertEquals(value, parsedValue); + assertEquals(value, parsedValue); } catch (Exception e) { - Assert.fail("Jackson se/de error"); + Assertions.fail("Jackson se/de error"); } } @Test - public void jacksonOrSetTest(){ + public void jacksonOrSetTest() { jacksonCrdtSeDeTest(new OrSet<>("1", "2", "3").remove("2"), OrSet.class); } @Test - public void jacksonLWWSetTest(){ + public void jacksonLWWSetTest() { jacksonCrdtSeDeTest(new LwwSet<>("1", "2", "3").remove("2"), LwwSet.class); } @Test - public void jacksonMaxChangeSetTest(){ + public void jacksonMaxChangeSetTest() { jacksonCrdtSeDeTest(new MaxChangeSet<>("1", "2", "3").remove("2"), MaxChangeSet.class); } @Test - public void jacksonTwoPhaseSetTest(){ + public void jacksonTwoPhaseSetTest() { jacksonCrdtSeDeTest(new TwoPhaseSet<>("1", "2", "3").remove("2"), TwoPhaseSet.class); } @@ -121,30 +123,34 @@ public class JacksonTest { public void testMessageEqualityAssumptions() { long timeA = System.nanoTime(); long timeB = System.nanoTime(); - Assert.assertNotEquals(timeA, timeB); + assertNotEquals(timeA, timeB); TestMessage messageA0 = new TestMessage(Long.toHexString(timeA)); TestMessage messageA1 = new TestMessage(Long.toHexString(timeA)); TestMessage messageB = new TestMessage(Long.toHexString(timeB)); - Assert.assertEquals(messageA0, messageA1); - Assert.assertFalse(messageA0 == messageA1); - Assert.assertNotEquals(messageA0, messageB); - Assert.assertNotEquals(messageA1, messageB); + assertEquals(messageA0, messageA1); + assertNotSame(messageA0, messageA1); + assertNotEquals(messageA0, messageB); + assertNotEquals(messageA1, messageB); } - // ideally, we would test the serializability of every message type, but we just want to make sure this works in + // ideally, we would test the serializability of every message type, but we just want to make sure + // this works in // basic cases. @Test public void testMessageSerializationRoundTrip() throws Exception { - ProtocolManager mgr = new JacksonProtocolManager(simpleSettings(new GossipSettings()), "foo", new MetricRegistry()); + ProtocolManager mgr = + new JacksonProtocolManager( + simpleSettings(new GossipSettings()), "foo", new MetricRegistry()); for (int i = 0; i < 100; i++) { TestMessage a = new TestMessage(Long.toHexString(System.nanoTime())); byte[] bytes = mgr.write(a); TestMessage b = (TestMessage) mgr.read(bytes); - Assert.assertFalse(a == b); - Assert.assertEquals(a, b); - Assert.assertEquals(a.getMapOfThings(), b.getMapOfThings()); // concerned about that one, so explicit check. + assertNotSame(a, b); + assertEquals(a, b); + assertEquals( + a.getMapOfThings(), b.getMapOfThings()); // concerned about that one, so explicit check. } } } diff --git a/gossip-protocol-jackson/src/test/java/org/apache/gossip/protocol/json/TestMessage.java b/gossip-protocol-jackson/src/test/java/org/apache/gossip/protocol/json/TestMessage.java index 7ac211d..5d14268 100644 --- a/gossip-protocol-jackson/src/test/java/org/apache/gossip/protocol/json/TestMessage.java +++ b/gossip-protocol-jackson/src/test/java/org/apache/gossip/protocol/json/TestMessage.java @@ -17,6 +17,8 @@ */ package org.apache.gossip.protocol.json; +import lombok.Data; +import lombok.Getter; import org.apache.gossip.model.Base; import org.apache.gossip.udp.Trackable; @@ -30,6 +32,7 @@ import java.util.Objects; * Note that there are no Jackson annotations. * getters and setters are the keys to making this work without the Jackson annotations. */ +@Data class TestMessage extends Base implements Trackable { private String unique; private String from; @@ -41,9 +44,8 @@ class TestMessage extends Base implements Trackable { private Object[] arrayOfThings; private Map mapOfThings = new HashMap<>(); - @SuppressWarnings("unused")//Used by ObjectMapper - private TestMessage() { - } + @SuppressWarnings("unused") // Used by ObjectMapper + private TestMessage() {} TestMessage(String unique) { this.unique = unique; @@ -53,9 +55,8 @@ class TestMessage extends Base implements Trackable { otherThing = new Subclass(Integer.toHexString(derivedField.hashCode())); floatValue = (float) unique.hashCode() / (float) from.hashCode(); doubleValue = (double) uuid.hashCode() / (double) derivedField.hashCode(); - arrayOfThings = new Object[]{ - this.unique, from, uuid, derivedField, otherThing, floatValue, doubleValue - }; + arrayOfThings = + new Object[] {this.unique, from, uuid, derivedField, otherThing, floatValue, doubleValue}; String curThing = unique; for (int i = 0; i < 100; i++) { @@ -91,18 +92,14 @@ class TestMessage extends Base implements Trackable { if (this == o) return true; if (!(o instanceof TestMessage)) return false; TestMessage that = (TestMessage) o; - return Objects.equals(unique, that.unique) && - Objects.equals(from, that.from) && - Objects.equals(getUuid(), that.getUuid()) && - Objects.equals(derivedField, that.derivedField) && - Objects.equals(floatValue, that.floatValue) && - Objects.equals(doubleValue, that.doubleValue) && - Arrays.equals(arrayOfThings, that.arrayOfThings) && - Objects.equals(mapOfThings, that.mapOfThings); - } - - public String getUnique() { - return unique; + return Objects.equals(unique, that.unique) + && Objects.equals(from, that.from) + && Objects.equals(getUuid(), that.getUuid()) + && Objects.equals(derivedField, that.derivedField) + && Objects.equals(floatValue, that.floatValue) + && Objects.equals(doubleValue, that.doubleValue) + && Arrays.equals(arrayOfThings, that.arrayOfThings) + && Objects.equals(mapOfThings, that.mapOfThings); } public void setUnique(String unique) { @@ -167,14 +164,21 @@ class TestMessage extends Base implements Trackable { @Override public int hashCode() { - return Objects.hash(unique, getUriFrom(), getUuid(), derivedField, floatValue, doubleValue, arrayOfThings, mapOfThings); + return Objects.hash( + unique, + getUriFrom(), + getUuid(), + derivedField, + floatValue, + doubleValue, + arrayOfThings, + mapOfThings); } static class Subclass { private String thing; - public Subclass() { - } + public Subclass() {} public Subclass(String thing) { this.thing = thing; @@ -197,4 +201,4 @@ class TestMessage extends Base implements Trackable { return thing; } } -} \ No newline at end of file +} diff --git a/gossip-transport-udp/pom.xml b/gossip-transport-udp/pom.xml index 446aace..77e729f 100644 --- a/gossip-transport-udp/pom.xml +++ b/gossip-transport-udp/pom.xml @@ -16,28 +16,28 @@ See the License for the specific language governing permissions and limitations under the License. --> - - 4.0.0 + 4.0.0 - - org.apache.gossip - gossip-parent + + org.apache.gossip + gossip-parent + 0.1.3-incubating-SNAPSHOT + ../pom.xml + + + Gossip UDP Transport + gossip-transport-udp 0.1.3-incubating-SNAPSHOT - ../pom.xml - - - Gossip UDP Transport - gossip-transport-udp - 0.1.3-incubating-SNAPSHOT - - - - org.apache.gossip - gossip-base - ${project.version} - - - + + + + org.apache.gossip + gossip-base + ${project.version} + + + diff --git a/gossip-transport-udp/src/main/java/org/apache/gossip/transport/udp/UdpTransportManager.java b/gossip-transport-udp/src/main/java/org/apache/gossip/transport/udp/UdpTransportManager.java index d6aaa15..306ffb1 100644 --- a/gossip-transport-udp/src/main/java/org/apache/gossip/transport/udp/UdpTransportManager.java +++ b/gossip-transport-udp/src/main/java/org/apache/gossip/transport/udp/UdpTransportManager.java @@ -17,11 +17,11 @@ */ package org.apache.gossip.transport.udp; +import lombok.extern.slf4j.Slf4j; import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipManager; import org.apache.gossip.model.Base; import org.apache.gossip.transport.AbstractTransportManager; -import org.apache.log4j.Logger; import java.io.IOException; import java.net.DatagramPacket; @@ -34,32 +34,33 @@ import java.net.URI; import java.util.concurrent.atomic.AtomicBoolean; /** - * This class is constructed by reflection in GossipManager. - * It manages transport (byte read/write) operations over UDP. + * This class is constructed by reflection in GossipManager. It manages transport (byte read/write) + * operations over UDP. */ +@Slf4j public class UdpTransportManager extends AbstractTransportManager implements Runnable { - - public static final Logger LOGGER = Logger.getLogger(UdpTransportManager.class); - + /** The socket used for the passive thread of the gossip service. */ private final DatagramSocket server; - + private final int soTimeout; - + private final Thread me; - + private final AtomicBoolean keepRunning = new AtomicBoolean(true); - + /** required for reflection to work! */ public UdpTransportManager(GossipManager gossipManager, GossipCore gossipCore) { super(gossipManager, gossipCore); soTimeout = gossipManager.getSettings().getGossipInterval() * 2; try { - SocketAddress socketAddress = new InetSocketAddress(gossipManager.getMyself().getUri().getHost(), + SocketAddress socketAddress = + new InetSocketAddress( + gossipManager.getMyself().getUri().getHost(), gossipManager.getMyself().getUri().getPort()); server = new DatagramSocket(socketAddress); } catch (SocketException ex) { - LOGGER.warn(ex); + log.warn("Warn!", ex); throw new RuntimeException(ex); } me = new Thread(this); @@ -73,21 +74,21 @@ public class UdpTransportManager extends AbstractTransportManager implements Run try { Base message = gossipManager.getProtocolManager().read(buf); gossipCore.receive(message); - //TODO this is suspect + // TODO this is suspect gossipManager.getMemberStateRefresher().run(); - } catch (RuntimeException ex) {//TODO trap json exception - LOGGER.error("Unable to process message", ex); + } catch (RuntimeException ex) { // TODO trap json exception + log.error("Unable to process message", ex); } } catch (IOException e) { // InterruptedException are completely normal here because of the blocking lifecycle. if (!(e.getCause() instanceof InterruptedException)) { - LOGGER.error(e); + log.error("Error", e); } keepRunning.set(false); } } } - + @Override public void shutdown() { keepRunning.set(false); @@ -98,6 +99,7 @@ public class UdpTransportManager extends AbstractTransportManager implements Run /** * blocking read a message. + * * @return buffer of message contents. * @throws IOException */ @@ -111,25 +113,22 @@ public class UdpTransportManager extends AbstractTransportManager implements Run @Override public void send(URI endpoint, byte[] buf) throws IOException { - // todo: investigate UDP socket reuse. It would save a little setup/teardown time wrt to the local socket. - try (DatagramSocket socket = new DatagramSocket()){ + // todo: investigate UDP socket reuse. It would save a little setup/teardown time wrt to the + // local socket. + try (DatagramSocket socket = new DatagramSocket()) { socket.setSoTimeout(soTimeout); InetAddress dest = InetAddress.getByName(endpoint.getHost()); DatagramPacket payload = new DatagramPacket(buf, buf.length, dest, endpoint.getPort()); socket.send(payload); } } - + private void debug(byte[] jsonBytes) { - if (LOGGER.isDebugEnabled()){ - String receivedMessage = new String(jsonBytes); - LOGGER.debug("Received message ( bytes): " + receivedMessage); - } + log.debug("Received message ( bytes): {}", jsonBytes); } @Override public void startEndpoint() { me.start(); } - } diff --git a/gossip-transport-udp/src/test/java/org/apache/gossip/transport/udp/UdpTransportIntegrationTest.java b/gossip-transport-udp/src/test/java/org/apache/gossip/transport/udp/UdpTransportIntegrationTest.java index 8a27d0a..cb153c7 100644 --- a/gossip-transport-udp/src/test/java/org/apache/gossip/transport/udp/UdpTransportIntegrationTest.java +++ b/gossip-transport-udp/src/test/java/org/apache/gossip/transport/udp/UdpTransportIntegrationTest.java @@ -21,40 +21,39 @@ import org.junit.Ignore; import org.junit.Test; public class UdpTransportIntegrationTest { - + // It's currently impossible to create a UdpTransportManager without bringing up an entire stack. - // This is because AbstractTransportManager creates a PassiveGossipThread (requires GossipManager, - // GossipCore) and also requires those same things plus a MetricsRegistry to create the + // This is because AbstractTransportManager creates a PassiveGossipThread (requires GossipManager, + // GossipCore) and also requires those same things plus a MetricsRegistry to create the // ActiveGossiper. // TODO: test UDPTransportManger semantics (read and write) in isolation. // I've written this test to indicate the direction I want things to go. // Uncomment/Fix it once the coupling issues are worked out. - @Test @Ignore + @Test + @Ignore public void testRoundTrip() { /* GossipSettings settings0 = new GossipSettings(); GossipSettings settings1 = new GossipSettings(); UdpTransportManager mgr0 = new UdpTransportManager(settings0); UdpTransportManager mgr1 = new UdpTransportManager(settings1); - + mgr0.startEndpoint(); mgr1.startEndpoint(); mgr0.startActiveGossiper(); mgr1.startActiveGossiper(); - + // wait a little while for convergence // perhaps there is a Mockito Whitebox way to foce members - + byte[] data = new byte[] {0,1,2,3,4,5}; Future someData = asyncWaitForData(mgr1); mgr0.send(toURI(settings1), data); Assert.assertEquals(data, someData.get(1000, TimeUnit.MILLISECONDS)); - + mgr0.shutdown(); mgr1.shutdown(); */ } - - } diff --git a/pom.xml b/pom.xml index 75a54a4..ce5e942 100644 --- a/pom.xml +++ b/pom.xml @@ -16,297 +16,299 @@ See the License for the specific language governing permissions and limitations under the License. --> - - 4.0.0 - - - UTF-8 - 1.8 - - - 2.8.5 - 3.1.2 - 1.2 - 5.0.0-M2 - 1.0.0-M2 - 4.12.0-M2 - 1.2.17 - 0.0.0 - 2.8.9 + + 4.0.0 - - 3.5.1 - 2.10 - 3.0.0 - 1.6 - 2.10 - - - - org.apache - apache - RELEASE - - - Gossip Parent - org.apache.gossip - gossip-parent - 0.1.3-incubating-SNAPSHOT - - pom - - - gossip-base - gossip-transport-udp - gossip-protocol-jackson - gossip-itest - gossip-examples - - - A peer to peer cluster discovery service - http://gossip.incubator.apache.org/ + + UTF-8 + 21 - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - scm:git:git@github.com:apache/incubator-gossip.git - scm:git:https://git-wip-us.apache.org/repos/asf/incubator-gossip.git - scm:git:git@github.com:apache/incubator-gossip.git - HEAD - - - - JIRA - https://issues.apache.org/jira/browse/GOSSIP - - - - - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.version} - test - - - org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.version} - test - - - org.junit.vintage - junit-vintage-engine - ${junit.vintage.version} - test - - - org.junit.platform - junit-platform-runner - ${junit.platform.version} - test - - - io.teknek - tunit - ${tunit.version} - test - - - org.mockito - mockito-core - ${mockito.version} - test - - - - - - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.1 - - false - true - true + + 2.16.0 + 4.2.17 + 4.0-beta1 + 5.9.2 + 1.3.2 + 2.22.0 + 0.0.0 + 5.7.0 - distribution - clean install - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven-jar-plugin.version} - - - - - - test-jar - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - true - - - - org.apache.maven.plugins - maven-dependency-plugin - ${maven-dependency-plugin.version} - - - - - - maven-compiler-plugin - 3.1 - - ${java.version} - ${java.version} - - - - maven-surefire-plugin - 2.19.1 - - - ${project.build.directory} - - - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - - - - - org.apache.rat - apache-rat-plugin - - - **/README.md - eclipse_template.xml - - **/*.mycluster.*.json - - **/*.log - - - - - verify - - check - - - - - - - - - - central - Maven Repository - https://repo1.maven.org/maven2 - - true - - - false - - - - - - - central - https://repo1.maven.org/maven2 - - true - - - false - - - - - - - ecapriolo - Edward Capriolo - edlinuxguru@gmail.com - https://github.com/edwardcapriolo - Apache Software Foundation - http://gossip.incubator.apache.org/ - - developer - - -6 - - - - - - Dev Mailing List - dev@gossip.incubator.apache.org - dev-subscribe@gossip.incubator.apache.org - dev-unsubscribe@gossip.incubator.apache.org - - - Commits Mailing List - commits@gossip.incubator.apache.org - commits-subscribe@gossip.incubator.apache.org - commits-unsubscribe@gossip.incubator.apache.org - - - - - - release-sign-artifacts - - - performRelease - true - - - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven-gpg-plugin.version} - - - sign-artifacts - verify - - sign - - - - - - - - + + 2.10 + 3.0.0 + 1.6 + 2.10 + + + + org.apache + apache + 31 + + + Gossip Parent + org.apache.gossip + gossip-parent + 0.1.3-incubating-SNAPSHOT + + pom + + + gossip-base + gossip-transport-udp + gossip-protocol-jackson + gossip-itest + gossip-examples + + + A peer to peer cluster discovery service + http://gossip.incubator.apache.org/ + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + scm:git:git@github.com:apache/incubator-gossip.git + scm:git:https://git-wip-us.apache.org/repos/asf/incubator-gossip.git + scm:git:git@github.com:apache/incubator-gossip.git + HEAD + + + + JIRA + https://issues.apache.org/jira/browse/GOSSIP + + + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + org.junit.platform + junit-platform-runner + 1.9.2 + test + + + io.teknek + tunit + ${tunit.version} + test + + + org.mockito + mockito-core + 5.4.0 + test + + + org.projectlombok + lombok + 1.18.30 + provided + + + + + org.slf4j + slf4j-reload4j + 2.0.9 + test + + + + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 3.0.1 + + false + true + true + + distribution + clean install + + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + + + + test-jar + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + ${java.version} + ${java.version} + true + + + + org.apache.maven.plugins + maven-dependency-plugin + ${maven-dependency-plugin.version} + + + + + + maven-compiler-plugin + 3.10.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.2 + + false + true + + + + org.apache.rat + apache-rat-plugin + + + **/README.md + eclipse_template.xml + + **/*.mycluster.*.json + + **/*.log + + + + + + + + + + + + central + Maven Repository + https://repo1.maven.org/maven2 + + true + + + false + + + + + + + central + https://repo1.maven.org/maven2 + + true + + + false + + + + + + + ecapriolo + Edward Capriolo + edlinuxguru@gmail.com + https://github.com/edwardcapriolo + Apache Software Foundation + http://gossip.incubator.apache.org/ + + developer + + -6 + + + + + + Dev Mailing List + dev@gossip.incubator.apache.org + dev-subscribe@gossip.incubator.apache.org + dev-unsubscribe@gossip.incubator.apache.org + + + Commits Mailing List + commits@gossip.incubator.apache.org + commits-subscribe@gossip.incubator.apache.org + commits-unsubscribe@gossip.incubator.apache.org + + + + + + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.1.0 + + + sign-artifacts + verify + + sign + + + + + + + +