GOSSIP-46 Refactor away GossipService cleaner better class names

This commit is contained in:
Edward Capriolo
2017-03-05 15:44:54 -05:00
parent d5fe9f96c8
commit 5199821980
47 changed files with 547 additions and 696 deletions

View File

@ -1,135 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.gossip;
import com.codahale.metrics.MetricRegistry;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.codahale.metrics.JmxReporter;
import org.apache.gossip.event.GossipListener;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.random.RandomGossipManager;
import org.apache.gossip.model.GossipDataMessage;
import org.apache.gossip.model.SharedGossipDataMessage;
import org.apache.log4j.Logger;
/**
* This object represents the service which is responsible for gossiping with other gossip members.
*
*/
public class GossipService {
public static final Logger LOGGER = Logger.getLogger(GossipService.class);
private final JmxReporter jmxReporter;
private final GossipManager gossipManager;
/**
* Constructor with the default settings.
*
* @throws InterruptedException
* @throws UnknownHostException
*/
public GossipService(StartupSettings startupSettings) throws InterruptedException,
UnknownHostException {
this(startupSettings.getCluster(), startupSettings.getUri()
, startupSettings.getId(), new HashMap<String,String> (),startupSettings.getGossipMembers(),
startupSettings.getGossipSettings(), null, new MetricRegistry());
}
/**
* Setup the client's lists, gossiping parameters, and parse the startup config file.
*
* @throws InterruptedException
* @throws UnknownHostException
*/
public GossipService(String cluster, URI uri, String id, Map<String,String> properties,
List<GossipMember> gossipMembers, GossipSettings settings, GossipListener listener, MetricRegistry registry)
throws InterruptedException, UnknownHostException {
jmxReporter = JmxReporter.forRegistry(registry).build();
jmxReporter.start();
gossipManager = RandomGossipManager.newBuilder()
.withId(id)
.cluster(cluster)
.uri(uri)
.settings(settings)
.gossipMembers(gossipMembers)
.listener(listener)
.registry(registry)
.properties(properties)
.build();
}
public void start() {
gossipManager.init();
}
public void shutdown() {
gossipManager.shutdown();
}
public GossipManager getGossipManager() {
return gossipManager;
}
/**
* Gossip data in a namespace that is per-node { node-id { key, value } }
* @param message
* message to be gossip'ed across the cluster
*/
public void gossipPerNodeData(GossipDataMessage message){
gossipManager.gossipPerNodeData(message);
}
/**
* Retrieve per-node gossip data by key
*
* @param nodeId
* the id of the node that owns the data
* @param key
* the key in the per-node map to find the data
* @return the value if found or null if not found or expired
*/
public GossipDataMessage findPerNodeData(String nodeId, String key){
return getGossipManager().findPerNodeGossipData(nodeId, key);
}
/**
*
* @param message
* Shared data to gossip around the cluster
*/
public void gossipSharedData(SharedGossipDataMessage message){
gossipManager.gossipSharedData(message);
}
/**
*
* @param key
* the key to search for
* @return the value associated with given key
*/
public SharedGossipDataMessage findSharedData(String key){
return getGossipManager().findSharedGossipData(key);
}
}

View File

