Search in sources :

Example 71 with RaftClient

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();
    }
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RaftClient(org.apache.ratis.client.RaftClient) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 72 with RaftClient

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();
    }
}
Also used : MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) IOException(java.io.IOException) RaftClient(org.apache.ratis.client.RaftClient) RaftClientRpc(org.apache.ratis.client.RaftClientRpc) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 73 with RaftClient

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");
}
Also used : Arrays(java.util.Arrays) RaftGroup(org.apache.ratis.protocol.RaftGroup) CheckedBiConsumer(org.apache.ratis.util.CheckedBiConsumer) LoggerFactory(org.slf4j.LoggerFactory) RaftGroupId(org.apache.ratis.protocol.RaftGroupId) Level(org.apache.log4j.Level) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) MiniRaftCluster(org.apache.ratis.MiniRaftCluster) JavaUtils(org.apache.ratis.util.JavaUtils) LogUtils(org.apache.ratis.util.LogUtils) Logger(org.slf4j.Logger) RaftPeer(org.apache.ratis.protocol.RaftPeer) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) Test(org.junit.Test) IOException(java.io.IOException) BaseTest(org.apache.ratis.BaseTest) Collectors(java.util.stream.Collectors) RaftTestUtil(org.apache.ratis.RaftTestUtil) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) RaftProperties(org.apache.ratis.conf.RaftProperties) RaftClient(org.apache.ratis.client.RaftClient) Assert(org.junit.Assert) Comparator(java.util.Comparator) Collections(java.util.Collections) RaftGroupId(org.apache.ratis.protocol.RaftGroupId) RaftGroup(org.apache.ratis.protocol.RaftGroup) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftPeer(org.apache.ratis.protocol.RaftPeer) RaftClient(org.apache.ratis.client.RaftClient)

Example 74 with RaftClient

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();
}
Also used : MiniRaftCluster(org.apache.ratis.MiniRaftCluster) RaftGroupId(org.apache.ratis.protocol.RaftGroupId) RaftGroup(org.apache.ratis.protocol.RaftGroup) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftPeer(org.apache.ratis.protocol.RaftPeer) RaftClient(org.apache.ratis.client.RaftClient) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 75 with RaftClient

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();
}
Also used : MiniRaftCluster(org.apache.ratis.MiniRaftCluster) CommitInfoProto(org.apache.ratis.shaded.proto.RaftProtos.CommitInfoProto) RaftClient(org.apache.ratis.client.RaftClient)

Aggregations

RaftClient (org.apache.ratis.client.RaftClient)134 RaftClientReply (org.apache.ratis.protocol.RaftClientReply)66 RaftPeerId (org.apache.ratis.protocol.RaftPeerId)54 SimpleMessage (org.apache.ratis.RaftTestUtil.SimpleMessage)46 RaftServer (org.apache.ratis.server.RaftServer)46 Test (org.junit.Test)44 IOException (java.io.IOException)41 RaftPeer (org.apache.ratis.protocol.RaftPeer)33 BaseTest (org.apache.ratis.BaseTest)27 RaftTestUtil (org.apache.ratis.RaftTestUtil)22 ArrayList (java.util.ArrayList)20 RaftClientRpc (org.apache.ratis.client.RaftClientRpc)20 RaftGroup (org.apache.ratis.protocol.RaftGroup)16 CompletableFuture (java.util.concurrent.CompletableFuture)14 RaftProperties (org.apache.ratis.conf.RaftProperties)14 File (java.io.File)13 SimpleStateMachine4Testing (org.apache.ratis.statemachine.SimpleStateMachine4Testing)13 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)11 RaftClientRequest (org.apache.ratis.protocol.RaftClientRequest)11 MiniRaftCluster (org.apache.ratis.server.impl.MiniRaftCluster)11