Search in sources :

Example 36 with RaftPeerId

use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method runTestReconfTimeout.

void runTestReconfTimeout(CLUSTER cluster) throws Exception {
    final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
    try (final RaftClient client = cluster.createClient(leaderId)) {
        PeerChanges c1 = cluster.addNewPeers(2, false);
        LOG.info("Start changing the configuration: {}", asList(c1.allPeersInNewConf));
        Assert.assertFalse(((RaftConfigurationImpl) 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.restartServer(np.getId(), false);
        }
        Assert.assertTrue(client.admin().setConfiguration(c1.allPeersInNewConf).isSuccess());
    }
}
Also used : ReconfigurationTimeoutException(org.apache.ratis.protocol.exceptions.ReconfigurationTimeoutException) PeerChanges(org.apache.ratis.server.impl.MiniRaftCluster.PeerChanges) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) IOException(java.io.IOException) RaftPeer(org.apache.ratis.protocol.RaftPeer) SetConfigurationRequest(org.apache.ratis.protocol.SetConfigurationRequest) RaftClient(org.apache.ratis.client.RaftClient) RaftClientRpc(org.apache.ratis.client.RaftClientRpc)

Example 37 with RaftPeerId

use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method runTestKillLeaderDuringReconf.

void runTestKillLeaderDuringReconf(CLUSTER cluster) throws Exception {
    final AtomicBoolean clientRunning = new AtomicBoolean(true);
    Thread clientThread = null;
    try {
        final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
        PeerChanges c1 = cluster.addNewPeers(1, false);
        PeerChanges c2 = cluster.removePeers(1, false, asList(c1.newPeers));
        LOG.info("Start setConf: {}", asList(c2.allPeersInNewConf));
        LOG.info(cluster.printServers());
        final CompletableFuture<Void> setConf = new CompletableFuture<>();
        clientThread = new Thread(() -> {
            try (final RaftClient client = cluster.createClient(leaderId)) {
                for (int i = 0; clientRunning.get() && !setConf.isDone(); i++) {
                    final RaftClientReply reply = client.admin().setConfiguration(c2.allPeersInNewConf);
                    if (reply.isSuccess()) {
                        setConf.complete(null);
                    }
                    LOG.info("setConf attempt #{} failed, {}", i, cluster.printServers());
                }
            } catch (Exception e) {
                LOG.error("Failed to setConf", e);
                setConf.completeExceptionally(e);
            }
        });
        clientThread.start();
        TimeUnit.SECONDS.sleep(1);
        // the leader cannot generate the (old, new) conf, and it will keep
        // bootstrapping the 2 new peers since they have not started yet
        Assert.assertFalse(((RaftConfigurationImpl) cluster.getLeader().getRaftConf()).isTransitional());
        // only (0) the first conf entry, (1) the 1st setConf entry and (2) a metadata entry
        {
            final RaftLog leaderLog = cluster.getLeader().getRaftLog();
            for (LogEntryProto e : RaftTestUtil.getLogEntryProtos(leaderLog)) {
                LOG.info("{}", LogProtoUtils.toLogEntryString(e));
            }
            final long commitIndex = leaderLog.getLastCommittedIndex();
            Assert.assertTrue("commitIndex = " + commitIndex + " > 2", commitIndex <= 2);
        }
        final RaftPeerId killed = RaftTestUtil.waitAndKillLeader(cluster);
        Assert.assertEquals(leaderId, killed);
        final RaftPeerId newLeaderId = RaftTestUtil.waitForLeader(cluster).getId();
        LOG.info("newLeaderId: {}", newLeaderId);
        LOG.info("start new peers: {}", Arrays.asList(c1.newPeers));
        for (RaftPeer np : c1.newPeers) {
            cluster.restartServer(np.getId(), false);
        }
        try {
            setConf.get(10, TimeUnit.SECONDS);
        } catch (TimeoutException ignored) {
        }
        // the client fails with the first leader, and then retry the same setConfiguration request
        waitAndCheckNewConf(cluster, c2.allPeersInNewConf, 2, Collections.singletonList(leaderId));
        setConf.get(1, TimeUnit.SECONDS);
    } finally {
        if (clientThread != null) {
            clientRunning.set(false);
            clientThread.interrupt();
        }
    }
}
Also used : RaftPeer(org.apache.ratis.protocol.RaftPeer) LeaderNotReadyException(org.apache.ratis.protocol.exceptions.LeaderNotReadyException) TimeoutException(java.util.concurrent.TimeoutException) ReconfigurationInProgressException(org.apache.ratis.protocol.exceptions.ReconfigurationInProgressException) ReconfigurationTimeoutException(org.apache.ratis.protocol.exceptions.ReconfigurationTimeoutException) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) PeerChanges(org.apache.ratis.server.impl.MiniRaftCluster.PeerChanges) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.raftlog.RaftLog) TimeoutException(java.util.concurrent.TimeoutException) ReconfigurationTimeoutException(org.apache.ratis.protocol.exceptions.ReconfigurationTimeoutException)