@ -27,7 +27,7 @@ import org.apache.gossip.accrual.FailureDetector;
* in the local list of gossip members. * in the local list of gossip members.
* *
*/ */
public class LocalGossipMember extends GossipMember { public class LocalMember extends Member {
/** The failure detector for this member */ /** The failure detector for this member */
private transient FailureDetector detector; private transient FailureDetector detector;
@ -40,13 +40,13 @@ public class LocalGossipMember extends GossipMember {
* @param heartbeat * @param heartbeat
* The current heartbeat * The current heartbeat
*/ */
public LocalGossipMember(String clusterName, URI uri, String id, public LocalMember(String clusterName, URI uri, String id,
long heartbeat, Map<String,String> properties, int windowSize, int minSamples, String distribution) { long heartbeat, Map<String,String> properties, int windowSize, int minSamples, String distribution) {
super(clusterName, uri, id, heartbeat, properties ); super(clusterName, uri, id, heartbeat, properties );
detector = new FailureDetector(this, minSamples, windowSize, distribution); detector = new FailureDetector(this, minSamples, windowSize, distribution);
} }
protected LocalGossipMember(){ protected LocalMember(){
} }

View File

@ -25,7 +25,7 @@ import java.util.Map;
* A abstract class representing a gossip member. * A abstract class representing a gossip member.
* *
*/ */
public abstract class GossipMember implements Comparable<GossipMember> { public abstract class Member implements Comparable<Member> {
protected URI uri; protected URI uri;
@ -56,7 +56,7 @@ public abstract class GossipMember implements Comparable<GossipMember> {
* @param id * @param id
* An id that may be replaced after contact * An id that may be replaced after contact
*/ */
public GossipMember(String clusterName, URI uri, String id, long heartbeat, Map<String,String> properties) { public Member(String clusterName, URI uri, String id, long heartbeat, Map<String,String> properties) {
this.clusterName = clusterName; this.clusterName = clusterName;
this.id = id; this.id = id;
this.heartbeat = heartbeat; this.heartbeat = heartbeat;
@ -64,7 +64,7 @@ public abstract class GossipMember implements Comparable<GossipMember> {
this.properties = properties; this.properties = properties;
} }
protected GossipMember(){} protected Member(){}
/** /**
* Get the name of the cluster the member belongs to. * Get the name of the cluster the member belongs to.
* *
@ -151,16 +151,16 @@ public abstract class GossipMember implements Comparable<GossipMember> {
System.err.println("equals(): obj is null."); System.err.println("equals(): obj is null.");
return false; return false;
} }
if (!(obj instanceof GossipMember)) { if (!(obj instanceof Member)) {
System.err.println("equals(): obj is not of type GossipMember."); System.err.println("equals(): obj is not of type GossipMember.");
return false; return false;
} }
// The object is the same of they both have the same address (hostname and port). // The object is the same of they both have the same address (hostname and port).
return computeAddress().equals(((LocalGossipMember) obj).computeAddress()) return computeAddress().equals(((LocalMember) obj).computeAddress())
&& getClusterName().equals(((LocalGossipMember) obj).getClusterName()); && getClusterName().equals(((LocalMember) obj).getClusterName());
} }
public int compareTo(GossipMember other) { public int compareTo(Member other) {
return this.computeAddress().compareTo(other.computeAddress()); return this.computeAddress().compareTo(other.computeAddress());
} }
} }

View File

@ -26,7 +26,7 @@ import java.util.Map;
* member. * member.
* *
*/ */
public class RemoteGossipMember extends GossipMember { public class RemoteMember extends Member {
/** /**
* Constructor. * Constructor.
@ -36,11 +36,11 @@ public class RemoteGossipMember extends GossipMember {
* @param heartbeat * @param heartbeat
* The current heartbeat * The current heartbeat
*/ */
public RemoteGossipMember(String clusterName, URI uri, String id, long heartbeat, Map<String,String> properties) { public RemoteMember(String clusterName, URI uri, String id, long heartbeat, Map<String,String> properties) {
super(clusterName, uri, id, heartbeat, properties); super(clusterName, uri, id, heartbeat, properties);
} }
public RemoteGossipMember(String clusterName, URI uri, String id) { public RemoteMember(String clusterName, URI uri, String id) {
super(clusterName, uri, id, System.nanoTime(), new HashMap<String,String>()); super(clusterName, uri, id, System.nanoTime(), new HashMap<String,String>());
} }

View File

@ -53,7 +53,7 @@ public class StartupSettings {
private final GossipSettings gossipSettings; private final GossipSettings gossipSettings;
/** The list with gossip members to start with. */ /** The list with gossip members to start with. */
private final List<GossipMember> gossipMembers; private final List<Member> gossipMembers;
/** /**
* Constructor. * Constructor.
@ -135,7 +135,7 @@ public class StartupSettings {
* @param member * @param member
* The member to add. * The member to add.
*/ */
public void addGossipMember(GossipMember member) { public void addGossipMember(Member member) {
gossipMembers.add(member); gossipMembers.add(member);
} }
@ -144,7 +144,7 @@ public class StartupSettings {
* *
* @return The gossip members. * @return The gossip members.
*/ */
public List<GossipMember> getGossipMembers() { public List<Member> getGossipMembers() {
return gossipMembers; return gossipMembers;
} }
@ -195,7 +195,7 @@ public class StartupSettings {
while (it.hasNext()){ while (it.hasNext()){
JsonNode child = it.next(); JsonNode child = it.next();
URI uri3 = new URI(child.get("uri").textValue()); URI uri3 = new URI(child.get("uri").textValue());
RemoteGossipMember member = new RemoteGossipMember(child.get("cluster").asText(), RemoteMember member = new RemoteMember(child.get("cluster").asText(),
uri3, "", 0, new HashMap<String,String>()); uri3, "", 0, new HashMap<String,String>());
settings.addGossipMember(member); settings.addGossipMember(member);
configMembersDetails += member.computeAddress(); configMembersDetails += member.computeAddress();

View File

@ -21,7 +21,7 @@ import org.apache.commons.math.MathException;
import org.apache.commons.math.distribution.ExponentialDistributionImpl; import org.apache.commons.math.distribution.ExponentialDistributionImpl;
import org.apache.commons.math.distribution.NormalDistributionImpl; import org.apache.commons.math.distribution.NormalDistributionImpl;
import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
public class FailureDetector { public class FailureDetector {
@ -30,10 +30,10 @@ public class FailureDetector {
private final DescriptiveStatistics descriptiveStatistics; private final DescriptiveStatistics descriptiveStatistics;
private final long minimumSamples; private final long minimumSamples;
private volatile long latestHeartbeatMs = -1; private volatile long latestHeartbeatMs = -1;
private final LocalGossipMember parent; private final LocalMember parent;
private final String distribution; private final String distribution;
public FailureDetector(LocalGossipMember parent, long minimumSamples, int windowSize, String distribution){ public FailureDetector(LocalMember parent, long minimumSamples, int windowSize, String distribution){
this.parent = parent; this.parent = parent;
descriptiveStatistics = new DescriptiveStatistics(windowSize); descriptiveStatistics = new DescriptiveStatistics(windowSize);
this.minimumSamples = minimumSamples; this.minimumSamples = minimumSamples;

View File

@ -17,8 +17,8 @@
*/ */
package org.apache.gossip.event; package org.apache.gossip.event;
import org.apache.gossip.GossipMember; import org.apache.gossip.Member;
public interface GossipListener { public interface GossipListener {
void gossipEvent(GossipMember member, GossipState state); void gossipEvent(Member member, GossipState state);
} }

View File

@ -1,105 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.gossip.examples;
import com.codahale.metrics.MetricRegistry;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.gossip.GossipMember;
import org.apache.gossip.GossipService;
import org.apache.gossip.GossipSettings;
import org.apache.gossip.RemoteGossipMember;
/**
* This class is an example of how one could use the gossip service. Here we start multiple gossip
* clients on this host as specified in the config file.
*
* @author harmenw
*/
public class GossipExample extends Thread {
/** The number of clients to start. */
private static final int NUMBER_OF_CLIENTS = 4;
/**
* @param args
*/
public static void main(String[] args) {
new GossipExample();
}
/**
* Constructor. This will start the this thread.
*/
public GossipExample() {
start();
}
/**
* @see java.lang.Thread#run()
*/
public void run() {
try {
GossipSettings settings = new GossipSettings();
List<GossipService> clients = new ArrayList<>();
String myIpAddress = InetAddress.getLocalHost().getHostAddress();
String cluster = "My Gossip Cluster";
// Create the gossip members and put them in a list and give them a port number starting with
// 2000.
List<GossipMember> startupMembers = new ArrayList<>();
for (int i = 0; i < NUMBER_OF_CLIENTS; ++i) {
URI u;
try {
u = new URI("udp://" + myIpAddress + ":" + (2000 + i));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
startupMembers.add(new RemoteGossipMember(cluster, u, "", 0, new HashMap<String,String>()));
}
// Lets start the gossip clients.
// Start the clients, waiting cleaning-interval + 1 second between them which will show the
// dead list handling.
for (GossipMember member : startupMembers) {
GossipService gossipService = new GossipService(cluster, member.getUri(), "", new HashMap<String,String>(),
startupMembers, settings, null, new MetricRegistry());
clients.add(gossipService);
gossipService.start();
sleep(settings.getCleanupInterval() + 1000);
}
// After starting all gossip clients, first wait 10 seconds and then shut them down.
sleep(10000);
System.err.println("Going to shutdown all services...");
// Since they all run in the same virtual machine and share the same executor, if one is
// shutdown they will all stop.
clients.get(0).shutdown();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -24,12 +24,11 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.gossip.GossipService;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.RemoteGossipMember; import org.apache.gossip.RemoteMember;
import org.apache.gossip.manager.DatacenterRackAwareActiveGossiper; import org.apache.gossip.manager.DatacenterRackAwareActiveGossiper;
import org.apache.gossip.manager.GossipManager;
import com.codahale.metrics.MetricRegistry; import org.apache.gossip.manager.GossipManagerBuilder;
public class StandAloneDatacenterAndRack { public class StandAloneDatacenterAndRack {
@ -43,18 +42,21 @@ public class StandAloneDatacenterAndRack {
gossipProps.put("sameRackGossipIntervalMs", "2000"); gossipProps.put("sameRackGossipIntervalMs", "2000");
gossipProps.put("differentDatacenterGossipIntervalMs", "10000"); gossipProps.put("differentDatacenterGossipIntervalMs", "10000");
s.setActiveGossipProperties(gossipProps); s.setActiveGossipProperties(gossipProps);
Map<String, String> props = new HashMap<>(); Map<String, String> props = new HashMap<>();
props.put(DatacenterRackAwareActiveGossiper.DATACENTER, args[4]); props.put(DatacenterRackAwareActiveGossiper.DATACENTER, args[4]);
props.put(DatacenterRackAwareActiveGossiper.RACK, args[5]); props.put(DatacenterRackAwareActiveGossiper.RACK, args[5]);
GossipService gossipService = new GossipService("mycluster", URI.create(args[0]), args[1], GossipManager manager = GossipManagerBuilder.newBuilder()
props, Arrays.asList(new RemoteGossipMember("mycluster", URI.create(args[2]), args[3])), .cluster("mycluster")
s, (a, b) -> { }, new MetricRegistry()); .uri(URI.create(args[0]))
gossipService.start(); .id(args[1])
.gossipSettings(s)
.gossipMembers(Arrays.asList(new RemoteMember("mycluster", URI.create(args[2]), args[3])))
.properties(props)
.build();
manager.init();
while (true){ while (true){
System.out.println("Live: " + gossipService.getGossipManager().getLiveMembers()); System.out.println("Live: " + manager.getLiveMembers());
System.out.println("Dead: " + gossipService.getGossipManager().getDeadMembers()); System.out.println("Dead: " + manager.getDeadMembers());
Thread.sleep(2000); Thread.sleep(2000);
} }
} }

View File

@ -17,15 +17,13 @@
*/ */
package org.apache.gossip.examples; package org.apache.gossip.examples;
import com.codahale.metrics.MetricRegistry;
import java.net.URI; import java.net.URI;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import org.apache.gossip.GossipService;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.RemoteGossipMember; import org.apache.gossip.RemoteMember;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
public class StandAloneNode { public class StandAloneNode {
public static void main (String [] args) throws UnknownHostException, InterruptedException{ public static void main (String [] args) throws UnknownHostException, InterruptedException{
@ -33,12 +31,17 @@ public class StandAloneNode {
s.setWindowSize(10); s.setWindowSize(10);
s.setConvictThreshold(1.0); s.setConvictThreshold(1.0);
s.setGossipInterval(10); s.setGossipInterval(10);
GossipService gossipService = new GossipService("mycluster", URI.create(args[0]), args[1], new HashMap<String, String>(), GossipManager gossipService = GossipManagerBuilder.newBuilder()
Arrays.asList( new RemoteGossipMember("mycluster", URI.create(args[2]), args[3])), s, (a,b) -> {}, new MetricRegistry()); .cluster("mycluster")
gossipService.start(); .uri(URI.create(args[0]))
.id(args[1])
.gossipMembers(Arrays.asList( new RemoteMember("mycluster", URI.create(args[2]), args[3])))
.gossipSettings(s)
.build();
gossipService.init();
while (true){ while (true){
System.out.println( "Live: " + gossipService.getGossipManager().getLiveMembers()); System.out.println("Live: " + gossipService.getLiveMembers());
System.out.println( "Dead: " + gossipService.getGossipManager().getDeadMembers()); System.out.println("Dead: " + gossipService.getDeadMembers());
Thread.sleep(2000); Thread.sleep(2000);
} }
} }

View File

@ -17,20 +17,17 @@
*/ */
package org.apache.gossip.examples; package org.apache.gossip.examples;
import com.codahale.metrics.MetricRegistry;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URI; import java.net.URI;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import org.apache.gossip.GossipService;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.RemoteGossipMember; import org.apache.gossip.RemoteMember;
import org.apache.gossip.crdt.OrSet; import org.apache.gossip.crdt.OrSet;
import org.apache.gossip.model.SharedGossipDataMessage; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
import org.apache.gossip.model.SharedDataMessage;
public class StandAloneNodeCrdtOrSet { public class StandAloneNodeCrdtOrSet {
public static void main (String [] args) throws InterruptedException, IOException{ public static void main (String [] args) throws InterruptedException, IOException{
@ -38,17 +35,22 @@ public class StandAloneNodeCrdtOrSet {
s.setWindowSize(10); s.setWindowSize(10);
s.setConvictThreshold(1.0); s.setConvictThreshold(1.0);
s.setGossipInterval(10); s.setGossipInterval(10);
GossipService gossipService = new GossipService("mycluster", URI.create(args[0]), args[1], new HashMap<String, String>(), GossipManager gossipService = GossipManagerBuilder.newBuilder()
Arrays.asList( new RemoteGossipMember("mycluster", URI.create(args[2]), args[3])), s, (a,b) -> {}, new MetricRegistry()); .cluster("mycluster")
gossipService.start(); .uri(URI.create(args[0]))
.id(args[1])
.gossipMembers(Arrays.asList( new RemoteMember("mycluster", URI.create(args[2]), args[3])))
.gossipSettings(s)
.build();
gossipService.init();
new Thread(() -> { new Thread(() -> {
while (true){ while (true){
System.out.println("Live: " + gossipService.getGossipManager().getLiveMembers()); System.out.println("Live: " + gossipService.getLiveMembers());
System.out.println("Dead: " + gossipService.getGossipManager().getDeadMembers()); System.out.println("Dead: " + gossipService.getDeadMembers());
System.out.println("---------- " + (gossipService.getGossipManager().findCrdt("abc") == null ? "": System.out.println("---------- " + (gossipService.findCrdt("abc") == null ? "":
gossipService.getGossipManager().findCrdt("abc").value())); gossipService.findCrdt("abc").value()));
System.out.println("********** " + gossipService.getGossipManager().findCrdt("abc")); System.out.println("********** " + gossipService.findCrdt("abc"));
try { try {
Thread.sleep(2000); Thread.sleep(2000);
} catch (Exception e) {} } catch (Exception e) {}
@ -70,22 +72,23 @@ public class StandAloneNodeCrdtOrSet {
} }
} }
private static void removeData(String val, GossipService gossipService){ private static void removeData(String val, GossipManager gossipService){
OrSet<String> s = (OrSet<String>) gossipService.getGossipManager().findCrdt("abc"); @SuppressWarnings("unchecked")
SharedGossipDataMessage m = new SharedGossipDataMessage(); OrSet<String> s = (OrSet<String>) gossipService.findCrdt("abc");
SharedDataMessage m = new SharedDataMessage();
m.setExpireAt(Long.MAX_VALUE); m.setExpireAt(Long.MAX_VALUE);
m.setKey("abc"); m.setKey("abc");
m.setPayload(new OrSet<String>(s , new OrSet.Builder<String>().remove(val))); m.setPayload(new OrSet<String>(s , new OrSet.Builder<String>().remove(val)));
m.setTimestamp(System.currentTimeMillis()); m.setTimestamp(System.currentTimeMillis());
gossipService.getGossipManager().merge(m); gossipService.merge(m);
} }
private static void addData(String val, GossipService gossipService){ private static void addData(String val, GossipManager gossipService){
SharedGossipDataMessage m = new SharedGossipDataMessage(); SharedDataMessage m = new SharedDataMessage();
m.setExpireAt(Long.MAX_VALUE); m.setExpireAt(Long.MAX_VALUE);
m.setKey("abc"); m.setKey("abc");
m.setPayload(new OrSet<String>(val)); m.setPayload(new OrSet<String>(val));
m.setTimestamp(System.currentTimeMillis()); m.setTimestamp(System.currentTimeMillis());
gossipService.getGossipManager().merge(m); gossipService.merge(m);
} }
} }

View File

@ -24,16 +24,16 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.codahale.metrics.Histogram; import com.codahale.metrics.Histogram;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.model.ActiveGossipOk; import org.apache.gossip.model.ActiveGossipOk;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.GossipMember; import org.apache.gossip.model.Member;
import org.apache.gossip.model.Response; import org.apache.gossip.model.Response;
import org.apache.gossip.model.SharedGossipDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.apache.gossip.model.ShutdownMessage; import org.apache.gossip.model.ShutdownMessage;
import org.apache.gossip.udp.UdpActiveGossipMessage; import org.apache.gossip.udp.UdpActiveGossipMessage;
import org.apache.gossip.udp.UdpGossipDataMessage; import org.apache.gossip.udp.UdpPerNodeDataMessage;
import org.apache.gossip.udp.UdpSharedGossipDataMessage; import org.apache.gossip.udp.UdpSharedDataMessage;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import static com.codahale.metrics.MetricRegistry.name; import static com.codahale.metrics.MetricRegistry.name;
@ -69,7 +69,7 @@ public abstract class AbstractActiveGossiper {
} }
public final void sendShutdownMessage(LocalGossipMember me, LocalGossipMember target){ public final void sendShutdownMessage(LocalMember me, LocalMember target){
if (target == null){ if (target == null){
return; return;
} }
@ -79,13 +79,13 @@ public abstract class AbstractActiveGossiper {
gossipCore.sendOneWay(m, target.getUri()); gossipCore.sendOneWay(m, target.getUri());
} }
public final void sendSharedData(LocalGossipMember me, LocalGossipMember member){ public final void sendSharedData(LocalMember me, LocalMember member){
if (member == null){ if (member == null){
return; return;
} }
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
for (Entry<String, SharedGossipDataMessage> innerEntry : gossipCore.getSharedData().entrySet()){ for (Entry<String, SharedDataMessage> innerEntry : gossipCore.getSharedData().entrySet()){
UdpSharedGossipDataMessage message = new UdpSharedGossipDataMessage(); UdpSharedDataMessage message = new UdpSharedDataMessage();
message.setUuid(UUID.randomUUID().toString()); message.setUuid(UUID.randomUUID().toString());
message.setUriFrom(me.getId()); message.setUriFrom(me.getId());
message.setExpireAt(innerEntry.getValue().getExpireAt()); message.setExpireAt(innerEntry.getValue().getExpireAt());
@ -98,14 +98,14 @@ public abstract class AbstractActiveGossiper {
sharedDataHistogram.update(System.currentTimeMillis() - startTime); sharedDataHistogram.update(System.currentTimeMillis() - startTime);
} }
public final void sendPerNodeData(LocalGossipMember me, LocalGossipMember member){ public final void sendPerNodeData(LocalMember me, LocalMember member){
if (member == null){ if (member == null){
return; return;
} }
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
for (Entry<String, ConcurrentHashMap<String, GossipDataMessage>> entry : gossipCore.getPerNodeData().entrySet()){ for (Entry<String, ConcurrentHashMap<String, PerNodeDataMessage>> entry : gossipCore.getPerNodeData().entrySet()){
for (Entry<String, GossipDataMessage> innerEntry : entry.getValue().entrySet()){ for (Entry<String, PerNodeDataMessage> innerEntry : entry.getValue().entrySet()){
UdpGossipDataMessage message = new UdpGossipDataMessage(); UdpPerNodeDataMessage message = new UdpPerNodeDataMessage();
message.setUuid(UUID.randomUUID().toString()); message.setUuid(UUID.randomUUID().toString());
message.setUriFrom(me.getId()); message.setUriFrom(me.getId());
message.setExpireAt(innerEntry.getValue().getExpireAt()); message.setExpireAt(innerEntry.getValue().getExpireAt());
@ -122,7 +122,7 @@ public abstract class AbstractActiveGossiper {
/** /**
* Performs the sending of the membership list, after we have incremented our own heartbeat. * Performs the sending of the membership list, after we have incremented our own heartbeat.
*/ */
protected void sendMembershipList(LocalGossipMember me, LocalGossipMember member) { protected void sendMembershipList(LocalMember me, LocalMember member) {
if (member == null){ if (member == null){
return; return;
} }
@ -132,7 +132,7 @@ public abstract class AbstractActiveGossiper {
message.setUriFrom(gossipManager.getMyself().getUri().toASCIIString()); message.setUriFrom(gossipManager.getMyself().getUri().toASCIIString());
message.setUuid(UUID.randomUUID().toString()); message.setUuid(UUID.randomUUID().toString());
message.getMembers().add(convert(me)); message.getMembers().add(convert(me));
for (LocalGossipMember other : gossipManager.getMembers().keySet()) { for (LocalMember other : gossipManager.getMembers().keySet()) {
message.getMembers().add(convert(other)); message.getMembers().add(convert(other));
} }
Response r = gossipCore.send(message, member.getUri()); Response r = gossipCore.send(message, member.getUri());
@ -144,8 +144,8 @@ public abstract class AbstractActiveGossiper {
sendMembershipHistorgram.update(System.currentTimeMillis() - startTime); sendMembershipHistorgram.update(System.currentTimeMillis() - startTime);
} }
protected final GossipMember convert(LocalGossipMember member){ protected final Member convert(LocalMember member){
GossipMember gm = new GossipMember(); Member gm = new Member();
gm.setCluster(member.getClusterName()); gm.setCluster(member.getClusterName());
gm.setHeartbeat(member.getHeartbeat()); gm.setHeartbeat(member.getHeartbeat());
gm.setUri(member.getUri().toASCIIString()); gm.setUri(member.getUri().toASCIIString());
@ -160,8 +160,8 @@ public abstract class AbstractActiveGossiper {
* An immutable list * An immutable list
* @return The chosen LocalGossipMember to gossip with. * @return The chosen LocalGossipMember to gossip with.
*/ */
protected LocalGossipMember selectPartner(List<LocalGossipMember> memberList) { protected LocalMember selectPartner(List<LocalMember> memberList) {
LocalGossipMember member = null; LocalMember member = null;
if (memberList.size() > 0) { if (memberList.size() > 0) {
int randomNeighborIndex = random.nextInt(memberList.size()); int randomNeighborIndex = random.nextInt(memberList.size());
member = memberList.get(randomNeighborIndex); member = memberList.get(randomNeighborIndex);

View File

@ -23,8 +23,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.SharedGossipDataMessage; import org.apache.gossip.model.SharedDataMessage;
/** /**
* We wish to periodically sweep user data and remove entries past their timestamp. This * We wish to periodically sweep user data and remove entries past their timestamp. This
@ -53,7 +53,7 @@ public class DataReaper {
} }
void runSharedOnce(){ void runSharedOnce(){
for (Entry<String, SharedGossipDataMessage> entry : gossipCore.getSharedData().entrySet()){ for (Entry<String, SharedDataMessage> entry : gossipCore.getSharedData().entrySet()){
if (entry.getValue().getExpireAt() < clock.currentTimeMillis()){ if (entry.getValue().getExpireAt() < clock.currentTimeMillis()){
gossipCore.getSharedData().remove(entry.getKey(), entry.getValue()); gossipCore.getSharedData().remove(entry.getKey(), entry.getValue());
} }
@ -61,13 +61,13 @@ public class DataReaper {
} }
void runPerNodeOnce(){ void runPerNodeOnce(){
for (Entry<String, ConcurrentHashMap<String, GossipDataMessage>> node : gossipCore.getPerNodeData().entrySet()){ for (Entry<String, ConcurrentHashMap<String, PerNodeDataMessage>> node : gossipCore.getPerNodeData().entrySet()){
reapData(node.getValue()); reapData(node.getValue());
} }
} }
void reapData(ConcurrentHashMap<String, GossipDataMessage> concurrentHashMap){ void reapData(ConcurrentHashMap<String, PerNodeDataMessage> concurrentHashMap){
for (Entry<String, GossipDataMessage> entry : concurrentHashMap.entrySet()){ for (Entry<String, PerNodeDataMessage> entry : concurrentHashMap.entrySet()){
if (entry.getValue().getExpireAt() < clock.currentTimeMillis()){ if (entry.getValue().getExpireAt() < clock.currentTimeMillis()){
concurrentHashMap.remove(entry.getKey(), entry.getValue()); concurrentHashMap.remove(entry.getKey(), entry.getValue());
} }

View File

@ -27,7 +27,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
@ -130,14 +130,14 @@ public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper {
sendMembershipList(gossipManager.getMyself(), selectPartner(gossipManager.getDeadMembers())); sendMembershipList(gossipManager.getMyself(), selectPartner(gossipManager.getDeadMembers()));
} }
private List<LocalGossipMember> differentDataCenter(){ private List<LocalMember> differentDataCenter(){
String myDc = gossipManager.getMyself().getProperties().get(DATACENTER); String myDc = gossipManager.getMyself().getProperties().get(DATACENTER);
String rack = gossipManager.getMyself().getProperties().get(RACK); String rack = gossipManager.getMyself().getProperties().get(RACK);
if (myDc == null|| rack == null){ if (myDc == null|| rack == null){
return Collections.emptyList(); return Collections.emptyList();
} }
List<LocalGossipMember> notMyDc = new ArrayList<LocalGossipMember>(10); List<LocalMember> notMyDc = new ArrayList<LocalMember>(10);
for (LocalGossipMember i : gossipManager.getLiveMembers()){ for (LocalMember i : gossipManager.getLiveMembers()){
if (!myDc.equals(i.getProperties().get(DATACENTER))){ if (!myDc.equals(i.getProperties().get(DATACENTER))){
notMyDc.add(i); notMyDc.add(i);
} }
@ -145,14 +145,14 @@ public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper {
return notMyDc; return notMyDc;
} }
private List<LocalGossipMember> sameDatacenterDifferentRack(){ private List<LocalMember> sameDatacenterDifferentRack(){
String myDc = gossipManager.getMyself().getProperties().get(DATACENTER); String myDc = gossipManager.getMyself().getProperties().get(DATACENTER);
String rack = gossipManager.getMyself().getProperties().get(RACK); String rack = gossipManager.getMyself().getProperties().get(RACK);
if (myDc == null|| rack == null){ if (myDc == null|| rack == null){
return Collections.emptyList(); return Collections.emptyList();
} }
List<LocalGossipMember> notMyDc = new ArrayList<LocalGossipMember>(10); List<LocalMember> notMyDc = new ArrayList<LocalMember>(10);
for (LocalGossipMember i : gossipManager.getLiveMembers()){ for (LocalMember i : gossipManager.getLiveMembers()){
if (myDc.equals(i.getProperties().get(DATACENTER)) && !rack.equals(i.getProperties().get(RACK))){ if (myDc.equals(i.getProperties().get(DATACENTER)) && !rack.equals(i.getProperties().get(RACK))){
notMyDc.add(i); notMyDc.add(i);
} }
@ -160,14 +160,14 @@ public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper {
return notMyDc; return notMyDc;
} }
private List<LocalGossipMember> sameRackNodes(){ private List<LocalMember> sameRackNodes(){
String myDc = gossipManager.getMyself().getProperties().get(DATACENTER); String myDc = gossipManager.getMyself().getProperties().get(DATACENTER);
String rack = gossipManager.getMyself().getProperties().get(RACK); String rack = gossipManager.getMyself().getProperties().get(RACK);
if (myDc == null|| rack == null){ if (myDc == null|| rack == null){
return Collections.emptyList(); return Collections.emptyList();
} }
List<LocalGossipMember> sameDcAndRack = new ArrayList<LocalGossipMember>(10); List<LocalMember> sameDcAndRack = new ArrayList<LocalMember>(10);
for (LocalGossipMember i : gossipManager.getLiveMembers()){ for (LocalMember i : gossipManager.getLiveMembers()){
if (myDc.equals(i.getProperties().get(DATACENTER)) if (myDc.equals(i.getProperties().get(DATACENTER))
&& rack.equals(i.getProperties().get(RACK))){ && rack.equals(i.getProperties().get(RACK))){
sameDcAndRack.add(i); sameDcAndRack.add(i);
@ -177,7 +177,7 @@ public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper {
} }
private void sendToSameRackMember() { private void sendToSameRackMember() {
LocalGossipMember i = selectPartner(sameRackNodes()); LocalMember i = selectPartner(sameRackNodes());
sendMembershipList(gossipManager.getMyself(), i); sendMembershipList(gossipManager.getMyself(), i);
} }
@ -235,7 +235,7 @@ public class DatacenterRackAwareActiveGossiper extends AbstractActiveGossiper {
* sends an optimistic shutdown message to several clusters nodes * sends an optimistic shutdown message to several clusters nodes
*/ */
protected void sendShutdownMessage(){ protected void sendShutdownMessage(){
List<LocalGossipMember> l = gossipManager.getLiveMembers(); List<LocalMember> l = gossipManager.getLiveMembers();
int sendTo = l.size() < 3 ? 1 : l.size() / 3; int sendTo = l.size() < 3 ? 1 : l.size() / 3;
for (int i = 0; i < sendTo; i++) { for (int i = 0; i < sendTo; i++) {
threadService.execute(() -> sendShutdownMessage(gossipManager.getMyself(), selectPartner(l))); threadService.execute(() -> sendShutdownMessage(gossipManager.getMyself(), selectPartner(l)));

View File

@ -20,9 +20,9 @@ package org.apache.gossip.manager;
import com.codahale.metrics.Gauge; import com.codahale.metrics.Gauge;
import com.codahale.metrics.Meter; import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import org.apache.gossip.GossipMember; import org.apache.gossip.Member;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.RemoteGossipMember; import org.apache.gossip.RemoteMember;
import org.apache.gossip.crdt.Crdt; import org.apache.gossip.crdt.Crdt;
import org.apache.gossip.event.GossipState; import org.apache.gossip.event.GossipState;
import org.apache.gossip.model.*; import org.apache.gossip.model.*;
@ -49,8 +49,8 @@ public class GossipCore implements GossipCoreConstants {
private final GossipManager gossipManager; private final GossipManager gossipManager;
private ConcurrentHashMap<String, Base> requests; private ConcurrentHashMap<String, Base> requests;
private ThreadPoolExecutor service; private ThreadPoolExecutor service;
private final ConcurrentHashMap<String, ConcurrentHashMap<String, GossipDataMessage>> perNodeData; private final ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> perNodeData;
private final ConcurrentHashMap<String, SharedGossipDataMessage> sharedData; private final ConcurrentHashMap<String, SharedDataMessage> sharedData;
private final BlockingQueue<Runnable> workQueue; private final BlockingQueue<Runnable> workQueue;
private final PKCS8EncodedKeySpec privKeySpec; private final PKCS8EncodedKeySpec privKeySpec;
private final PrivateKey privKey; private final PrivateKey privKey;
@ -113,14 +113,14 @@ public class GossipCore implements GossipCoreConstants {
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public void addSharedData(SharedGossipDataMessage message) { public void addSharedData(SharedDataMessage message) {
while (true){ while (true){
SharedGossipDataMessage previous = sharedData.putIfAbsent(message.getKey(), message); SharedDataMessage previous = sharedData.putIfAbsent(message.getKey(), message);
if (previous == null){ if (previous == null){
return; return;
} }
if (message.getPayload() instanceof Crdt){ if (message.getPayload() instanceof Crdt){
SharedGossipDataMessage merged = new SharedGossipDataMessage(); SharedDataMessage merged = new SharedDataMessage();
merged.setExpireAt(message.getExpireAt()); merged.setExpireAt(message.getExpireAt());
merged.setKey(message.getKey()); merged.setKey(message.getKey());
merged.setNodeId(message.getNodeId()); merged.setNodeId(message.getNodeId());
@ -144,12 +144,12 @@ public class GossipCore implements GossipCoreConstants {
} }
} }
public void addPerNodeData(GossipDataMessage message){ public void addPerNodeData(PerNodeDataMessage message){
ConcurrentHashMap<String,GossipDataMessage> nodeMap = new ConcurrentHashMap<>(); ConcurrentHashMap<String,PerNodeDataMessage> nodeMap = new ConcurrentHashMap<>();
nodeMap.put(message.getKey(), message); nodeMap.put(message.getKey(), message);
nodeMap = perNodeData.putIfAbsent(message.getNodeId(), nodeMap); nodeMap = perNodeData.putIfAbsent(message.getNodeId(), nodeMap);
if (nodeMap != null){ if (nodeMap != null){
GossipDataMessage current = nodeMap.get(message.getKey()); PerNodeDataMessage current = nodeMap.get(message.getKey());
if (current == null){ if (current == null){
nodeMap.putIfAbsent(message.getKey(), message); nodeMap.putIfAbsent(message.getKey(), message);
} else { } else {
@ -160,11 +160,11 @@ public class GossipCore implements GossipCoreConstants {
} }
} }
public ConcurrentHashMap<String, ConcurrentHashMap<String, GossipDataMessage>> getPerNodeData(){ public ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> getPerNodeData(){
return perNodeData; return perNodeData;
} }
public ConcurrentHashMap<String, SharedGossipDataMessage> getSharedData() { public ConcurrentHashMap<String, SharedDataMessage> getSharedData() {
return sharedData; return sharedData;
} }
@ -314,12 +314,12 @@ public class GossipCore implements GossipCoreConstants {
* @param remoteList * @param remoteList
* *
*/ */
public void mergeLists(GossipManager gossipManager, RemoteGossipMember senderMember, public void mergeLists(GossipManager gossipManager, RemoteMember senderMember,
List<GossipMember> remoteList) { List<Member> remoteList) {
if (LOGGER.isDebugEnabled()){ if (LOGGER.isDebugEnabled()){
debugState(senderMember, remoteList); debugState(senderMember, remoteList);
} }
for (LocalGossipMember i : gossipManager.getDeadMembers()) { for (LocalMember i : gossipManager.getDeadMembers()) {
if (i.getId().equals(senderMember.getId())) { if (i.getId().equals(senderMember.getId())) {
LOGGER.debug(gossipManager.getMyself() + " contacted by dead member " + senderMember.getUri()); LOGGER.debug(gossipManager.getMyself() + " contacted by dead member " + senderMember.getUri());
i.recordHeartbeat(senderMember.getHeartbeat()); i.recordHeartbeat(senderMember.getHeartbeat());
@ -327,11 +327,11 @@ public class GossipCore implements GossipCoreConstants {
//TODO consider forcing an UP here //TODO consider forcing an UP here
} }
} }
for (GossipMember remoteMember : remoteList) { for (Member remoteMember : remoteList) {
if (remoteMember.getId().equals(gossipManager.getMyself().getId())) { if (remoteMember.getId().equals(gossipManager.getMyself().getId())) {
continue; continue;
} }
LocalGossipMember aNewMember = new LocalGossipMember(remoteMember.getClusterName(), LocalMember aNewMember = new LocalMember(remoteMember.getClusterName(),
remoteMember.getUri(), remoteMember.getUri(),
remoteMember.getId(), remoteMember.getId(),
remoteMember.getHeartbeat(), remoteMember.getHeartbeat(),
@ -342,7 +342,7 @@ public class GossipCore implements GossipCoreConstants {
aNewMember.recordHeartbeat(remoteMember.getHeartbeat()); aNewMember.recordHeartbeat(remoteMember.getHeartbeat());
Object result = gossipManager.getMembers().putIfAbsent(aNewMember, GossipState.UP); Object result = gossipManager.getMembers().putIfAbsent(aNewMember, GossipState.UP);
if (result != null){ if (result != null){
for (Entry<LocalGossipMember, GossipState> localMember : gossipManager.getMembers().entrySet()){ for (Entry<LocalMember, GossipState> localMember : gossipManager.getMembers().entrySet()){
if (localMember.getKey().getId().equals(remoteMember.getId())){ if (localMember.getKey().getId().equals(remoteMember.getId())){
localMember.getKey().recordHeartbeat(remoteMember.getHeartbeat()); localMember.getKey().recordHeartbeat(remoteMember.getHeartbeat());
localMember.getKey().setHeartbeat(remoteMember.getHeartbeat()); localMember.getKey().setHeartbeat(remoteMember.getHeartbeat());
@ -356,8 +356,8 @@ public class GossipCore implements GossipCoreConstants {
} }
} }
private void debugState(RemoteGossipMember senderMember, private void debugState(RemoteMember senderMember,
List<GossipMember> remoteList){ List<Member> remoteList){
LOGGER.warn( LOGGER.warn(
"-----------------------\n" + "-----------------------\n" +
"Me " + gossipManager.getMyself() + "\n" + "Me " + gossipManager.getMyself() + "\n" +
@ -369,13 +369,13 @@ public class GossipCore implements GossipCoreConstants {
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public Crdt merge(SharedGossipDataMessage message) { public Crdt merge(SharedDataMessage message) {
for (;;){ for (;;){
SharedGossipDataMessage previous = sharedData.putIfAbsent(message.getKey(), message); SharedDataMessage previous = sharedData.putIfAbsent(message.getKey(), message);
if (previous == null){ if (previous == null){
return (Crdt) message.getPayload(); return (Crdt) message.getPayload();
} }
SharedGossipDataMessage copy = new SharedGossipDataMessage(); SharedDataMessage copy = new SharedDataMessage();
copy.setExpireAt(message.getExpireAt()); copy.setExpireAt(message.getExpireAt());
copy.setKey(message.getKey()); copy.setKey(message.getKey());
copy.setNodeId(message.getNodeId()); copy.setNodeId(message.getNodeId());

View File

@ -19,16 +19,16 @@ package org.apache.gossip.manager;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.gossip.GossipMember; import org.apache.gossip.Member;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.crdt.Crdt; import org.apache.gossip.crdt.Crdt;
import org.apache.gossip.event.GossipListener; import org.apache.gossip.event.GossipListener;
import org.apache.gossip.event.GossipState; import org.apache.gossip.event.GossipState;
import org.apache.gossip.manager.handlers.MessageInvoker; import org.apache.gossip.manager.handlers.MessageInvoker;
import org.apache.gossip.manager.impl.OnlyProcessReceivedPassiveGossipThread; import org.apache.gossip.manager.impl.OnlyProcessReceivedPassiveGossipThread;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.SharedGossipDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.apache.gossip.model.ShutdownMessage; import org.apache.gossip.model.ShutdownMessage;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -44,13 +44,12 @@ import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public abstract class GossipManager { public abstract class GossipManager {
public static final Logger LOGGER = Logger.getLogger(GossipManager.class); public static final Logger LOGGER = Logger.getLogger(GossipManager.class);
private final ConcurrentSkipListMap<LocalGossipMember, GossipState> members; private final ConcurrentSkipListMap<LocalMember, GossipState> members;
private final LocalGossipMember me; private final LocalMember me;
private final GossipSettings settings; private final GossipSettings settings;
private final AtomicBoolean gossipServiceRunning; private final AtomicBoolean gossipServiceRunning;
private final GossipListener listener; private final GossipListener listener;
@ -70,19 +69,19 @@ public abstract class GossipManager {
public GossipManager(String cluster, public GossipManager(String cluster,
URI uri, String id, Map<String, String> properties, GossipSettings settings, URI uri, String id, Map<String, String> properties, GossipSettings settings,
List<GossipMember> gossipMembers, GossipListener listener, MetricRegistry registry, List<Member> gossipMembers, GossipListener listener, MetricRegistry registry,
ObjectMapper objectMapper, MessageInvoker messageInvoker) { ObjectMapper objectMapper, MessageInvoker messageInvoker) {
this.settings = settings; this.settings = settings;
this.messageInvoker = messageInvoker; this.messageInvoker = messageInvoker;
clock = new SystemClock(); clock = new SystemClock();
me = new LocalGossipMember(cluster, uri, id, clock.nanoTime(), properties, me = new LocalMember(cluster, uri, id, clock.nanoTime(), properties,
settings.getWindowSize(), settings.getMinimumSamples(), settings.getDistribution()); settings.getWindowSize(), settings.getMinimumSamples(), settings.getDistribution());
gossipCore = new GossipCore(this, registry); gossipCore = new GossipCore(this, registry);
dataReaper = new DataReaper(gossipCore, clock); dataReaper = new DataReaper(gossipCore, clock);
members = new ConcurrentSkipListMap<>(); members = new ConcurrentSkipListMap<>();
for (GossipMember startupMember : gossipMembers) { for (Member startupMember : gossipMembers) {
if (!startupMember.equals(me)) { if (!startupMember.equals(me)) {
LocalGossipMember member = new LocalGossipMember(startupMember.getClusterName(), LocalMember member = new LocalMember(startupMember.getClusterName(),
startupMember.getUri(), startupMember.getId(), startupMember.getUri(), startupMember.getId(),
clock.nanoTime(), startupMember.getProperties(), settings.getWindowSize(), clock.nanoTime(), startupMember.getProperties(), settings.getWindowSize(),
settings.getMinimumSamples(), settings.getDistribution()); settings.getMinimumSamples(), settings.getDistribution());
@ -106,7 +105,7 @@ public abstract class GossipManager {
return messageInvoker; return messageInvoker;
} }
public ConcurrentSkipListMap<LocalGossipMember, GossipState> getMembers() { public ConcurrentSkipListMap<LocalMember, GossipState> getMembers() {
return members; return members;
} }
@ -117,7 +116,7 @@ public abstract class GossipManager {
/** /**
* @return a read only list of members found in the DOWN state. * @return a read only list of members found in the DOWN state.
*/ */
public List<LocalGossipMember> getDeadMembers() { public List<LocalMember> getDeadMembers() {
return Collections.unmodifiableList( return Collections.unmodifiableList(
members.entrySet() members.entrySet()
.stream() .stream()
@ -129,7 +128,7 @@ public abstract class GossipManager {
* *
* @return a read only list of members found in the UP state * @return a read only list of members found in the UP state
*/ */
public List<LocalGossipMember> getLiveMembers() { public List<LocalMember> getLiveMembers() {
return Collections.unmodifiableList( return Collections.unmodifiableList(
members.entrySet() members.entrySet()
.stream() .stream()
@ -137,7 +136,7 @@ public abstract class GossipManager {
.map(Entry::getKey).collect(Collectors.toList())); .map(Entry::getKey).collect(Collectors.toList()));
} }
public LocalGossipMember getMyself() { public LocalMember getMyself() {
return me; return me;
} }
@ -164,7 +163,7 @@ public abstract class GossipManager {
scheduledServiced.scheduleAtFixedRate(userDataState, 60, 60, TimeUnit.SECONDS); scheduledServiced.scheduleAtFixedRate(userDataState, 60, 60, TimeUnit.SECONDS);
scheduledServiced.scheduleAtFixedRate(() -> { scheduledServiced.scheduleAtFixedRate(() -> {
try { try {
for (Entry<LocalGossipMember, GossipState> entry : members.entrySet()) { for (Entry<LocalMember, GossipState> entry : members.entrySet()) {
boolean userDown = processOptomisticShutdown(entry); boolean userDown = processOptomisticShutdown(entry);
if (userDown) if (userDown)
continue; continue;
@ -205,8 +204,8 @@ public abstract class GossipManager {
* @param l member to consider * @param l member to consider
* @return true if node forced down * @return true if node forced down
*/ */
public boolean processOptomisticShutdown(Entry<LocalGossipMember, GossipState> l){ public boolean processOptomisticShutdown(Entry<LocalMember, GossipState> l){
GossipDataMessage m = findPerNodeGossipData(l.getKey().getId(), ShutdownMessage.PER_NODE_KEY); PerNodeDataMessage m = findPerNodeGossipData(l.getKey().getId(), ShutdownMessage.PER_NODE_KEY);
if (m == null){ if (m == null){
return false; return false;
} }
@ -224,8 +223,8 @@ public abstract class GossipManager {
} }
private void readSavedRingState() { private void readSavedRingState() {
for (LocalGossipMember l : ringState.readFromDisk()){ for (LocalMember l : ringState.readFromDisk()){
LocalGossipMember member = new LocalGossipMember(l.getClusterName(), LocalMember member = new LocalMember(l.getClusterName(),
l.getUri(), l.getId(), l.getUri(), l.getId(),
clock.nanoTime(), l.getProperties(), settings.getWindowSize(), clock.nanoTime(), l.getProperties(), settings.getWindowSize(),
settings.getMinimumSamples(), settings.getDistribution()); settings.getMinimumSamples(), settings.getDistribution());
@ -234,12 +233,12 @@ public abstract class GossipManager {
} }
private void readSavedDataState() { private void readSavedDataState() {
for (Entry<String, ConcurrentHashMap<String, GossipDataMessage>> l : userDataState.readPerNodeFromDisk().entrySet()){ for (Entry<String, ConcurrentHashMap<String, PerNodeDataMessage>> l : userDataState.readPerNodeFromDisk().entrySet()){
for (Entry<String, GossipDataMessage> j : l.getValue().entrySet()){ for (Entry<String, PerNodeDataMessage> j : l.getValue().entrySet()){
gossipCore.addPerNodeData(j.getValue()); gossipCore.addPerNodeData(j.getValue());
} }
} }
for (Entry<String, SharedGossipDataMessage> l: userDataState.readSharedDataFromDisk().entrySet()){ for (Entry<String, SharedDataMessage> l: userDataState.readSharedDataFromDisk().entrySet()){
gossipCore.addSharedData(l.getValue()); gossipCore.addSharedData(l.getValue());
} }
} }
@ -276,7 +275,7 @@ public abstract class GossipManager {
scheduledServiced.shutdownNow(); scheduledServiced.shutdownNow();
} }
public void gossipPerNodeData(GossipDataMessage message){ public void gossipPerNodeData(PerNodeDataMessage message){
Objects.nonNull(message.getKey()); Objects.nonNull(message.getKey());
Objects.nonNull(message.getTimestamp()); Objects.nonNull(message.getTimestamp());
Objects.nonNull(message.getPayload()); Objects.nonNull(message.getPayload());
@ -284,7 +283,7 @@ public abstract class GossipManager {
gossipCore.addPerNodeData(message); gossipCore.addPerNodeData(message);
} }
public void gossipSharedData(SharedGossipDataMessage message){ public void gossipSharedData(SharedDataMessage message){
Objects.nonNull(message.getKey()); Objects.nonNull(message.getKey());
Objects.nonNull(message.getTimestamp()); Objects.nonNull(message.getTimestamp());
Objects.nonNull(message.getPayload()); Objects.nonNull(message.getPayload());
@ -295,7 +294,7 @@ public abstract class GossipManager {
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public Crdt findCrdt(String key){ public Crdt findCrdt(String key){
SharedGossipDataMessage l = gossipCore.getSharedData().get(key); SharedDataMessage l = gossipCore.getSharedData().get(key);
if (l == null){ if (l == null){
return null; return null;
} }
@ -307,7 +306,7 @@ public abstract class GossipManager {
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public Crdt merge(SharedGossipDataMessage message){ public Crdt merge(SharedDataMessage message){
Objects.nonNull(message.getKey()); Objects.nonNull(message.getKey());
Objects.nonNull(message.getTimestamp()); Objects.nonNull(message.getTimestamp());
Objects.nonNull(message.getPayload()); Objects.nonNull(message.getPayload());
@ -318,12 +317,12 @@ public abstract class GossipManager {
return gossipCore.merge(message); return gossipCore.merge(message);
} }
public GossipDataMessage findPerNodeGossipData(String nodeId, String key){ public PerNodeDataMessage findPerNodeGossipData(String nodeId, String key){
ConcurrentHashMap<String, GossipDataMessage> j = gossipCore.getPerNodeData().get(nodeId); ConcurrentHashMap<String, PerNodeDataMessage> j = gossipCore.getPerNodeData().get(nodeId);
if (j == null){ if (j == null){
return null; return null;
} else { } else {
GossipDataMessage l = j.get(key); PerNodeDataMessage l = j.get(key);
if (l == null){ if (l == null){
return null; return null;
} }
@ -334,8 +333,8 @@ public abstract class GossipManager {
} }
} }
public SharedGossipDataMessage findSharedGossipData(String key){ public SharedDataMessage findSharedGossipData(String key){
SharedGossipDataMessage l = gossipCore.getSharedData().get(key); SharedDataMessage l = gossipCore.getSharedData().get(key);
if (l == null){ if (l == null){
return null; return null;
} }

View File

@ -15,16 +15,16 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.gossip.manager.random; package org.apache.gossip.manager;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.core.JsonGenerator.Feature; import com.fasterxml.jackson.core.JsonGenerator.Feature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.gossip.GossipMember; import org.apache.gossip.Member;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.StartupSettings;
import org.apache.gossip.crdt.CrdtModule; import org.apache.gossip.crdt.CrdtModule;
import org.apache.gossip.event.GossipListener; import org.apache.gossip.event.GossipListener;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.handlers.DefaultMessageInvoker; import org.apache.gossip.manager.handlers.DefaultMessageInvoker;
import org.apache.gossip.manager.handlers.MessageInvoker; import org.apache.gossip.manager.handlers.MessageInvoker;
@ -34,7 +34,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class RandomGossipManager extends GossipManager { public class GossipManagerBuilder {
public static ManagerBuilder newBuilder() { public static ManagerBuilder newBuilder() {
return new ManagerBuilder(); return new ManagerBuilder();
@ -45,7 +45,7 @@ public class RandomGossipManager extends GossipManager {
private URI uri; private URI uri;
private String id; private String id;
private GossipSettings settings; private GossipSettings settings;
private List<GossipMember> gossipMembers; private List<Member> gossipMembers;
private GossipListener listener; private GossipListener listener;
private MetricRegistry registry; private MetricRegistry registry;
private Map<String,String> properties; private Map<String,String> properties;
@ -70,17 +70,26 @@ public class RandomGossipManager extends GossipManager {
return this; return this;
} }
public ManagerBuilder withId(String id) { public ManagerBuilder id(String id) {
this.id = id; this.id = id;
return this; return this;
} }
public ManagerBuilder settings(GossipSettings settings) { public ManagerBuilder gossipSettings(GossipSettings settings) {
this.settings = settings; this.settings = settings;
return this; return this;
} }
public ManagerBuilder gossipMembers(List<GossipMember> members) { public ManagerBuilder startupSettings(StartupSettings startupSettings) {
this.cluster = startupSettings.getCluster();
this.id = startupSettings.getId();
this.settings = startupSettings.getGossipSettings();
this.gossipMembers = startupSettings.getGossipMembers();
this.uri = startupSettings.getUri();
return this;
}
public ManagerBuilder gossipMembers(List<Member> members) {
this.gossipMembers = members; this.gossipMembers = members;
return this; return this;
} }
@ -110,12 +119,14 @@ public class RandomGossipManager extends GossipManager {
return this; return this;
} }
public RandomGossipManager build() { public GossipManager build() {
checkArgument(id != null, "You must specify an id"); checkArgument(id != null, "You must specify an id");
checkArgument(cluster != null, "You must specify a cluster name"); checkArgument(cluster != null, "You must specify a cluster name");
checkArgument(settings != null, "You must specify gossip settings"); checkArgument(settings != null, "You must specify gossip settings");
checkArgument(uri != null, "You must specify a uri"); checkArgument(uri != null, "You must specify a uri");
checkArgument(registry != null, "You must specify a MetricRegistry"); if (registry == null){
registry = new MetricRegistry();
}
if (properties == null){ if (properties == null){
properties = new HashMap<String,String>(); properties = new HashMap<String,String>();
} }
@ -134,12 +145,8 @@ public class RandomGossipManager extends GossipManager {
if (messageInvoker == null) { if (messageInvoker == null) {
messageInvoker = new DefaultMessageInvoker(); messageInvoker = new DefaultMessageInvoker();
} }
return new RandomGossipManager(cluster, uri, id, properties, settings, gossipMembers, listener, registry, objectMapper, messageInvoker); return new GossipManager(cluster, uri, id, properties, settings, gossipMembers, listener, registry, objectMapper, messageInvoker) {} ;
} }
} }
private RandomGossipManager(String cluster, URI uri, String id, Map<String,String> properties, GossipSettings settings,
List<GossipMember> gossipMembers, GossipListener listener, MetricRegistry registry, ObjectMapper objectMapper, MessageInvoker messageInvoker) {
super(cluster, uri, id, properties, settings, gossipMembers, listener, registry, objectMapper, messageInvoker);
}
} }

View File

@ -26,7 +26,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.NavigableSet; import java.util.NavigableSet;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
public class RingStatePersister implements Runnable { public class RingStatePersister implements Runnable {
@ -52,7 +52,7 @@ public class RingStatePersister implements Runnable {
if (!parent.getSettings().isPersistRingState()){ if (!parent.getSettings().isPersistRingState()){
return; return;
} }
NavigableSet<LocalGossipMember> i = parent.getMembers().keySet(); NavigableSet<LocalMember> i = parent.getMembers().keySet();
try (FileOutputStream fos = new FileOutputStream(computeTarget())){ try (FileOutputStream fos = new FileOutputStream(computeTarget())){
parent.getObjectMapper().writeValue(fos, i); parent.getObjectMapper().writeValue(fos, i);
} catch (IOException e) { } catch (IOException e) {
@ -61,7 +61,7 @@ public class RingStatePersister implements Runnable {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<LocalGossipMember> readFromDisk(){ List<LocalMember> readFromDisk(){
if (!parent.getSettings().isPersistRingState()){ if (!parent.getSettings().isPersistRingState()){
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -25,7 +25,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
@ -88,12 +88,12 @@ public class SimpleActiveGossipper extends AbstractActiveGossiper {
} }
protected void sendToALiveMember(){ protected void sendToALiveMember(){
LocalGossipMember member = selectPartner(gossipManager.getLiveMembers()); LocalMember member = selectPartner(gossipManager.getLiveMembers());
sendMembershipList(gossipManager.getMyself(), member); sendMembershipList(gossipManager.getMyself(), member);
} }
protected void sendToDeadMember(){ protected void sendToDeadMember(){
LocalGossipMember member = selectPartner(gossipManager.getDeadMembers()); LocalMember member = selectPartner(gossipManager.getDeadMembers());
sendMembershipList(gossipManager.getMyself(), member); sendMembershipList(gossipManager.getMyself(), member);
} }
@ -101,7 +101,7 @@ public class SimpleActiveGossipper extends AbstractActiveGossiper {
* sends an optimistic shutdown message to several clusters nodes * sends an optimistic shutdown message to several clusters nodes
*/ */
protected void sendShutdownMessage(){ protected void sendShutdownMessage(){
List<LocalGossipMember> l = gossipManager.getLiveMembers(); List<LocalMember> l = gossipManager.getLiveMembers();
int sendTo = l.size() < 3 ? 1 : l.size() / 2; int sendTo = l.size() < 3 ? 1 : l.size() / 2;
for (int i = 0; i < sendTo; i++) { for (int i = 0; i < sendTo; i++) {
threadService.execute(() -> sendShutdownMessage(gossipManager.getMyself(), selectPartner(l))); threadService.execute(() -> sendShutdownMessage(gossipManager.getMyself(), selectPartner(l)));

View File

@ -23,8 +23,8 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.SharedGossipDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
public class UserDataPersister implements Runnable { public class UserDataPersister implements Runnable {
@ -49,16 +49,16 @@ public class UserDataPersister implements Runnable {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ConcurrentHashMap<String, ConcurrentHashMap<String, GossipDataMessage>> readPerNodeFromDisk(){ ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> readPerNodeFromDisk(){
if (!parent.getSettings().isPersistDataState()){ if (!parent.getSettings().isPersistDataState()){
return new ConcurrentHashMap<String, ConcurrentHashMap<String, GossipDataMessage>>(); return new ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>>();
} }
try (FileInputStream fos = new FileInputStream(computePerNodeTarget())){ try (FileInputStream fos = new FileInputStream(computePerNodeTarget())){
return parent.getObjectMapper().readValue(fos, ConcurrentHashMap.class); return parent.getObjectMapper().readValue(fos, ConcurrentHashMap.class);
} catch (IOException e) { } catch (IOException e) {
LOGGER.debug(e); LOGGER.debug(e);
} }
return new ConcurrentHashMap<String, ConcurrentHashMap<String, GossipDataMessage>>(); return new ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>>();
} }
void writePerNodeToDisk(){ void writePerNodeToDisk(){
@ -84,16 +84,16 @@ public class UserDataPersister implements Runnable {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ConcurrentHashMap<String, SharedGossipDataMessage> readSharedDataFromDisk(){ ConcurrentHashMap<String, SharedDataMessage> readSharedDataFromDisk(){
if (!parent.getSettings().isPersistRingState()){ if (!parent.getSettings().isPersistRingState()){
return new ConcurrentHashMap<String, SharedGossipDataMessage>(); return new ConcurrentHashMap<String, SharedDataMessage>();
} }
try (FileInputStream fos = new FileInputStream(computeSharedTarget())){ try (FileInputStream fos = new FileInputStream(computeSharedTarget())){
return parent.getObjectMapper().readValue(fos, ConcurrentHashMap.class); return parent.getObjectMapper().readValue(fos, ConcurrentHashMap.class);
} catch (IOException e) { } catch (IOException e) {
LOGGER.debug(e); LOGGER.debug(e);
} }
return new ConcurrentHashMap<String, SharedGossipDataMessage>(); return new ConcurrentHashMap<String, SharedDataMessage>();
} }
/** /**

View File

@ -17,8 +17,8 @@
*/ */
package org.apache.gossip.manager.handlers; package org.apache.gossip.manager.handlers;
import org.apache.gossip.GossipMember; import org.apache.gossip.Member;
import org.apache.gossip.RemoteGossipMember; import org.apache.gossip.RemoteMember;
import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipCore;
import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.Base; import org.apache.gossip.model.Base;
@ -34,8 +34,8 @@ import java.util.List;
public class ActiveGossipMessageHandler implements MessageHandler { public class ActiveGossipMessageHandler implements MessageHandler {
@Override @Override
public void invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) { public void invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) {
List<GossipMember> remoteGossipMembers = new ArrayList<>(); List<Member> remoteGossipMembers = new ArrayList<>();
RemoteGossipMember senderMember = null; RemoteMember senderMember = null;
UdpActiveGossipMessage activeGossipMessage = (UdpActiveGossipMessage) base; UdpActiveGossipMessage activeGossipMessage = (UdpActiveGossipMessage) base;
for (int i = 0; i < activeGossipMessage.getMembers().size(); i++) { for (int i = 0; i < activeGossipMessage.getMembers().size(); i++) {
URI u; URI u;
@ -45,7 +45,7 @@ public class ActiveGossipMessageHandler implements MessageHandler {
GossipCore.LOGGER.debug("Gossip message with faulty URI", e); GossipCore.LOGGER.debug("Gossip message with faulty URI", e);
continue; continue;
} }
RemoteGossipMember member = new RemoteGossipMember( RemoteMember member = new RemoteMember(
activeGossipMessage.getMembers().get(i).getCluster(), activeGossipMessage.getMembers().get(i).getCluster(),
u, u,
activeGossipMessage.getMembers().get(i).getId(), activeGossipMessage.getMembers().get(i).getId(),

View File

@ -29,8 +29,8 @@ public class DefaultMessageInvoker implements MessageInvoker {
mic = new MessageInvokerCombiner(); mic = new MessageInvokerCombiner();
mic.add(new SimpleMessageInvoker(Response.class, new ResponseHandler())); mic.add(new SimpleMessageInvoker(Response.class, new ResponseHandler()));
mic.add(new SimpleMessageInvoker(ShutdownMessage.class, new ShutdownMessageHandler())); mic.add(new SimpleMessageInvoker(ShutdownMessage.class, new ShutdownMessageHandler()));
mic.add(new SimpleMessageInvoker(GossipDataMessage.class, new GossipDataMessageHandler())); mic.add(new SimpleMessageInvoker(PerNodeDataMessage.class, new PerNodeDataMessageHandler()));
mic.add(new SimpleMessageInvoker(SharedGossipDataMessage.class, new SharedGossipDataMessageHandler())); mic.add(new SimpleMessageInvoker(SharedDataMessage.class, new SharedDataMessageHandler()));
mic.add(new SimpleMessageInvoker(ActiveGossipMessage.class, new ActiveGossipMessageHandler())); mic.add(new SimpleMessageInvoker(ActiveGossipMessage.class, new ActiveGossipMessageHandler()));
} }

View File

@ -20,12 +20,12 @@ package org.apache.gossip.manager.handlers;
import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipCore;
import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.Base; import org.apache.gossip.model.Base;
import org.apache.gossip.udp.UdpGossipDataMessage; import org.apache.gossip.udp.UdpPerNodeDataMessage;
public class GossipDataMessageHandler implements MessageHandler { public class PerNodeDataMessageHandler implements MessageHandler {
@Override @Override
public void invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) { public void invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) {
UdpGossipDataMessage message = (UdpGossipDataMessage) base; UdpPerNodeDataMessage message = (UdpPerNodeDataMessage) base;
gossipCore.addPerNodeData(message); gossipCore.addPerNodeData(message);
} }
} }

View File

@ -20,12 +20,12 @@ package org.apache.gossip.manager.handlers;
import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipCore;
import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.Base; import org.apache.gossip.model.Base;
import org.apache.gossip.udp.UdpSharedGossipDataMessage; import org.apache.gossip.udp.UdpSharedDataMessage;
public class SharedGossipDataMessageHandler implements MessageHandler{ public class SharedDataMessageHandler implements MessageHandler{
@Override @Override
public void invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) { public void invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) {
UdpSharedGossipDataMessage message = (UdpSharedGossipDataMessage) base; UdpSharedDataMessage message = (UdpSharedDataMessage) base;
gossipCore.addSharedData(message); gossipCore.addSharedData(message);
} }
} }

View File

@ -20,14 +20,14 @@ package org.apache.gossip.manager.handlers;
import org.apache.gossip.manager.GossipCore; import org.apache.gossip.manager.GossipCore;
import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.Base; import org.apache.gossip.model.Base;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.ShutdownMessage; import org.apache.gossip.model.ShutdownMessage;
public class ShutdownMessageHandler implements MessageHandler { public class ShutdownMessageHandler implements MessageHandler {
@Override @Override
public void invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) { public void invoke(GossipCore gossipCore, GossipManager gossipManager, Base base) {
ShutdownMessage s = (ShutdownMessage) base; ShutdownMessage s = (ShutdownMessage) base;
GossipDataMessage m = new GossipDataMessage(); PerNodeDataMessage m = new PerNodeDataMessage();
m.setKey(ShutdownMessage.PER_NODE_KEY); m.setKey(ShutdownMessage.PER_NODE_KEY);
m.setNodeId(s.getNodeId()); m.setNodeId(s.getNodeId());
m.setPayload(base); m.setPayload(base);

View File

@ -22,17 +22,17 @@ import java.util.List;
public class ActiveGossipMessage extends Base { public class ActiveGossipMessage extends Base {
private List<GossipMember> members = new ArrayList<>(); private List<Member> members = new ArrayList<>();
public ActiveGossipMessage(){ public ActiveGossipMessage(){
} }
public List<GossipMember> getMembers() { public List<Member> getMembers() {
return members; return members;
} }
public void setMembers(List<GossipMember> members) { public void setMembers(List<Member> members) {
this.members = members; this.members = members;
} }

View File

@ -19,9 +19,9 @@ package org.apache.gossip.model;
import org.apache.gossip.udp.UdpActiveGossipMessage; import org.apache.gossip.udp.UdpActiveGossipMessage;
import org.apache.gossip.udp.UdpActiveGossipOk; import org.apache.gossip.udp.UdpActiveGossipOk;
import org.apache.gossip.udp.UdpGossipDataMessage; import org.apache.gossip.udp.UdpPerNodeDataMessage;
import org.apache.gossip.udp.UdpNotAMemberFault; import org.apache.gossip.udp.UdpNotAMemberFault;
import org.apache.gossip.udp.UdpSharedGossipDataMessage; import org.apache.gossip.udp.UdpSharedDataMessage;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
@ -39,10 +39,10 @@ import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
@Type(value = UdpActiveGossipOk.class, name = "UdpActiveGossipOk"), @Type(value = UdpActiveGossipOk.class, name = "UdpActiveGossipOk"),
@Type(value = UdpActiveGossipMessage.class, name = "UdpActiveGossipMessage"), @Type(value = UdpActiveGossipMessage.class, name = "UdpActiveGossipMessage"),
@Type(value = UdpNotAMemberFault.class, name = "UdpNotAMemberFault"), @Type(value = UdpNotAMemberFault.class, name = "UdpNotAMemberFault"),
@Type(value = GossipDataMessage.class, name = "GossipDataMessage"), @Type(value = PerNodeDataMessage.class, name = "PerNodeDataMessage"),
@Type(value = UdpGossipDataMessage.class, name = "UdpGossipDataMessage"), @Type(value = UdpPerNodeDataMessage.class, name = "UdpPerNodeDataMessage"),
@Type(value = SharedGossipDataMessage.class, name = "SharedGossipDataMessage"), @Type(value = SharedDataMessage.class, name = "SharedDataMessage"),
@Type(value = UdpSharedGossipDataMessage.class, name = "UdpSharedGossipDataMessage") @Type(value = UdpSharedDataMessage.class, name = "UdpSharedDataMessage")
}) })
public class Base { public class Base {

View File

@ -19,7 +19,7 @@ package org.apache.gossip.model;
import java.util.Map; import java.util.Map;
public class GossipMember { public class Member {
private String cluster; private String cluster;
private String uri; private String uri;
@ -27,11 +27,11 @@ public class GossipMember {
private Long heartbeat; private Long heartbeat;
private Map<String,String> properties; private Map<String,String> properties;
public GossipMember(){ public Member(){
} }
public GossipMember(String cluster, String uri, String id, Long heartbeat){ public Member(String cluster, String uri, String id, Long heartbeat){
this.cluster = cluster; this.cluster = cluster;
this.uri = uri; this.uri = uri;
this.id = id; this.id = id;
@ -80,7 +80,7 @@ public class GossipMember {
@Override @Override
public String toString() { public String toString() {
return "GossipMember [cluster=" + cluster + ", uri=" + uri + ", id=" + id + ", heartbeat=" return "Member [cluster=" + cluster + ", uri=" + uri + ", id=" + id + ", heartbeat="
+ heartbeat + ", properties=" + properties + "]"; + heartbeat + ", properties=" + properties + "]";
} }

View File

@ -17,7 +17,7 @@
*/ */
package org.apache.gossip.model; package org.apache.gossip.model;
public class GossipDataMessage extends Base { public class PerNodeDataMessage extends Base {
private String nodeId; private String nodeId;
private String key; private String key;

View File

@ -17,7 +17,7 @@
*/ */
package org.apache.gossip.model; package org.apache.gossip.model;
public class SharedGossipDataMessage extends Base { public class SharedDataMessage extends Base {
private String nodeId; private String nodeId;
private String key; private String key;

View File

@ -17,9 +17,9 @@
*/ */
package org.apache.gossip.udp; package org.apache.gossip.udp;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
public class UdpGossipDataMessage extends GossipDataMessage implements Trackable { public class UdpPerNodeDataMessage extends PerNodeDataMessage implements Trackable {
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;

View File

@ -17,9 +17,9 @@
*/ */
package org.apache.gossip.udp; package org.apache.gossip.udp;
import org.apache.gossip.model.SharedGossipDataMessage; import org.apache.gossip.model.SharedDataMessage;
public class UdpSharedGossipDataMessage extends SharedGossipDataMessage implements Trackable { public class UdpSharedDataMessage extends SharedDataMessage implements Trackable {
private String uriFrom; private String uriFrom;
private String uuid; private String uuid;

View File

@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.gossip;
import java.util.ArrayList;
import java.util.List;
import org.apache.gossip.manager.GossipManager;
import org.junit.After;
import org.junit.Before;
public abstract class AbstractIntegrationBase {
List <GossipManager> nodes = new ArrayList<GossipManager>();
public void register(GossipManager manager){
nodes.add(manager);
}
@Before
public void before(){
nodes = new ArrayList<GossipManager>();
}
@After
public void after(){
for (GossipManager node: nodes){
if (node !=null){
node.shutdown();
}
}
}
}

View File

@ -17,26 +17,26 @@
*/ */
package org.apache.gossip; package org.apache.gossip;
import com.codahale.metrics.MetricRegistry;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.gossip.crdt.GrowOnlySet; import org.apache.gossip.crdt.GrowOnlySet;
import org.apache.gossip.crdt.OrSet; import org.apache.gossip.crdt.OrSet;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.SharedGossipDataMessage; import org.apache.gossip.manager.GossipManagerBuilder;
import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.SharedDataMessage;
import org.junit.Test; import org.junit.Test;
import io.teknek.tunit.TUnit; import io.teknek.tunit.TUnit;
public class DataTest { public class DataTest extends AbstractIntegrationBase {
private String orSetKey = "cror"; private String orSetKey = "cror";
@ -47,25 +47,25 @@ public class DataTest {
settings.setPersistDataState(false); settings.setPersistDataState(false);
String cluster = UUID.randomUUID().toString(); String cluster = UUID.randomUUID().toString();
int seedNodes = 1; int seedNodes = 1;
List<GossipMember> startupMembers = new ArrayList<>(); List<Member> 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" + ":" + (50000 + i)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
startupMembers.add(new RemoteGossipMember(cluster, uri, i + "")); startupMembers.add(new RemoteMember(cluster, uri, i + ""));
} }
final List<GossipService> clients = new ArrayList<>(); final List<GossipManager> clients = new ArrayList<>();
final int clusterMembers = 2; final int clusterMembers = 2;
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" + ":" + (50000 + i)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
GossipService gossipService = new GossipService(cluster, uri, i + "", GossipManager gossipService = GossipManagerBuilder.newBuilder().cluster(cluster).uri(uri)
new HashMap<String,String>(), startupMembers, settings, .id(i + "").gossipMembers(startupMembers).gossipSettings(settings).build();
(a,b) -> {}, new MetricRegistry());
clients.add(gossipService); clients.add(gossipService);
gossipService.start(); gossipService.init();
register(gossipService);
} }
TUnit.assertThat(() -> { TUnit.assertThat(() -> {
int total = 0; int total = 0;
for (int i = 0; i < clusterMembers; ++i) { for (int i = 0; i < clusterMembers; ++i) {
total += clients.get(i).getGossipManager().getLiveMembers().size(); total += clients.get(i).getLiveMembers().size();
} }
return total; return total;
}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(2); }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(2);
@ -73,7 +73,7 @@ public class DataTest {
clients.get(0).gossipSharedData(sharedMsg()); clients.get(0).gossipSharedData(sharedMsg());
TUnit.assertThat(()-> { TUnit.assertThat(()-> {
GossipDataMessage x = clients.get(1).findPerNodeData(1 + "", "a"); PerNodeDataMessage x = clients.get(1).findPerNodeGossipData(1 + "", "a");
if (x == null) if (x == null)
return ""; return "";
else else
@ -81,7 +81,7 @@ public class DataTest {
}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("b"); }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo("b");
TUnit.assertThat(() -> { TUnit.assertThat(() -> {
SharedGossipDataMessage x = clients.get(1).findSharedData("a"); SharedDataMessage x = clients.get(1).findSharedGossipData("a");
if (x == null) if (x == null)
return ""; return "";
else else
@ -95,71 +95,67 @@ public class DataTest {
assertThatOrSetIsMerged(clients); assertThatOrSetIsMerged(clients);
dropIt(clients); dropIt(clients);
assertThatOrSetDelIsMerged(clients); assertThatOrSetDelIsMerged(clients);
for (int i = 0; i < clusterMembers; ++i) {
clients.get(i).shutdown();
}
} }
private void givenOrs(List<GossipService> clients) { private void givenOrs(List<GossipManager> clients) {
{ {
SharedGossipDataMessage d = new SharedGossipDataMessage(); SharedDataMessage d = new SharedDataMessage();
d.setKey(orSetKey); d.setKey(orSetKey);
d.setPayload(new OrSet<String>("1", "2")); d.setPayload(new OrSet<String>("1", "2"));
d.setExpireAt(Long.MAX_VALUE); d.setExpireAt(Long.MAX_VALUE);
d.setTimestamp(System.currentTimeMillis()); d.setTimestamp(System.currentTimeMillis());
clients.get(0).getGossipManager().merge(d); clients.get(0).merge(d);
} }
{ {
SharedGossipDataMessage d = new SharedGossipDataMessage(); SharedDataMessage d = new SharedDataMessage();
d.setKey(orSetKey); d.setKey(orSetKey);
d.setPayload(new OrSet<String>("3", "4")); d.setPayload(new OrSet<String>("3", "4"));
d.setExpireAt(Long.MAX_VALUE); d.setExpireAt(Long.MAX_VALUE);
d.setTimestamp(System.currentTimeMillis()); d.setTimestamp(System.currentTimeMillis());
clients.get(1).getGossipManager().merge(d); clients.get(1).merge(d);
} }
} }
private void dropIt(List<GossipService> clients) { private void dropIt(List<GossipManager> clients) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
OrSet<String> o = (OrSet<String>) clients.get(0).getGossipManager().findCrdt(orSetKey); OrSet<String> o = (OrSet<String>) clients.get(0).findCrdt(orSetKey);
OrSet<String> o2 = new OrSet<String>(o, new OrSet.Builder<String>().remove("3")); OrSet<String> o2 = new OrSet<String>(o, new OrSet.Builder<String>().remove("3"));
SharedGossipDataMessage d = new SharedGossipDataMessage(); SharedDataMessage d = new SharedDataMessage();
d.setKey(orSetKey); d.setKey(orSetKey);
d.setPayload(o2); d.setPayload(o2);
d.setExpireAt(Long.MAX_VALUE); d.setExpireAt(Long.MAX_VALUE);
d.setTimestamp(System.currentTimeMillis()); d.setTimestamp(System.currentTimeMillis());
clients.get(0).getGossipManager().merge(d); clients.get(0).merge(d);
} }
private void assertThatOrSetIsMerged(final List<GossipService> clients){ private void assertThatOrSetIsMerged(final List<GossipManager> clients){
TUnit.assertThat(() -> { TUnit.assertThat(() -> {
return clients.get(0).getGossipManager().findCrdt(orSetKey).value(); return clients.get(0).findCrdt(orSetKey).value();
}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(new OrSet<String>("1", "2", "3", "4").value()); }).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(new OrSet<String>("1", "2", "3", "4").value());
TUnit.assertThat(() -> { TUnit.assertThat(() -> {
return clients.get(1).getGossipManager().findCrdt(orSetKey).value(); return clients.get(1).findCrdt(orSetKey).value();
}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(new OrSet<String>("1", "2", "3", "4").value()); }).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(new OrSet<String>("1", "2", "3", "4").value());
} }
private void assertThatOrSetDelIsMerged(final List<GossipService> clients){ private void assertThatOrSetDelIsMerged(final List<GossipManager> clients){
TUnit.assertThat(() -> { TUnit.assertThat(() -> {
return clients.get(0).getGossipManager().findCrdt(orSetKey); return clients.get(0).findCrdt(orSetKey);
}).afterWaitingAtMost(10, TimeUnit.SECONDS).equals(new OrSet<String>("1", "2", "4")); }).afterWaitingAtMost(10, TimeUnit.SECONDS).equals(new OrSet<String>("1", "2", "4"));
} }
private void givenDifferentDatumsInSet(final List<GossipService> clients){ private void givenDifferentDatumsInSet(final List<GossipManager> clients){
clients.get(0).getGossipManager().merge(CrdtMessage("1")); clients.get(0).merge(CrdtMessage("1"));
clients.get(1).getGossipManager().merge(CrdtMessage("2")); clients.get(1).merge(CrdtMessage("2"));
} }
private void assertThatListIsMerged(final List<GossipService> clients){ private void assertThatListIsMerged(final List<GossipManager> clients){
TUnit.assertThat(() -> { TUnit.assertThat(() -> {
return clients.get(0).getGossipManager().findCrdt("cr"); return clients.get(0).findCrdt("cr");
}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(new GrowOnlySet<String>(Arrays.asList("1","2"))); }).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(new GrowOnlySet<String>(Arrays.asList("1","2")));
} }
private SharedGossipDataMessage CrdtMessage(String item){ private SharedDataMessage CrdtMessage(String item){
SharedGossipDataMessage d = new SharedGossipDataMessage(); SharedDataMessage d = new SharedDataMessage();
d.setKey("cr"); d.setKey("cr");
d.setPayload(new GrowOnlySet<String>( Arrays.asList(item))); d.setPayload(new GrowOnlySet<String>( Arrays.asList(item)));
d.setExpireAt(Long.MAX_VALUE); d.setExpireAt(Long.MAX_VALUE);
@ -167,8 +163,8 @@ public class DataTest {
return d; return d;
} }
private GossipDataMessage msg(){ private PerNodeDataMessage msg(){
GossipDataMessage g = new GossipDataMessage(); PerNodeDataMessage g = new PerNodeDataMessage();
g.setExpireAt(Long.MAX_VALUE); g.setExpireAt(Long.MAX_VALUE);
g.setKey("a"); g.setKey("a");
g.setPayload("b"); g.setPayload("b");
@ -176,8 +172,8 @@ public class DataTest {
return g; return g;
} }
private SharedGossipDataMessage sharedMsg(){ private SharedDataMessage sharedMsg(){
SharedGossipDataMessage g = new SharedGossipDataMessage(); SharedDataMessage g = new SharedDataMessage();
g.setExpireAt(Long.MAX_VALUE); g.setExpireAt(Long.MAX_VALUE);
g.setKey("a"); g.setKey("a");
g.setPayload("c"); g.setPayload("c");

View File

@ -28,43 +28,54 @@ 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.DatacenterRackAwareActiveGossiper;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import com.codahale.metrics.MetricRegistry;
import io.teknek.tunit.TUnit; import io.teknek.tunit.TUnit;
@RunWith(JUnitPlatform.class) @RunWith(JUnitPlatform.class)
public class IdAndPropertyTest { public class IdAndPropertyTest extends AbstractIntegrationBase {
@Test @Test
public void testDatacenterRackGossiper() throws URISyntaxException, UnknownHostException, InterruptedException{ public void testDatacenterRackGossiper() throws URISyntaxException, UnknownHostException, InterruptedException {
GossipSettings settings = new GossipSettings(); GossipSettings settings = new GossipSettings();
settings.setActiveGossipClass(DatacenterRackAwareActiveGossiper.class.getName()); settings.setActiveGossipClass(DatacenterRackAwareActiveGossiper.class.getName());
List<GossipMember> startupMembers = new ArrayList<>(); List<Member> startupMembers = new ArrayList<>();
Map<String, String> x = new HashMap<>(); Map<String, String> x = new HashMap<>();
x.put("a", "b"); x.put("a", "b");
x.put("datacenter", "dc1"); x.put("datacenter", "dc1");
x.put("rack", "rack1"); x.put("rack", "rack1");
GossipService gossipService1 = new GossipService("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0)), "0", x, startupMembers, settings, GossipManager gossipService1 = GossipManagerBuilder.newBuilder()
(a, b) -> {}, new MetricRegistry()); .cluster("a")
gossipService1.start(); .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0)))
.id("0")
.properties(x)
.gossipMembers(startupMembers)
.gossipSettings(settings).build();
gossipService1.init();
register(gossipService1);
Map<String, String> y = new HashMap<>(); Map<String, String> y = new HashMap<>();
y.put("a", "c"); y.put("a", "c");
y.put("datacenter", "dc2"); y.put("datacenter", "dc2");
y.put("rack", "rack2"); y.put("rack", "rack2");
GossipService gossipService2 = new GossipService("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)), "1", y, GossipManager gossipService2 = GossipManagerBuilder.newBuilder().cluster("a")
Arrays.asList(new RemoteGossipMember("a", .uri( new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0)), "0")), .id("1")
settings, (a, b) -> { }, new MetricRegistry()); .properties(y)
gossipService2.start(); .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(() -> { TUnit.assertThat(() -> {
String value = ""; String value = "";
try { try {
value = gossipService1.getGossipManager().getLiveMembers().get(0).getProperties().get("a"); value = gossipService1.getLiveMembers().get(0).getProperties().get("a");
} catch (RuntimeException e){ } } catch (RuntimeException e){ }
return value; return value;
}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo("c"); }).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo("c");
@ -72,12 +83,9 @@ public class IdAndPropertyTest {
TUnit.assertThat(() -> { TUnit.assertThat(() -> {
String value = ""; String value = "";
try { try {
value = gossipService2.getGossipManager().getLiveMembers().get(0).getProperties().get("a"); value = gossipService2.getLiveMembers().get(0).getProperties().get("a");
} catch (RuntimeException e){ } } catch (RuntimeException e){ }
return value; return value;
}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo("b"); }).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo("b");
gossipService1.shutdown();
gossipService2.shutdown();
} }
} }

View File

@ -27,14 +27,14 @@ import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@RunWith(JUnitPlatform.class) @RunWith(JUnitPlatform.class)
public class GossipMemberTest { public class MemberTest {
@Test @Test
public void testHashCodeFromGossip40() throws URISyntaxException { public void testHashCodeFromGossip40() throws URISyntaxException {
Assert.assertNotEquals( Assert.assertNotEquals(
new LocalGossipMember("mycluster", new URI("udp://4.4.4.4:1000"), "myid", 1, new HashMap<String,String>(), 10, 5, "exponential") new LocalMember("mycluster", new URI("udp://4.4.4.4:1000"), "myid", 1, new HashMap<String,String>(), 10, 5, "exponential")
.hashCode(), .hashCode(),
new LocalGossipMember("mycluster", new URI("udp://4.4.4.5:1005"), "yourid", 11, new HashMap<String,String>(), 11, 6, "exponential") new LocalMember("mycluster", new URI("udp://4.4.4.5:1005"), "yourid", 11, new HashMap<String,String>(), 11, 6, "exponential")
.hashCode()); .hashCode());
} }
} }

View File

@ -17,7 +17,6 @@
*/ */
package org.apache.gossip; package org.apache.gossip;
import com.codahale.metrics.MetricRegistry;
import io.teknek.tunit.TUnit; import io.teknek.tunit.TUnit;
import java.net.URI; import java.net.URI;
@ -25,13 +24,14 @@ import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.runner.JUnitPlatform;
@ -52,25 +52,31 @@ public class ShutdownDeadtimeTest {
settings.setPersistDataState(false); settings.setPersistDataState(false);
String cluster = UUID.randomUUID().toString(); String cluster = UUID.randomUUID().toString();
int seedNodes = 3; int seedNodes = 3;
List<GossipMember> startupMembers = new ArrayList<>(); List<Member> 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" + ":" + (30300 + i)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30300 + i));
startupMembers.add(new RemoteGossipMember(cluster, uri, i + "")); startupMembers.add(new RemoteMember(cluster, uri, i + ""));
} }
final List<GossipService> clients = Collections.synchronizedList(new ArrayList<GossipService>()); final List<GossipManager> clients = Collections.synchronizedList(new ArrayList<GossipManager>());
final int clusterMembers = 5; 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" + ":" + (30300 + i)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30300 + i));
GossipService gossipService = new GossipService(cluster, uri, i + "", new HashMap<String,String>(), startupMembers, GossipManager gossipService = GossipManagerBuilder.newBuilder()
settings, (a,b) -> {}, new MetricRegistry()); .cluster(cluster)
.uri(uri)
.id(i + "")
.gossipMembers(startupMembers)
.gossipSettings(settings)
.build();
clients.add(gossipService); clients.add(gossipService);
gossipService.start(); gossipService.init();
} }
TUnit.assertThat(new Callable<Integer>() { TUnit.assertThat(new Callable<Integer>() {
public Integer call() throws Exception { public Integer call() throws Exception {
int total = 0; int total = 0;
for (int i = 0; i < clusterMembers; ++i) { for (int i = 0; i < clusterMembers; ++i) {
total += clients.get(i).getGossipManager().getLiveMembers().size(); total += clients.get(i).getLiveMembers().size();
} }
return total; return total;
} }
@ -79,15 +85,15 @@ public class ShutdownDeadtimeTest {
Random r = new Random(); Random r = new Random();
int randomClientId = r.nextInt(clusterMembers); int randomClientId = r.nextInt(clusterMembers);
log.info("shutting down " + randomClientId); log.info("shutting down " + randomClientId);
final int shutdownPort = clients.get(randomClientId).getGossipManager().getMyself().getUri() final int shutdownPort = clients.get(randomClientId).getMyself().getUri()
.getPort(); .getPort();
final String shutdownId = clients.get(randomClientId).getGossipManager().getMyself().getId(); final String shutdownId = clients.get(randomClientId).getMyself().getId();
clients.get(randomClientId).shutdown(); clients.get(randomClientId).shutdown();
TUnit.assertThat(new Callable<Integer>() { TUnit.assertThat(new Callable<Integer>() {
public Integer call() throws Exception { public Integer call() throws Exception {
int total = 0; int total = 0;
for (int i = 0; i < clusterMembers; ++i) { for (int i = 0; i < clusterMembers; ++i) {
total += clients.get(i).getGossipManager().getLiveMembers().size(); total += clients.get(i).getLiveMembers().size();
} }
return total; return total;
} }
@ -98,7 +104,7 @@ public class ShutdownDeadtimeTest {
public Integer call() throws Exception { public Integer call() throws Exception {
int total = 0; int total = 0;
for (int i = 0; i < clusterMembers - 1; ++i) { for (int i = 0; i < clusterMembers - 1; ++i) {
total += clients.get(i).getGossipManager().getDeadMembers().size(); total += clients.get(i).getDeadMembers().size();
} }
return total; return total;
} }
@ -106,17 +112,22 @@ public class ShutdownDeadtimeTest {
URI uri = new URI("udp://" + "127.0.0.1" + ":" + shutdownPort); URI uri = new URI("udp://" + "127.0.0.1" + ":" + shutdownPort);
// start client again // start client again
GossipService gossipService = new GossipService(cluster, uri, shutdownId + "", new HashMap<String,String>(), startupMembers, GossipManager gossipService = GossipManagerBuilder.newBuilder()
settings, (a,b) -> {}, new MetricRegistry()); .gossipSettings(settings)
.cluster(cluster)
.uri(uri)
.id(shutdownId+"")
.gossipMembers(startupMembers)
.build();
clients.add(gossipService); clients.add(gossipService);
gossipService.start(); gossipService.init();
// verify that the client is alive again for every node // verify that the client is alive again for every node
TUnit.assertThat(new Callable<Integer>() { TUnit.assertThat(new Callable<Integer>() {
public Integer call() throws Exception { public Integer call() throws Exception {
int total = 0; int total = 0;
for (int i = 0; i < clusterMembers; ++i) { for (int i = 0; i < clusterMembers; ++i) {
total += clients.get(i).getGossipManager().getLiveMembers().size(); total += clients.get(i).getLiveMembers().size();
} }
return total; return total;
} }

View File

@ -25,33 +25,36 @@ import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
import org.apache.gossip.manager.PassiveGossipConstants; import org.apache.gossip.manager.PassiveGossipConstants;
import org.apache.gossip.secure.KeyTool; import org.apache.gossip.secure.KeyTool;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import com.codahale.metrics.MetricRegistry;
import io.teknek.tunit.TUnit; import io.teknek.tunit.TUnit;
public class SignedMessageTest { public class SignedMessageTest extends AbstractIntegrationBase {
@Test(expected=IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void ifSignMustHaveKeys() public void ifSignMustHaveKeys()
throws URISyntaxException, UnknownHostException, InterruptedException { throws URISyntaxException, UnknownHostException, InterruptedException {
String cluster = UUID.randomUUID().toString(); String cluster = UUID.randomUUID().toString();
GossipSettings settings = gossiperThatSigns(); GossipSettings settings = gossiperThatSigns();
List<GossipMember> startupMembers = new ArrayList<>(); List<Member> startupMembers = new ArrayList<>();
URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30000 + 1)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30000 + 1));
GossipService gossipService = new GossipService(cluster, uri, 1 + "", GossipManager gossipService = GossipManagerBuilder.newBuilder()
new HashMap<String, String>(), startupMembers, settings, (a, b) -> { }, .cluster(cluster)
new MetricRegistry()); .uri(uri)
gossipService.start(); .id(1 + "")
.gossipMembers(startupMembers)
.gossipSettings(settings)
.build();
gossipService.init();
} }
private GossipSettings gossiperThatSigns(){ private GossipSettings gossiperThatSigns(){
@ -63,48 +66,52 @@ public class SignedMessageTest {
} }
@Test @Test
public void dataTest() throws InterruptedException, URISyntaxException, NoSuchAlgorithmException, NoSuchProviderException, IOException{ public void dataTest() throws InterruptedException, URISyntaxException, NoSuchAlgorithmException, NoSuchProviderException, IOException {
String keys = "./keys"; String keys = "./keys";
GossipSettings settings = gossiperThatSigns(); GossipSettings settings = gossiperThatSigns();
setup(keys); setup(keys);
String cluster = UUID.randomUUID().toString(); String cluster = UUID.randomUUID().toString();
List<GossipMember> startupMembers = new ArrayList<>(); List<Member> startupMembers = new ArrayList<>();
for (int i = 1; i < 2; ++i) { for (int i = 1; i < 2; ++i) {
URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30000 + i)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30000 + i));
startupMembers.add(new RemoteGossipMember(cluster, uri, i + "")); startupMembers.add(new RemoteMember(cluster, uri, i + ""));
} }
final List<GossipService> clients = new ArrayList<>(); final List<GossipManager> clients = new ArrayList<>();
for (int i = 1; i < 3; ++i) { for (int i = 1; i < 3; ++i) {
URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30000 + i)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (30000 + i));
GossipService gossipService = new GossipService(cluster, uri, i + "", GossipManager gossipService = GossipManagerBuilder.newBuilder()
new HashMap<String,String>(), startupMembers, settings, .cluster(cluster)
(a,b) -> {}, new MetricRegistry()); .uri(uri)
.id(i + "")
.gossipMembers(startupMembers)
.gossipSettings(settings)
.build();
gossipService.init();
clients.add(gossipService); clients.add(gossipService);
gossipService.start();
} }
assertTwoAlive(clients); assertTwoAlive(clients);
assertOnlySignedMessages(clients); assertOnlySignedMessages(clients);
cleanup(keys, clients); cleanup(keys, clients);
} }
private void assertTwoAlive(List<GossipService> clients){ private void assertTwoAlive(List<GossipManager> clients){
TUnit.assertThat(() -> { TUnit.assertThat(() -> {
int total = 0; int total = 0;
for (int i = 0; i < clients.size(); ++i) { for (int i = 0; i < clients.size(); ++i) {
total += clients.get(i).getGossipManager().getLiveMembers().size(); total += clients.get(i).getLiveMembers().size();
} }
return total; return total;
}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(2); }).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(2);
} }
private void assertOnlySignedMessages(List<GossipService> clients){ private void assertOnlySignedMessages(List<GossipManager> clients){
Assert.assertEquals(0, clients.get(0).getGossipManager().getRegistry() Assert.assertEquals(0, clients.get(0).getRegistry()
.meter(PassiveGossipConstants.UNSIGNED_MESSAGE).getCount()); .meter(PassiveGossipConstants.UNSIGNED_MESSAGE).getCount());
Assert.assertTrue(clients.get(0).getGossipManager().getRegistry() Assert.assertTrue(clients.get(0).getRegistry()
.meter(PassiveGossipConstants.SIGNED_MESSAGE).getCount() > 0); .meter(PassiveGossipConstants.SIGNED_MESSAGE).getCount() > 0);
} }
private void cleanup(String keys, List<GossipService> clients){ private void cleanup(String keys, List<GossipManager> clients){
new File(keys, "1").delete(); new File(keys, "1").delete();
new File(keys, "2").delete(); new File(keys, "2").delete();
new File(keys).delete(); new File(keys).delete();

View File

@ -17,7 +17,8 @@
*/ */
package org.apache.gossip; package org.apache.gossip;
import com.codahale.metrics.MetricRegistry; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -27,8 +28,6 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -39,7 +38,7 @@ import org.junit.runner.RunWith;
*/ */
@RunWith(JUnitPlatform.class) @RunWith(JUnitPlatform.class)
public class StartupSettingsTest { public class StartupSettingsTest {
private static final Logger log = Logger.getLogger( StartupSettingsTest.class ); private static final Logger log = Logger.getLogger(StartupSettingsTest.class);
private static final String CLUSTER = UUID.randomUUID().toString(); private static final String CLUSTER = UUID.randomUUID().toString();
@Test @Test
@ -48,15 +47,17 @@ public class StartupSettingsTest {
settingsFile.deleteOnExit(); settingsFile.deleteOnExit();
writeSettingsFile(settingsFile); writeSettingsFile(settingsFile);
URI uri = new URI("udp://" + "127.0.0.1" + ":" + 50000); URI uri = new URI("udp://" + "127.0.0.1" + ":" + 50000);
final GossipService firstService = new GossipService( GossipManager firstService = GossipManagerBuilder.newBuilder()
CLUSTER, uri, "1", new HashMap<String, String>(), .cluster(CLUSTER)
new ArrayList<GossipMember>(), new GossipSettings(), null, new MetricRegistry()); .uri(uri)
firstService.start(); .id("1")
final GossipService serviceUnderTest = new GossipService( .gossipSettings(new GossipSettings()).build();
StartupSettings.fromJSONFile(settingsFile)); firstService.init();
serviceUnderTest.start(); GossipManager manager = GossipManagerBuilder.newBuilder()
.startupSettings(StartupSettings.fromJSONFile(settingsFile)).build();
manager.init();
firstService.shutdown(); firstService.shutdown();
serviceUnderTest.shutdown(); manager.shutdown();
} }
private void writeSettingsFile( File target ) throws IOException { private void writeSettingsFile( File target ) throws IOException {

View File

@ -17,20 +17,20 @@
*/ */
package org.apache.gossip; package org.apache.gossip;
import com.codahale.metrics.MetricRegistry;
import io.teknek.tunit.TUnit; import io.teknek.tunit.TUnit;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@RunWith(JUnitPlatform.class) @RunWith(JUnitPlatform.class)
@ -42,35 +42,40 @@ public class TenNodeThreeSeedTest {
} }
@Test @Test
public void testAgain() throws UnknownHostException, InterruptedException, URISyntaxException{ public void testAgain() throws UnknownHostException, InterruptedException, URISyntaxException {
abc(30100); abc(30100);
} }
public void abc(int base) throws InterruptedException, UnknownHostException, URISyntaxException{ public void abc(int base) throws InterruptedException, UnknownHostException, URISyntaxException {
GossipSettings settings = new GossipSettings(1000, 10000, 1000, 1, 2.0, "exponential"); GossipSettings settings = new GossipSettings(1000, 10000, 1000, 1, 1.6, "exponential");
settings.setPersistRingState(false); settings.setPersistRingState(false);
settings.setPersistDataState(false); settings.setPersistDataState(false);
String cluster = UUID.randomUUID().toString(); String cluster = UUID.randomUUID().toString();
int seedNodes = 3; int seedNodes = 3;
List<GossipMember> startupMembers = new ArrayList<>(); List<Member> 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)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (base + i));
startupMembers.add(new RemoteGossipMember(cluster, uri, i + "")); startupMembers.add(new RemoteMember(cluster, uri, i + ""));
} }
final List<GossipService> clients = new ArrayList<>(); final List<GossipManager> clients = new ArrayList<>();
final int clusterMembers = 5; 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)); URI uri = new URI("udp://" + "127.0.0.1" + ":" + (base + i));
GossipService gossipService = new GossipService(cluster, uri, i + "", new HashMap<String,String>(), GossipManager gossipService = GossipManagerBuilder.newBuilder()
startupMembers, settings, (a,b) -> {}, new MetricRegistry()); .cluster(cluster)
.uri(uri)
.id(i + "")
.gossipSettings(settings)
.gossipMembers(startupMembers)
.build();
gossipService.init();
clients.add(gossipService); clients.add(gossipService);
gossipService.start();
} }
TUnit.assertThat(new Callable<Integer> (){ TUnit.assertThat(new Callable<Integer> (){
public Integer call() throws Exception { public Integer call() throws Exception {
int total = 0; int total = 0;
for (int i = 0; i < clusterMembers; ++i) { for (int i = 0; i < clusterMembers; ++i) {
total += clients.get(i).getGossipManager().getLiveMembers().size(); total += clients.get(i).getLiveMembers().size();
} }
return total; return total;
}}).afterWaitingAtMost(40, TimeUnit.SECONDS).isEqualTo(20); }}).afterWaitingAtMost(40, TimeUnit.SECONDS).isEqualTo(20);

View File

@ -19,7 +19,7 @@ package org.apache.gossip.accrual;
import java.net.URI; import java.net.URI;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -33,7 +33,7 @@ public class FailureDetectorTest {
public void aNormalTest(){ public void aNormalTest(){
int samples = 1; int samples = 1;
int windowSize = 1000; int windowSize = 1000;
LocalGossipMember member = new LocalGossipMember("", URI.create("udp://127.0.0.1:1000"), LocalMember member = new LocalMember("", URI.create("udp://127.0.0.1:1000"),
"", 0L, null, windowSize, samples, "normal"); "", 0L, null, windowSize, samples, "normal");
member.recordHeartbeat(5); member.recordHeartbeat(5);
member.recordHeartbeat(10); member.recordHeartbeat(10);
@ -44,7 +44,7 @@ public class FailureDetectorTest {
public void aTest(){ public void aTest(){
int samples = 1; int samples = 1;
int windowSize = 1000; int windowSize = 1000;
LocalGossipMember member = new LocalGossipMember("", URI.create("udp://127.0.0.1:1000"), LocalMember member = new LocalMember("", URI.create("udp://127.0.0.1:1000"),
"", 0L, null, windowSize, samples, "exponential"); "", 0L, null, windowSize, samples, "exponential");
member.recordHeartbeat(5); member.recordHeartbeat(5);
member.recordHeartbeat(10); member.recordHeartbeat(10);
@ -64,7 +64,7 @@ public class FailureDetectorTest {
public void sameHeartbeatTest(){ public void sameHeartbeatTest(){
int samples = 1; int samples = 1;
int windowSize = 1000; int windowSize = 1000;
LocalGossipMember member = new LocalGossipMember("", URI.create("udp://127.0.0.1:1000"), LocalMember member = new LocalMember("", URI.create("udp://127.0.0.1:1000"),
"", 0L, null, windowSize, samples, "exponential"); "", 0L, null, windowSize, samples, "exponential");
member.recordHeartbeat(5); member.recordHeartbeat(5);
member.recordHeartbeat(5); member.recordHeartbeat(5);

View File

@ -21,18 +21,15 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import org.apache.gossip.GossipService;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.RemoteGossipMember; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.manager.GossipManagerBuilder;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import com.codahale.metrics.MetricRegistry;
public class OrSetTest { public class OrSetTest {
@Test @Test
@ -91,14 +88,16 @@ public class OrSetTest {
@Test @Test
public void serialTest() throws InterruptedException, URISyntaxException, IOException { public void serialTest() throws InterruptedException, URISyntaxException, IOException {
GossipService gossipService2 = new GossipService("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)), "1", new HashMap<>(), GossipManager gossipService2 = GossipManagerBuilder.newBuilder()
Arrays.asList(new RemoteGossipMember("a", .cluster("a")
new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0)), "0")), .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
new GossipSettings(), (a, b) -> { }, new MetricRegistry()); .id("1")
.gossipSettings(new GossipSettings())
.build();
OrSet<Integer> i = new OrSet<Integer>(new OrSet.Builder<Integer>().add(1).remove(1)); OrSet<Integer> i = new OrSet<Integer>(new OrSet.Builder<Integer>().add(1).remove(1));
String s = gossipService2.getGossipManager().getObjectMapper().writeValueAsString(i); String s = gossipService2.getObjectMapper().writeValueAsString(i);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
OrSet<Integer> back = gossipService2.getGossipManager().getObjectMapper().readValue(s, OrSet.class); OrSet<Integer> back = gossipService2.getObjectMapper().readValue(s, OrSet.class);
Assert.assertEquals(back, i); Assert.assertEquals(back, i);
} }

View File

@ -21,9 +21,8 @@ import com.codahale.metrics.MetricRegistry;
import java.net.URI; import java.net.URI;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.manager.random.RandomGossipManager; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.apache.gossip.model.SharedGossipDataMessage;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -41,8 +40,8 @@ public class DataReaperTest {
GossipSettings settings = new GossipSettings(); GossipSettings settings = new GossipSettings();
settings.setPersistRingState(false); settings.setPersistRingState(false);
settings.setPersistDataState(false); settings.setPersistDataState(false);
GossipManager gm = RandomGossipManager.newBuilder().cluster("abc").settings(settings) GossipManager gm = GossipManagerBuilder.newBuilder().cluster("abc").gossipSettings(settings)
.withId(myId).uri(URI.create("udp://localhost:6000")).registry(registry).build(); .id(myId).uri(URI.create("udp://localhost:6000")).registry(registry).build();
gm.init(); gm.init();
gm.gossipPerNodeData(perNodeDatum(key, value)); gm.gossipPerNodeData(perNodeDatum(key, value));
gm.gossipSharedData(sharedDatum(key, value)); gm.gossipSharedData(sharedDatum(key, value));
@ -65,8 +64,8 @@ public class DataReaperTest {
TUnit.assertThat(() -> gm.findSharedGossipData(key)).equals(null); TUnit.assertThat(() -> gm.findSharedGossipData(key)).equals(null);
} }
private GossipDataMessage perNodeDatum(String key, String value) { private PerNodeDataMessage perNodeDatum(String key, String value) {
GossipDataMessage m = new GossipDataMessage(); PerNodeDataMessage m = new PerNodeDataMessage();
m.setExpireAt(System.currentTimeMillis() + 5L); m.setExpireAt(System.currentTimeMillis() + 5L);
m.setKey(key); m.setKey(key);
m.setPayload(value); m.setPayload(value);
@ -74,8 +73,8 @@ public class DataReaperTest {
return m; return m;
} }
private SharedGossipDataMessage sharedDatum(String key, String value) { private SharedDataMessage sharedDatum(String key, String value) {
SharedGossipDataMessage m = new SharedGossipDataMessage(); SharedDataMessage m = new SharedDataMessage();
m.setExpireAt(System.currentTimeMillis() + 5L); m.setExpireAt(System.currentTimeMillis() + 5L);
m.setKey(key); m.setKey(key);
m.setPayload(value); m.setPayload(value);
@ -89,11 +88,11 @@ public class DataReaperTest {
String key = "key"; String key = "key";
String value = "a"; String value = "a";
GossipSettings settings = new GossipSettings(); GossipSettings settings = new GossipSettings();
GossipManager gm = RandomGossipManager.newBuilder().cluster("abc").settings(settings) GossipManager gm = GossipManagerBuilder.newBuilder().cluster("abc").gossipSettings(settings)
.withId(myId).uri(URI.create("udp://localhost:7000")).registry(registry).build(); .id(myId).uri(URI.create("udp://localhost:7000")).registry(registry).build();
gm.init(); gm.init();
GossipDataMessage before = perNodeDatum(key, value); PerNodeDataMessage before = perNodeDatum(key, value);
GossipDataMessage after = perNodeDatum(key, "b"); PerNodeDataMessage after = perNodeDatum(key, "b");
after.setTimestamp(after.getTimestamp() - 1); after.setTimestamp(after.getTimestamp() - 1);
gm.gossipPerNodeData(before); gm.gossipPerNodeData(before);
Assert.assertEquals(value, gm.findPerNodeGossipData(myId, key).getPayload()); Assert.assertEquals(value, gm.findPerNodeGossipData(myId, key).getPayload());

View File

@ -18,14 +18,13 @@
package org.apache.gossip.manager; package org.apache.gossip.manager;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import org.apache.gossip.GossipMember; import org.apache.gossip.Member;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.LocalGossipMember; import org.apache.gossip.LocalMember;
import org.apache.gossip.manager.handlers.DefaultMessageInvoker; import org.apache.gossip.manager.handlers.DefaultMessageInvoker;
import org.apache.gossip.manager.handlers.MessageInvoker; import org.apache.gossip.manager.handlers.MessageInvoker;
import org.apache.gossip.manager.handlers.ResponseHandler; import org.apache.gossip.manager.handlers.ResponseHandler;
import org.apache.gossip.manager.handlers.SimpleMessageInvoker; import org.apache.gossip.manager.handlers.SimpleMessageInvoker;
import org.apache.gossip.manager.random.RandomGossipManager;
import org.junit.Assert; import org.junit.Assert;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.runner.JUnitPlatform;
@ -43,47 +42,47 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.expectThrows; import static org.junit.jupiter.api.Assertions.expectThrows;
@RunWith(JUnitPlatform.class) @RunWith(JUnitPlatform.class)
public class RandomGossipManagerBuilderTest { public class GossipManagerBuilderTest {
@Test @Test
public void idShouldNotBeNull() { public void idShouldNotBeNull() {
expectThrows(IllegalArgumentException.class,() -> { expectThrows(IllegalArgumentException.class,() -> {
RandomGossipManager.newBuilder().cluster("aCluster").build(); GossipManagerBuilder.newBuilder().cluster("aCluster").build();
}); });
} }
@Test @Test
public void clusterShouldNotBeNull() { public void clusterShouldNotBeNull() {
expectThrows(IllegalArgumentException.class,() -> { expectThrows(IllegalArgumentException.class,() -> {
RandomGossipManager.newBuilder().withId("id").build(); GossipManagerBuilder.newBuilder().id("id").build();
}); });
} }
@Test @Test
public void settingsShouldNotBeNull() { public void settingsShouldNotBeNull() {
expectThrows(IllegalArgumentException.class,() -> { expectThrows(IllegalArgumentException.class,() -> {
RandomGossipManager.newBuilder().withId("id").cluster("aCluster").build(); GossipManagerBuilder.newBuilder().id("id").cluster("aCluster").build();
}); });
} }
@Test @Test
public void createMembersListIfNull() throws URISyntaxException { public void createMembersListIfNull() throws URISyntaxException {
RandomGossipManager gossipManager = RandomGossipManager.newBuilder() GossipManager gossipManager = GossipManagerBuilder.newBuilder()
.withId("id") .id("id")
.cluster("aCluster") .cluster("aCluster")
.uri(new URI("udp://localhost:2000")) .uri(new URI("udp://localhost:2000"))
.settings(new GossipSettings()) .gossipSettings(new GossipSettings())
.gossipMembers(null).registry(new MetricRegistry()).build(); .gossipMembers(null).registry(new MetricRegistry()).build();
assertNotNull(gossipManager.getLiveMembers()); assertNotNull(gossipManager.getLiveMembers());
} }
@Test @Test
public void createDefaultMessageInvokerIfNull() throws URISyntaxException { public void createDefaultMessageInvokerIfNull() throws URISyntaxException {
RandomGossipManager gossipManager = RandomGossipManager.newBuilder() GossipManager gossipManager = GossipManagerBuilder.newBuilder()
.withId("id") .id("id")
.cluster("aCluster") .cluster("aCluster")
.uri(new URI("udp://localhost:2000")) .uri(new URI("udp://localhost:2000"))
.settings(new GossipSettings()) .gossipSettings(new GossipSettings())
.messageInvoker(null).registry(new MetricRegistry()).build(); .messageInvoker(null).registry(new MetricRegistry()).build();
assertNotNull(gossipManager.getMessageInvoker()); assertNotNull(gossipManager.getMessageInvoker());
Assert.assertEquals(gossipManager.getMessageInvoker().getClass(), new DefaultMessageInvoker().getClass()); Assert.assertEquals(gossipManager.getMessageInvoker().getClass(), new DefaultMessageInvoker().getClass());
@ -92,11 +91,11 @@ public class RandomGossipManagerBuilderTest {
@Test @Test
public void testMessageInvokerKeeping() throws URISyntaxException { public void testMessageInvokerKeeping() throws URISyntaxException {
MessageInvoker mi = new SimpleMessageInvoker(Response.class, new ResponseHandler()); MessageInvoker mi = new SimpleMessageInvoker(Response.class, new ResponseHandler());
RandomGossipManager gossipManager = RandomGossipManager.newBuilder() GossipManager gossipManager = GossipManagerBuilder.newBuilder()
.withId("id") .id("id")
.cluster("aCluster") .cluster("aCluster")
.uri(new URI("udp://localhost:2000")) .uri(new URI("udp://localhost:2000"))
.settings(new GossipSettings()) .gossipSettings(new GossipSettings())
.messageInvoker(mi).registry(new MetricRegistry()).build(); .messageInvoker(mi).registry(new MetricRegistry()).build();
assertNotNull(gossipManager.getMessageInvoker()); assertNotNull(gossipManager.getMessageInvoker());
Assert.assertEquals(gossipManager.getMessageInvoker(), mi); Assert.assertEquals(gossipManager.getMessageInvoker(), mi);
@ -104,15 +103,15 @@ public class RandomGossipManagerBuilderTest {
@Test @Test
public void useMemberListIfProvided() throws URISyntaxException { public void useMemberListIfProvided() throws URISyntaxException {
LocalGossipMember member = new LocalGossipMember( LocalMember member = new LocalMember(
"aCluster", new URI("udp://localhost:2000"), "aGossipMember", "aCluster", new URI("udp://localhost:2000"), "aGossipMember",
System.nanoTime(), new HashMap<String, String>(), 1000, 1, "exponential"); System.nanoTime(), new HashMap<String, String>(), 1000, 1, "exponential");
List<GossipMember> memberList = new ArrayList<>(); List<Member> memberList = new ArrayList<>();
memberList.add(member); memberList.add(member);
RandomGossipManager gossipManager = RandomGossipManager.newBuilder() GossipManager gossipManager = GossipManagerBuilder.newBuilder()
.withId("id") .id("id")
.cluster("aCluster") .cluster("aCluster")
.settings(new GossipSettings()) .gossipSettings(new GossipSettings())
.uri(new URI("udp://localhost:8000")) .uri(new URI("udp://localhost:8000"))
.gossipMembers(memberList).registry(new MetricRegistry()).build(); .gossipMembers(memberList).registry(new MetricRegistry()).build();
assertEquals(1, gossipManager.getDeadMembers().size()); assertEquals(1, gossipManager.getDeadMembers().size());

View File

@ -22,15 +22,11 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import org.apache.gossip.GossipService;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.RemoteGossipMember; import org.apache.gossip.RemoteMember;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import com.codahale.metrics.MetricRegistry;
public class RingPersistenceTest { public class RingPersistenceTest {
@Test @Test
@ -43,21 +39,26 @@ public class RingPersistenceTest {
} }
private File aGossiperPersists(GossipSettings settings) throws UnknownHostException, InterruptedException, URISyntaxException { private File aGossiperPersists(GossipSettings settings) throws UnknownHostException, InterruptedException, URISyntaxException {
GossipService gossipService = new GossipService("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)), "1", new HashMap<String, String>(), GossipManager gossipService = GossipManagerBuilder.newBuilder()
Arrays.asList( .cluster("a")
new RemoteGossipMember("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0)), "0"), .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
new RemoteGossipMember("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 2)), "2") .id("1")
), .gossipSettings(settings)
settings, (a, b) -> { }, new MetricRegistry()); .gossipMembers(
gossipService.getGossipManager().getRingState().writeToDisk(); Arrays.asList(
return gossipService.getGossipManager().getRingState().computeTarget(); new RemoteMember("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 0)), "0"),
new RemoteMember("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 2)), "2"))).build();
gossipService.getRingState().writeToDisk();
return gossipService.getRingState().computeTarget();
} }
private void aNewInstanceGetsRingInfo(GossipSettings settings) throws UnknownHostException, InterruptedException, URISyntaxException{ private void aNewInstanceGetsRingInfo(GossipSettings settings) throws UnknownHostException, InterruptedException, URISyntaxException {
GossipService gossipService2 = new GossipService("a", new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)), "1", new HashMap<String, String>(), GossipManager gossipService2 = GossipManagerBuilder.newBuilder()
Arrays.asList(), .cluster("a")
settings, (a, b) -> { }, new MetricRegistry()); .uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
Assert.assertEquals(2, gossipService2.getGossipManager().getMembers().size()); .id("1")
.gossipSettings(settings).build();
Assert.assertEquals(2, gossipService2.getMembers().size());
} }
} }

View File

@ -21,64 +21,65 @@ import java.io.File;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.apache.gossip.GossipService;
import org.apache.gossip.GossipSettings; import org.apache.gossip.GossipSettings;
import org.apache.gossip.model.GossipDataMessage; import org.apache.gossip.model.PerNodeDataMessage;
import org.apache.gossip.model.SharedGossipDataMessage; import org.apache.gossip.model.SharedDataMessage;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import com.codahale.metrics.MetricRegistry;
public class UserDataPersistenceTest { public class UserDataPersistenceTest {
String nodeId = "1";
private GossipManager sameService() throws URISyntaxException {
GossipSettings settings = new GossipSettings();
return GossipManagerBuilder.newBuilder()
.cluster("a")
.uri(new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)))
.id(nodeId)
.gossipSettings(settings).build();
}
@Test @Test
public void givenThatRingIsPersisted() throws UnknownHostException, InterruptedException, URISyntaxException { public void givenThatRingIsPersisted() throws UnknownHostException, InterruptedException, URISyntaxException {
String nodeId = "1";
GossipSettings settings = new GossipSettings();
{ //Create a gossip service and force it to persist its user data { //Create a gossip service and force it to persist its user data
GossipService gossipService = new GossipService("a", GossipManager gossipService = sameService();
new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)), nodeId, new HashMap<String, String>(), gossipService.init();
Arrays.asList(), settings, (a, b) -> { }, new MetricRegistry());
gossipService.start();
gossipService.gossipPerNodeData(getToothpick()); gossipService.gossipPerNodeData(getToothpick());
gossipService.gossipSharedData(getAnotherToothpick()); gossipService.gossipSharedData(getAnotherToothpick());
gossipService.getGossipManager().getUserDataState().writePerNodeToDisk(); gossipService.getUserDataState().writePerNodeToDisk();
gossipService.getGossipManager().getUserDataState().writeSharedToDisk(); gossipService.getUserDataState().writeSharedToDisk();
{ //read the raw data and confirm { //read the raw data and confirm
ConcurrentHashMap<String, ConcurrentHashMap<String, GossipDataMessage>> l = gossipService.getGossipManager().getUserDataState().readPerNodeFromDisk(); ConcurrentHashMap<String, ConcurrentHashMap<String, PerNodeDataMessage>> l = gossipService.getUserDataState().readPerNodeFromDisk();
Assert.assertEquals("red", ((AToothpick) l.get(nodeId).get("a").getPayload()).getColor()); Assert.assertEquals("red", ((AToothpick) l.get(nodeId).get("a").getPayload()).getColor());
} }
{ {
ConcurrentHashMap<String, SharedGossipDataMessage> l = ConcurrentHashMap<String, SharedDataMessage> l =
gossipService.getGossipManager().getUserDataState().readSharedDataFromDisk(); gossipService.getUserDataState().readSharedDataFromDisk();
Assert.assertEquals("blue", ((AToothpick) l.get("a").getPayload()).getColor()); Assert.assertEquals("blue", ((AToothpick) l.get("a").getPayload()).getColor());
} }
gossipService.shutdown(); 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
GossipService gossipService = new GossipService("a", GossipManager gossipService = sameService();
new URI("udp://" + "127.0.0.1" + ":" + (29000 + 1)), nodeId, new HashMap<String, String>(), gossipService.init();
Arrays.asList(), settings, (a, b) -> { }, new MetricRegistry()); Assert.assertEquals("red", ((AToothpick) gossipService.findPerNodeGossipData(nodeId, "a").getPayload()).getColor());
gossipService.start(); Assert.assertEquals("blue", ((AToothpick) gossipService.findSharedGossipData("a").getPayload()).getColor());
Assert.assertEquals("red", ((AToothpick) gossipService.findPerNodeData(nodeId, "a").getPayload()).getColor()); File f = gossipService.getUserDataState().computeSharedTarget();
Assert.assertEquals("blue", ((AToothpick) gossipService.findSharedData("a").getPayload()).getColor()); File g = gossipService.getUserDataState().computePerNodeTarget();
File f = gossipService.getGossipManager().getUserDataState().computeSharedTarget();
File g = gossipService.getGossipManager().getUserDataState().computePerNodeTarget();
gossipService.shutdown(); gossipService.shutdown();
f.delete(); f.delete();
g.delete(); g.delete();
} }
} }
public GossipDataMessage getToothpick(){ public PerNodeDataMessage getToothpick(){
AToothpick a = new AToothpick(); AToothpick a = new AToothpick();
a.setColor("red"); a.setColor("red");
GossipDataMessage d = new GossipDataMessage(); PerNodeDataMessage d = new PerNodeDataMessage();
d.setExpireAt(Long.MAX_VALUE); d.setExpireAt(Long.MAX_VALUE);
d.setKey("a"); d.setKey("a");
d.setPayload(a); d.setPayload(a);
@ -86,10 +87,10 @@ public class UserDataPersistenceTest {
return d; return d;
} }
public SharedGossipDataMessage getAnotherToothpick(){ public SharedDataMessage getAnotherToothpick(){
AToothpick a = new AToothpick(); AToothpick a = new AToothpick();
a.setColor("blue"); a.setColor("blue");
SharedGossipDataMessage d = new SharedGossipDataMessage(); SharedDataMessage d = new SharedDataMessage();
d.setExpireAt(Long.MAX_VALUE); d.setExpireAt(Long.MAX_VALUE);
d.setKey("a"); d.setKey("a");
d.setPayload(a); d.setPayload(a);

View File

@ -21,7 +21,7 @@ import org.apache.gossip.manager.GossipCore;
import org.apache.gossip.manager.GossipManager; import org.apache.gossip.manager.GossipManager;
import org.apache.gossip.model.ActiveGossipMessage; import org.apache.gossip.model.ActiveGossipMessage;
import org.apache.gossip.model.Base; import org.apache.gossip.model.Base;
import org.apache.gossip.udp.UdpSharedGossipDataMessage; import org.apache.gossip.udp.UdpSharedDataMessage;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -166,7 +166,7 @@ public class MessageInvokerTest {
//UdpSharedGossipDataMessage with null gossipCore -> exception //UdpSharedGossipDataMessage with null gossipCore -> exception
boolean thrown = false; boolean thrown = false;
try { try {
mi.invoke(null, null, new UdpSharedGossipDataMessage()); mi.invoke(null, null, new UdpSharedDataMessage());
} catch (NullPointerException e) { } catch (NullPointerException e) {
thrown = true; thrown = true;
} }