Search in sources :

Example 11 with RaftClient

use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.

the class TestRaftStateMachineException method testRetryOnExceptionDuringReplication.

@Test
public void testRetryOnExceptionDuringReplication() throws Exception {
    setAndStart(cluster);
    final RaftPeerId leaderId = cluster.getLeaderAndSendFirstMessage(true).getId();
    // turn on the preAppend failure switch
    failPreAppend = true;
    final RaftClient client = cluster.createClient(leaderId);
    final RaftClientRpc rpc = client.getClientRpc();
    final long callId = 999;
    final long seqNum = 111;
    RaftClientRequest r = cluster.newRaftClientRequest(client.getId(), leaderId, callId, seqNum, new SimpleMessage("message"));
    RaftClientReply reply = rpc.sendRequest(r);
    Objects.requireNonNull(reply.getStateMachineException());
    RetryCache.CacheEntry oldEntry = RaftServerTestUtil.getRetryEntry(cluster.getLeader(), client.getId(), callId);
    Assert.assertNotNull(oldEntry);
    Assert.assertTrue(RaftServerTestUtil.isRetryCacheEntryFailed(oldEntry));
    // retry
    reply = rpc.sendRequest(r);
    Objects.requireNonNull(reply.getStateMachineException());
    RetryCache.CacheEntry currentEntry = RaftServerTestUtil.getRetryEntry(cluster.getLeader(), client.getId(), callId);
    Assert.assertNotNull(currentEntry);
    Assert.assertTrue(RaftServerTestUtil.isRetryCacheEntryFailed(currentEntry));
    Assert.assertNotEquals(oldEntry, currentEntry);
    failPreAppend = false;
    client.close();
}
Also used : RetryCache(org.apache.ratis.server.impl.RetryCache) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftClient(org.apache.ratis.client.RaftClient) RaftClientRpc(org.apache.ratis.client.RaftClientRpc) ParameterizedBaseTest(org.apache.ratis.examples.ParameterizedBaseTest) Test(org.junit.Test)

Example 12 with RaftClient

use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testNoChangeRequest.

/**
 * When a request's new configuration is the same with the current one, make
 * sure we return success immediately and no log entry is recorded.
 */
@Test
public void testNoChangeRequest() throws Exception {
    LOG.info("Start testNoChangeRequest");
    // originally 3 peers
    final MiniRaftCluster cluster = getCluster(3);
    try {
        cluster.start();
        RaftTestUtil.waitForLeader(cluster);
        final RaftPeerId leaderId = cluster.getLeader().getId();
        final RaftClient client = cluster.createClient(leaderId);
        client.send(new SimpleMessage("m"));
        final long committedIndex = cluster.getLeader().getState().getLog().getLastCommittedIndex();
        final RaftConfiguration confBefore = cluster.getLeader().getRaftConf();
        // no real configuration change in the request
        RaftClientReply reply = client.setConfiguration(cluster.getPeers().toArray(new RaftPeer[0]));
        Assert.assertTrue(reply.isSuccess());
        Assert.assertEquals(committedIndex, cluster.getLeader().getState().getLog().getLastCommittedIndex());
        Assert.assertSame(confBefore, cluster.getLeader().getRaftConf());
        client.close();
    } finally {
        cluster.shutdown();
    }
}
Also used : MiniRaftCluster(org.apache.ratis.MiniRaftCluster) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftClient(org.apache.ratis.client.RaftClient) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 13 with RaftClient

use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testRevertConfigurationChange.

/**
 * Test a scenario where the follower truncates its log entries which causes
 * configuration change.
 */
@Test
public void testRevertConfigurationChange() throws Exception {
    LOG.info("Start testRevertConfigurationChange");
    RaftLog log2 = null;
    final MiniRaftCluster cluster = getCluster(5);
    try {
        cluster.start();
        RaftTestUtil.waitForLeader(cluster);
        final RaftServerImpl leader = cluster.getLeader();
        final RaftPeerId leaderId = leader.getId();
        final RaftLog log = leader.getState().getLog();
        log2 = log;
        Thread.sleep(1000);
        // we block the incoming msg for the leader and block its requests to
        // followers, so that we force the leader change and the old leader will
        // not know
        LOG.info("start blocking the leader");
        BlockRequestHandlingInjection.getInstance().blockReplier(leaderId.toString());
        cluster.setBlockRequestsFrom(leaderId.toString(), true);
        PeerChanges change = cluster.removePeers(1, false, new ArrayList<>());
        AtomicBoolean gotNotLeader = new AtomicBoolean(false);
        final Thread clientThread = new Thread(() -> {
            try (final RaftClient client = cluster.createClient(leaderId)) {
                LOG.info("client starts to change conf");
                final RaftClientRpc sender = client.getClientRpc();
                RaftClientReply reply = sender.sendRequest(cluster.newSetConfigurationRequest(client.getId(), leaderId, change.allPeersInNewConf));
                if (reply.getNotLeaderException() != null) {
                    gotNotLeader.set(true);
                }
            } catch (IOException e) {
                LOG.warn("Got unexpected exception when client1 changes conf", e);
            }
        });
        clientThread.start();
        // find CONFIGURATIONENTRY, there may be NOOP before and after it.
        final long confIndex = JavaUtils.attempt(() -> {
            final long last = log.getLastEntryTermIndex().getIndex();
            for (long i = 1; i <= last; i++) {
                if (log.get(i).getLogEntryBodyCase() == CONFIGURATIONENTRY) {
                    return i;
                }
            }
            throw new Exception("CONFIGURATIONENTRY not found: last=" + last);
        }, 10, 500, "confIndex", LOG);
        // wait till the old leader persist the new conf
        JavaUtils.attempt(() -> log.getLatestFlushedIndex() >= confIndex, 10, 500L, "FLUSH", LOG);
        final long committed = log.getLastCommittedIndex();
        Assert.assertTrue(committed < confIndex);
        // unblock the old leader
        BlockRequestHandlingInjection.getInstance().unblockReplier(leaderId.toString());
        cluster.setBlockRequestsFrom(leaderId.toString(), false);
        // the client should get NotLeaderException
        clientThread.join(5000);
        Assert.assertTrue(gotNotLeader.get());
        // the old leader should have truncated the setConf from the log
        JavaUtils.attempt(() -> log.getLastCommittedIndex() >= confIndex, 10, 500L, "COMMIT", LOG);
        Assert.assertEquals(NOOP, log.get(confIndex).getLogEntryBodyCase());
        log2 = null;
    } finally {
        RaftStorageTestUtils.printLog(log2, s -> LOG.info(s));
        cluster.shutdown();
    }
}
Also used : IOException(java.io.IOException) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.storage.RaftLog) RaftClientRpc(org.apache.ratis.client.RaftClientRpc) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 14 with RaftClient