Example 38 with RaftPeerId

use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.

the class RaftReconfigurationBaseTest method runTestRevertConfigurationChange.

void runTestRevertConfigurationChange(CLUSTER cluster) throws Exception {
    RaftLogBase log2 = null;
    try {
        RaftTestUtil.waitForLeader(cluster);
        final RaftServer.Division leader = cluster.getLeader();
        final RaftPeerId leaderId = leader.getId();
        final RaftLog log = leader.getRaftLog();
        log2 = (RaftLogBase) 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
        final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
        final long confIndex = JavaUtils.attemptRepeatedly(() -> {
            final long last = log.getLastEntryTermIndex().getIndex();
            for (long i = last; i >= 1; i--) {
                if (log.get(i).hasConfigurationEntry()) {
                    return i;
                }
            }
            throw new Exception("ConfigurationEntry not found: last=" + last);
        }, 10, sleepTime, "confIndex", LOG);
        // wait till the old leader persist the new conf
        JavaUtils.attemptRepeatedly(() -> {
            Assert.assertTrue(log.getFlushIndex() >= confIndex);
            return null;
        }, 10, sleepTime, "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.attemptRepeatedly(() -> {
            Assert.assertTrue(log.getLastCommittedIndex() >= confIndex);
            return null;
        }, 10, ONE_SECOND, "COMMIT", LOG);
        Assert.assertTrue(log.get(confIndex).hasConfigurationEntry());
        log2 = null;
    } finally {
        RaftStorageTestUtils.printLog(log2, s -> LOG.info(s));
    }
}
Also used : RaftServer(org.apache.ratis.server.RaftServer) RaftLogBase(org.apache.ratis.server.raftlog.RaftLogBase) IOException(java.io.IOException) LeaderNotReadyException(org.apache.ratis.protocol.exceptions.LeaderNotReadyException) TimeoutException(java.util.concurrent.TimeoutException) ReconfigurationInProgressException(org.apache.ratis.protocol.exceptions.ReconfigurationInProgressException) ReconfigurationTimeoutException(org.apache.ratis.protocol.exceptions.ReconfigurationTimeoutException) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) PeerChanges(org.apache.ratis.server.impl.MiniRaftCluster.PeerChanges) TimeDuration(org.apache.ratis.util.TimeDuration) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.raftlog.RaftLog) RaftClientRpc(org.apache.ratis.client.RaftClientRpc)

Example 39 with RaftPeerId

use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.

the class LogAppenderTests method runTest.

