use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class RaftReconfigurationBaseTest method testKillLeaderDuringReconf.
/**
* kill the leader before reconfiguration finishes. Make sure the client keeps
* retrying.
*/
@Test
public void testKillLeaderDuringReconf() throws Exception {
LOG.info("Start testKillLeaderDuringReconf");
// originally 3 peers
final MiniRaftCluster cluster = getCluster(3);
cluster.start();
try {
RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = cluster.getLeader().getId();
final RaftClient client = cluster.createClient(leaderId);
PeerChanges c1 = cluster.addNewPeers(2, false);
PeerChanges c2 = cluster.removePeers(2, false, asList(c1.newPeers));
LOG.info("Start changing the configuration: {}", asList(c2.allPeersInNewConf));
final AtomicReference<Boolean> success = new AtomicReference<>();
final AtomicBoolean clientRunning = new AtomicBoolean(true);
Thread clientThread = new Thread(() -> {
try {
boolean r = false;
while (clientRunning.get() && !r) {
r = client.setConfiguration(c2.allPeersInNewConf).isSuccess();
}
success.set(r);
client.close();
} catch (IOException ignored) {
}
});
clientThread.start();
// the leader cannot generate the (old, new) conf, and it will keep
// bootstrapping the 2 new peers since they have not started yet
LOG.info(cluster.printServers());
Assert.assertFalse(cluster.getLeader().getRaftConf().isTransitional());
// only the first empty entry got committed
final long committedIndex = cluster.getLeader().getState().getLog().getLastCommittedIndex();
Assert.assertTrue("committedIndex is " + committedIndex, committedIndex <= 1);
LOG.info("kill the current leader");
final String oldLeaderId = RaftTestUtil.waitAndKillLeader(cluster, true);
LOG.info("start the two new peers: {}", Arrays.asList(c1.newPeers));
for (RaftPeer np : c1.newPeers) {
cluster.startServer(np.getId());
}
Thread.sleep(3000);
// the client should get the NotLeaderException from the first leader, and
// will retry the same setConfiguration request
waitAndCheckNewConf(cluster, c2.allPeersInNewConf, 2, Collections.singletonList(oldLeaderId));
clientRunning.set(false);
// Assert.assertTrue(success.get());
} finally {
cluster.shutdown();
}
}
use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class RaftReconfigurationBaseTest method testReconfTimeout.
@Test
public void testReconfTimeout() throws Exception {
LOG.info("Start testReconfTimeout");
// originally 3 peers
final MiniRaftCluster cluster = getCluster(3);
cluster.start();
try {
RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = cluster.getLeader().getId();
final RaftClient client = cluster.createClient(leaderId);
PeerChanges c1 = cluster.addNewPeers(2, false);
LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
Assert.assertFalse(cluster.getLeader().getRaftConf().isTransitional());
final RaftClientRpc sender = client.getClientRpc();
final SetConfigurationRequest request = cluster.newSetConfigurationRequest(client.getId(), leaderId, c1.allPeersInNewConf);
try {
sender.sendRequest(request);
Assert.fail("did not get expected exception");
} catch (IOException e) {
Assert.assertTrue("Got exception " + e, e instanceof ReconfigurationTimeoutException);
}
// the two new peers have not started yet, the bootstrapping must timeout
LOG.info(cluster.printServers());
// state so that we still get timeout instead of in-progress exception
try {
sender.sendRequest(request);
Assert.fail("did not get expected exception");
} catch (IOException e) {
Assert.assertTrue("Got exception " + e, e instanceof ReconfigurationTimeoutException);
}
// start the two new peers
LOG.info("Start new peers");
for (RaftPeer np : c1.newPeers) {
cluster.startServer(np.getId());
}
Assert.assertTrue(client.setConfiguration(c1.allPeersInNewConf).isSuccess());
client.close();
} finally {
cluster.shutdown();
}
}
use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class ReinitializationBaseTest method runTestReinitializeMultiGroups.
public static <T extends Throwable> void runTestReinitializeMultiGroups(MiniRaftCluster cluster, int[] idIndex, int chosen, CheckedBiConsumer<MiniRaftCluster, RaftGroup, T> checker) throws IOException, InterruptedException, T {
if (chosen < 0) {
chosen = ThreadLocalRandom.current().nextInt(idIndex.length);
}
final String type = cluster.getClass().getSimpleName() + Arrays.toString(idIndex) + "chosen=" + chosen;
LOG.info("\n\nrunTestReinitializeMultiGroups with " + type + ": " + cluster.printServers());
// Start server with an empty conf
final RaftGroup emptyGroup = new RaftGroup(RaftGroupId.randomId());
final List<RaftPeerId> ids = Arrays.stream(MiniRaftCluster.generateIds(idIndex[idIndex.length - 1], 0)).map(RaftPeerId::valueOf).collect(Collectors.toList());
ids.forEach(id -> cluster.putNewServer(id, emptyGroup, true));
LOG.info("putNewServer: " + cluster.printServers());
cluster.start();
LOG.info("start: " + cluster.printServers());
// Make sure that there are no leaders.
TimeUnit.SECONDS.sleep(1);
Assert.assertNull(cluster.getLeader());
// Reinitialize servers to three groups
final List<RaftPeer> allPeers = cluster.getPeers();
Collections.sort(allPeers, Comparator.comparing(p -> p.getId().toString()));
final RaftGroup[] groups = new RaftGroup[idIndex.length];
for (int i = 0; i < idIndex.length; i++) {
final RaftGroupId gid = RaftGroupId.randomId();
final int previous = i == 0 ? 0 : idIndex[i - 1];
final RaftPeer[] peers = allPeers.subList(previous, idIndex[i]).toArray(RaftPeer.emptyArray());
groups[i] = new RaftGroup(gid, peers);
LOG.info(i + ") starting " + groups[i]);
for (RaftPeer p : peers) {
try (final RaftClient client = cluster.createClient(p.getId(), emptyGroup)) {
client.reinitialize(groups[i], p.getId());
}
}
Assert.assertNotNull(RaftTestUtil.waitForLeader(cluster, true, gid));
checker.accept(cluster, groups[i]);
}
printThreadCount(type, "start groups");
LOG.info("start groups: " + cluster.printServers());
// randomly close two of the groups (i.e. reinitialize to empty peers)
LOG.info("chosen = " + chosen + ", " + groups[chosen]);
for (int i = 0; i < groups.length; i++) {
if (i != chosen) {
final RaftGroup g = groups[i];
final RaftGroup newGroup = new RaftGroup(g.getGroupId());
LOG.info(i + ") close " + cluster.printServers(g.getGroupId()));
for (RaftPeer p : g.getPeers()) {
try (final RaftClient client = cluster.createClient(p.getId(), g)) {
client.reinitialize(newGroup, p.getId());
}
}
}
}
printThreadCount(type, "close groups");
LOG.info("close groups: " + cluster.printServers());
// update chosen group to use all the peers
final RaftGroup newGroup = new RaftGroup(groups[chosen].getGroupId());
for (int i = 0; i < groups.length; i++) {
if (i != chosen) {
LOG.info(i + ") reinitialize: " + cluster.printServers(groups[i].getGroupId()));
for (RaftPeer p : groups[i].getPeers()) {
try (final RaftClient client = cluster.createClient(p.getId(), groups[i])) {
client.reinitialize(newGroup, p.getId());
}
}
}
}
LOG.info(chosen + ") setConfiguration: " + cluster.printServers(groups[chosen].getGroupId()));
try (final RaftClient client = cluster.createClient(groups[chosen])) {
client.setConfiguration(allPeers.toArray(RaftPeer.emptyArray()));
}
Assert.assertNotNull(RaftTestUtil.waitForLeader(cluster, true));
checker.accept(cluster, groups[chosen]);
LOG.info("update groups: " + cluster.printServers());
printThreadCount(type, "update groups");
cluster.shutdown();
printThreadCount(type, "shutdown");
}
use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class ReinitializationBaseTest method testReinitialize.
@Test
public void testReinitialize() throws Exception {
final MiniRaftCluster cluster = getCluster(0);
LOG.info("Start testReinitialize" + cluster.printServers());
// Start server with an empty conf
final RaftGroupId groupId = RaftGroupId.randomId();
final RaftGroup group = new RaftGroup(groupId);
final List<RaftPeerId> ids = Arrays.stream(MiniRaftCluster.generateIds(3, 0)).map(RaftPeerId::valueOf).collect(Collectors.toList());
ids.forEach(id -> cluster.putNewServer(id, group, true));
LOG.info("putNewServer: " + cluster.printServers());
cluster.start();
LOG.info("start: " + cluster.printServers());
// Make sure that there are no leaders.
TimeUnit.SECONDS.sleep(1);
Assert.assertNull(cluster.getLeader());
// Reinitialize servers
final RaftGroup newGroup = new RaftGroup(groupId, cluster.getPeers());
final RaftClient client = cluster.createClient(newGroup);
for (RaftPeer p : newGroup.getPeers()) {
client.reinitialize(newGroup, p.getId());
}
Assert.assertNotNull(RaftTestUtil.waitForLeader(cluster, true));
cluster.shutdown();
}
use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.
the class ServerInformationBaseTest method runTest.
private void runTest(int num) throws Exception {
LOG.info("Running server info test with " + num);
final MiniRaftCluster cluster = newCluster(num);
cluster.start();
// all the peers in the cluster are in the same group, get it.
RaftGroup group = cluster.getGroup();
List<RaftPeer> peers = cluster.getPeers();
// is requested.
for (RaftPeer peer : peers) {
try (final RaftClient client = cluster.createClient(peer.getId())) {
RaftClientReply reply = client.serverInformation(peer.getId());
assertTrue(reply instanceof ServerInformationReply);
ServerInformationReply info = (ServerInformationReply) reply;
assertTrue(sameGroup(group, info.getGroup()));
}
}
final int numMessages = 5;
final long maxCommit;
{
// send some messages and get max commit from the last reply
final RaftClientReply reply = sendMessages(numMessages, cluster);
maxCommit = reply.getCommitInfos().stream().mapToLong(CommitInfoProto::getCommitIndex).max().getAsLong();
}
// kill a follower
final RaftPeerId killedFollower = cluster.getFollowers().iterator().next().getId();
cluster.killServer(killedFollower);
{
// send more messages and check last reply
final RaftClientReply reply = sendMessages(numMessages, cluster);
for (CommitInfoProto i : reply.getCommitInfos()) {
if (RaftPeerId.valueOf(i.getServer().getId()).equals(killedFollower)) {
Assert.assertTrue(i.getCommitIndex() <= maxCommit);
} else {
Assert.assertTrue(i.getCommitIndex() > maxCommit);
}
}
}
// check serverInformation
for (RaftPeer peer : peers) {
if (peer.getId().equals(killedFollower)) {
continue;
}
try (final RaftClient client = cluster.createClient(peer.getId())) {
RaftClientReply reply = client.serverInformation(peer.getId());
assertTrue(reply instanceof ServerInformationReply);
ServerInformationReply info = (ServerInformationReply) reply;
assertTrue(sameGroup(group, info.getGroup()));
for (CommitInfoProto i : info.getCommitInfos()) {
if (RaftPeerId.valueOf(i.getServer().getId()).equals(killedFollower)) {
Assert.assertTrue(i.getCommitIndex() <= maxCommit);
} else {
Assert.assertTrue(i.getCommitIndex() > maxCommit);
}
}
}
}
cluster.shutdown();
}
Aggregations