use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testBootstrapReconf.

@Test
public void testBootstrapReconf() throws Exception {
    LOG.info("Start testBootstrapReconf");
    // 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);
        // submit some msgs before reconf
        for (int i = 0; i < getStagingGap() * 2; i++) {
            RaftClientReply reply = client.send(new SimpleMessage("m" + i));
            Assert.assertTrue(reply.isSuccess());
        }
        PeerChanges c1 = cluster.addNewPeers(2, true);
        LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
        final AtomicReference<Boolean> success = new AtomicReference<>();
        Thread clientThread = new Thread(() -> {
            try {
                RaftClientReply reply = client.setConfiguration(c1.allPeersInNewConf);
                success.set(reply.isSuccess());
                client.close();
            } catch (IOException ioe) {
                LOG.error("FAILED", ioe);
            }
        });
        clientThread.start();
        Thread.sleep(5000);
        LOG.info(cluster.printServers());
        assertSuccess(success);
        final RaftLog leaderLog = cluster.getLeader().getState().getLog();
        for (RaftPeer newPeer : c1.newPeers) {
            Assert.assertArrayEquals(leaderLog.getEntries(0, Long.MAX_VALUE), cluster.getServer(newPeer.getId()).getImpl().getState().getLog().getEntries(0, Long.MAX_VALUE));
        }
    } finally {
        cluster.shutdown();
    }
}
Also used : SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.storage.RaftLog) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 15 with RaftClient

use of org.apache.ratis.client.RaftClient in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method testReconfTwice.

@Test(timeout = 30000)
public void testReconfTwice() throws Exception {
    LOG.info("Start testReconfTwice");
    final MiniRaftCluster cluster = getCluster(3);
    cluster.start();
    try {
        RaftTestUtil.waitForLeader(cluster);
        final RaftPeerId leaderId = cluster.getLeader().getId();
        final RaftClient client = cluster.createClient(leaderId);
        // submit some msgs before reconf
        for (int i = 0; i < getStagingGap() * 2; i++) {
            RaftClientReply reply = client.send(new SimpleMessage("m" + i));
            Assert.assertTrue(reply.isSuccess());
        }
        final AtomicBoolean reconf1 = new AtomicBoolean(false);
        final AtomicBoolean reconf2 = new AtomicBoolean(false);
        final AtomicReference<RaftPeer[]> finalPeers = new AtomicReference<>(null);
        final AtomicReference<RaftPeer[]> deadPeers = new AtomicReference<>(null);
        CountDownLatch latch = new CountDownLatch(1);
        Thread clientThread = new Thread(() -> {
            try {
                PeerChanges c1 = cluster.addNewPeers(2, true);
                LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
                RaftClientReply reply = client.setConfiguration(c1.allPeersInNewConf);
                reconf1.set(reply.isSuccess());
                PeerChanges c2 = cluster.removePeers(2, true, asList(c1.newPeers));
                finalPeers.set(c2.allPeersInNewConf);
                deadPeers.set(c2.removedPeers);
                LOG.info("Start changing the configuration again: {}", asList(c2.allPeersInNewConf));
                reply = client.setConfiguration(c2.allPeersInNewConf);
                reconf2.set(reply.isSuccess());
                latch.countDown();
                client.close();
            } catch (IOException ignored) {
            }
        });
        clientThread.start();
        latch.await();
        Assert.assertTrue(reconf1.get());
        Assert.assertTrue(reconf2.get());
        waitAndCheckNewConf(cluster, finalPeers.get(), 2, null);
        // check configuration manager's internal state
        // each reconf will generate two configurations: (old, new) and (new)
        cluster.getServerAliveStream().forEach(server -> {
            ConfigurationManager confManager = (ConfigurationManager) Whitebox.getInternalState(server.getState(), "configurationManager");
            // each reconf will generate two configurations: (old, new) and (new)
            Assert.assertEquals(5, confManager.numOfConf());
        });
    } finally {
        cluster.shutdown();
    }
}
Also used : SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MiniRaftCluster(org.apache.ratis.MiniRaftCluster) PeerChanges(org.apache.ratis.MiniRaftCluster.PeerChanges) RaftClient(org.apache.ratis.client.RaftClient) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

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