void runTest(CLUSTER cluster) throws Exception {
    final int numMsgs = 10;
    final int numClients = 5;
    final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
    List<RaftClient> clients = new ArrayList<>();
    try {
        List<Sender> senders = new ArrayList<>();
        // start several clients and write concurrently
        final CountDownLatch latch = new CountDownLatch(1);
        for (int i = 0; i < numClients; i++) {
            RaftClient client = cluster.createClient(leaderId);
            clients.add(client);
            senders.add(new Sender(client, numMsgs, latch));
        }
        senders.forEach(Thread::start);
        latch.countDown();
        for (Sender s : senders) {
            s.join();
            final Exception e = s.exception.get();
            if (e != null) {
                throw e;
            }
            Assert.assertTrue(s.succeed.get());
        }
    } finally {
        for (int i = 0; i < clients.size(); i++) {
            try {
                clients.get(i).close();
            } catch (Exception ignored) {
                LOG.warn("{} is ignored", JavaUtils.getClassSimpleName(ignored.getClass()), ignored);
            }
        }
    }
    final RaftServer.Division leader = cluster.getLeader();
    final RaftLog leaderLog = cluster.getLeader().getRaftLog();
    final EnumMap<LogEntryBodyCase, AtomicLong> counts = RaftTestUtil.countEntries(leaderLog);
    LOG.info("counts = " + counts);
    Assert.assertEquals(6 * numMsgs * numClients, counts.get(LogEntryBodyCase.STATEMACHINELOGENTRY).get());
    final LogEntryProto last = RaftTestUtil.getLastEntry(LogEntryBodyCase.STATEMACHINELOGENTRY, leaderLog);
    LOG.info("last = {}", LogProtoUtils.toLogEntryString(last));
    Assert.assertNotNull(last);
    Assert.assertTrue(last.getIndex() <= leader.getInfo().getLastAppliedIndex());
}
Also used : RaftServer(org.apache.ratis.server.RaftServer) ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) IOException(java.io.IOException) LogEntryBodyCase(org.apache.ratis.proto.RaftProtos.LogEntryProto.LogEntryBodyCase) AtomicLong(java.util.concurrent.atomic.AtomicLong) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.raftlog.RaftLog)

Example 40 with RaftPeerId

use of org.apache.ratis.protocol.RaftPeerId in project incubator-ratis by apache.

the class RaftBasicTests method runTestOldLeaderCommit.

void runTestOldLeaderCommit(CLUSTER cluster) throws Exception {
    final RaftServer.Division leader = waitForLeader(cluster);
    final RaftPeerId leaderId = leader.getId();
    final long term = leader.getInfo().getCurrentTerm();
    final List<RaftServer.Division> followers = cluster.getFollowers();
    final List<RaftServer.Division> followersToSendLog = followers.subList(0, followers.size() / 2);
    for (int i = followers.size() / 2; i < NUM_SERVERS - 1; i++) {
        cluster.killServer(followers.get(i).getId());
    }
    SimpleMessage[] messages = SimpleMessage.create(1);
    RaftTestUtil.sendMessageInNewThread(cluster, leaderId, messages);
    Thread.sleep(cluster.getTimeoutMax().toLong(TimeUnit.MILLISECONDS) + 100);
    for (RaftServer.Division followerToSendLog : followersToSendLog) {
        RaftLog followerLog = followerToSendLog.getRaftLog();
        Assert.assertTrue(RaftTestUtil.logEntriesContains(followerLog, messages));
    }
    LOG.info(String.format("killing old leader: %s", leaderId.toString()));
    cluster.killServer(leaderId);
    for (int i = followers.size() / 2; i < NUM_SERVERS - 1; i++) {
        final RaftPeerId followerId = followers.get(i).getId();
        LOG.info(String.format("restarting follower: %s", followerId));
        cluster.restartServer(followerId, false);
    }
    Thread.sleep(cluster.getTimeoutMax().toLong(TimeUnit.MILLISECONDS) * 5);
    // confirm the server with log is elected as new leader.
    final RaftPeerId newLeaderId = waitForLeader(cluster).getId();
    Set<RaftPeerId> followersToSendLogIds = followersToSendLog.stream().map(f -> f.getId()).collect(Collectors.toSet());
    Assert.assertTrue(followersToSendLogIds.contains(newLeaderId));
    cluster.getServerAliveStream().map(RaftServer.Division::getRaftLog).forEach(log -> RaftTestUtil.assertLogEntries(log, term, messages));
}
Also used : RetryCacheTestUtil(org.apache.ratis.server.impl.RetryCacheTestUtil) Timer(java.util.Timer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Level(org.apache.log4j.Level) JavaUtils(org.apache.ratis.util.JavaUtils) TimerTask(java.util.TimerTask) BlockRequestHandlingInjection(org.apache.ratis.server.impl.BlockRequestHandlingInjection) RaftTestUtil.waitForLeader(org.apache.ratis.RaftTestUtil.waitForLeader) STATEMACHINE_APPLIED_INDEX_GAUGE(org.apache.ratis.server.impl.StateMachineMetrics.STATEMACHINE_APPLIED_INDEX_GAUGE) Timestamp(org.apache.ratis.util.Timestamp) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) Predicate(java.util.function.Predicate) Set(java.util.Set) RATIS_STATEMACHINE_METRICS(org.apache.ratis.server.impl.StateMachineMetrics.RATIS_STATEMACHINE_METRICS) Collectors(java.util.stream.Collectors) RATIS_STATEMACHINE_METRICS_DESC(org.apache.ratis.server.impl.StateMachineMetrics.RATIS_STATEMACHINE_METRICS_DESC) MetricRegistries(org.apache.ratis.metrics.MetricRegistries) MetricRegistryInfo(org.apache.ratis.metrics.MetricRegistryInfo) List(java.util.List) Stream(java.util.stream.Stream) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) Optional(java.util.Optional) ClientInvocationId(org.apache.ratis.protocol.ClientInvocationId) Gauge(com.codahale.metrics.Gauge) SortedMap(java.util.SortedMap) MiniRaftCluster(org.apache.ratis.server.impl.MiniRaftCluster) TimeDuration(org.apache.ratis.util.TimeDuration) RaftGroupMemberId(org.apache.ratis.protocol.RaftGroupMemberId) RaftLog(org.apache.ratis.server.raftlog.RaftLog) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) RATIS_APPLICATION_NAME_METRICS(org.apache.ratis.metrics.RatisMetrics.RATIS_APPLICATION_NAME_METRICS) Log4jUtils(org.apache.ratis.util.Log4jUtils) RaftServerTestUtil(org.apache.ratis.server.impl.RaftServerTestUtil) RaftServerMetricsImpl(org.apache.ratis.server.metrics.RaftServerMetricsImpl) Logger(org.slf4j.Logger) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftServerConfigKeys(org.apache.ratis.server.RaftServerConfigKeys) RaftClientTestUtil(org.apache.ratis.client.impl.RaftClientTestUtil) STATEMACHINE_APPLY_COMPLETED_GAUGE(org.apache.ratis.server.impl.StateMachineMetrics.STATEMACHINE_APPLY_COMPLETED_GAUGE) Test(org.junit.Test) IOException(java.io.IOException) RatisMetricRegistry(org.apache.ratis.metrics.RatisMetricRegistry) TimeUnit(java.util.concurrent.TimeUnit) ExitUtils(org.apache.ratis.util.ExitUtils) RaftServer(org.apache.ratis.server.RaftServer) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftClient(org.apache.ratis.client.RaftClient) Assert(org.junit.Assert) RaftServer(org.apache.ratis.server.RaftServer) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftLog(org.apache.ratis.server.raftlog.RaftLog)

Aggregations

RaftPeerId (org.apache.ratis.protocol.RaftPeerId)101 RaftClient (org.apache.ratis.client.RaftClient)58 RaftClientReply (org.apache.ratis.protocol.RaftClientReply)45 IOException (java.io.IOException)36 Test (org.junit.Test)32 RaftPeer (org.apache.ratis.protocol.RaftPeer)31 RaftServer (org.apache.ratis.server.RaftServer)31 BaseTest (org.apache.ratis.BaseTest)21 SimpleMessage (org.apache.ratis.RaftTestUtil.SimpleMessage)20 CompletableFuture (java.util.concurrent.CompletableFuture)18 RaftProperties (org.apache.ratis.conf.RaftProperties)18 File (java.io.File)17 ArrayList (java.util.ArrayList)15 RaftGroupId (org.apache.ratis.protocol.RaftGroupId)15 RaftGroup (org.apache.ratis.protocol.RaftGroup)14 TimeDuration (org.apache.ratis.util.TimeDuration)14 List (java.util.List)13 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)12 Collectors (java.util.stream.Collectors)11 RaftLog (org.apache.ratis.server.raftlog.RaftLog)11