Search in sources :

Example 1 with RaftClient

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

the class RaftAsyncTests method testStaleReadAsync.

@Test
public void testStaleReadAsync() throws Exception {
    final int numMesssages = 10;
    final CLUSTER cluster = getFactory().newCluster(NUM_SERVERS, properties);
    try (RaftClient client = cluster.createClient()) {
        cluster.start();
        RaftTestUtil.waitForLeader(cluster);
        // submit some messages
        final List<CompletableFuture<RaftClientReply>> futures = new ArrayList<>();
        for (int i = 0; i < numMesssages; i++) {
            final String s = "m" + i;
            LOG.info("sendAsync " + s);
            futures.add(client.sendAsync(new RaftTestUtil.SimpleMessage(s)));
        }
        Assert.assertEquals(numMesssages, futures.size());
        RaftClientReply lastWriteReply = null;
        for (CompletableFuture<RaftClientReply> f : futures) {
            lastWriteReply = f.join();
            Assert.assertTrue(lastWriteReply.isSuccess());
        }
        futures.clear();
        // Use a follower with the max commit index
        final RaftPeerId leader = lastWriteReply.getServerId();
        LOG.info("leader = " + leader);
        final Collection<CommitInfoProto> commitInfos = lastWriteReply.getCommitInfos();
        LOG.info("commitInfos = " + commitInfos);
        final CommitInfoProto followerCommitInfo = commitInfos.stream().filter(info -> !RaftPeerId.valueOf(info.getServer().getId()).equals(leader)).max(Comparator.comparing(CommitInfoProto::getCommitIndex)).get();
        final RaftPeerId follower = RaftPeerId.valueOf(followerCommitInfo.getServer().getId());
        LOG.info("max follower = " + follower);
        // test a failure case
        testFailureCaseAsync("sendStaleReadAsync(..) with a larger commit index", () -> client.sendStaleReadAsync(new RaftTestUtil.SimpleMessage("" + (numMesssages + 1)), followerCommitInfo.getCommitIndex(), follower), StateMachineException.class, IndexOutOfBoundsException.class);
        // test sendStaleReadAsync
        for (int i = 1; i < followerCommitInfo.getCommitIndex(); i++) {
            final int query = i;
            LOG.info("sendStaleReadAsync, query=" + query);
            final Message message = new RaftTestUtil.SimpleMessage("" + query);
            final CompletableFuture<RaftClientReply> readFuture = client.sendReadOnlyAsync(message);
            final CompletableFuture<RaftClientReply> staleReadFuture = client.sendStaleReadAsync(message, followerCommitInfo.getCommitIndex(), follower);
            futures.add(readFuture.thenApply(r -> getMessageContent(r)).thenCombine(staleReadFuture.thenApply(r -> getMessageContent(r)), (expected, computed) -> {
                try {
                    LOG.info("query " + query + " returns " + LogEntryProto.parseFrom(expected).getSmLogEntry().getData().toStringUtf8());
                } catch (InvalidProtocolBufferException e) {
                    throw new CompletionException(e);
                }
                Assert.assertEquals("log entry mismatch for query=" + query, expected, computed);
                return null;
            }));
        }
        JavaUtils.allOf(futures).join();
    } finally {
        cluster.shutdown();
    }
}
Also used : ByteString(org.apache.ratis.shaded.com.google.protobuf.ByteString) InvalidProtocolBufferException(org.apache.ratis.shaded.com.google.protobuf.InvalidProtocolBufferException) RaftServerProxy(org.apache.ratis.server.impl.RaftServerProxy) org.apache.ratis.protocol(org.apache.ratis.protocol) ArrayList(java.util.ArrayList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Level(org.apache.log4j.Level) SimpleStateMachine4Testing(org.apache.ratis.statemachine.SimpleStateMachine4Testing) CommitInfoProto(org.apache.ratis.shaded.proto.RaftProtos.CommitInfoProto) JavaUtils(org.apache.ratis.util.JavaUtils) LogUtils(org.apache.ratis.util.LogUtils) RaftTestUtil.waitForLeader(org.apache.ratis.RaftTestUtil.waitForLeader) StateMachine(org.apache.ratis.statemachine.StateMachine) RaftServerImpl(org.apache.ratis.server.impl.RaftServerImpl) LogEntryProto(org.apache.ratis.shaded.proto.RaftProtos.LogEntryProto) java.util.concurrent(java.util.concurrent) RaftServerConfigKeys(org.apache.ratis.server.RaftServerConfigKeys) Collection(java.util.Collection) RaftClientTestUtil(org.apache.ratis.client.impl.RaftClientTestUtil) IOException(java.io.IOException) List(java.util.List) RaftProperties(org.apache.ratis.conf.RaftProperties) org.junit(org.junit) RaftClient(org.apache.ratis.client.RaftClient) Comparator(java.util.Comparator) RaftClientConfigKeys(org.apache.ratis.client.RaftClientConfigKeys) TimeDuration(org.apache.ratis.util.TimeDuration) CommitInfoProto(org.apache.ratis.shaded.proto.RaftProtos.CommitInfoProto) ArrayList(java.util.ArrayList) InvalidProtocolBufferException(org.apache.ratis.shaded.com.google.protobuf.InvalidProtocolBufferException) ByteString(org.apache.ratis.shaded.com.google.protobuf.ByteString) RaftClient(org.apache.ratis.client.RaftClient)

Example 2 with RaftClient

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

the class RaftBasicTests method testRequestTimeout.

public static void testRequestTimeout(boolean async, MiniRaftCluster cluster, Logger LOG, RaftProperties properties) throws InterruptedException, IOException, ExecutionException {
    LOG.info("Running testRequestTimeout");
    waitForLeader(cluster);
    long time = System.currentTimeMillis();
    try (final RaftClient client = cluster.createClient()) {
        // Get the next callId to be used by the client
        long callId = RaftClientTestUtil.getCallId(client);
        // Create an entry corresponding to the callId and clientId
        // in each server's retry cache.
        cluster.getServerAliveStream().forEach(raftServer -> RetryCacheTestUtil.getOrCreateEntry(raftServer.getRetryCache(), client.getId(), callId));
        // The retry is successful when the retry cache entry for the corresponding callId and clientId expires.
        if (async) {
            CompletableFuture<RaftClientReply> replyFuture = client.sendAsync(new SimpleMessage("abc"));
            replyFuture.get();
        } else {
            client.send(new SimpleMessage("abc"));
        }
        // Eventually the request would be accepted by the server
        // when the retry cache entry is invalidated.
        // The duration for which the client waits should be more than the retryCacheExpiryDuration.
        TimeDuration duration = TimeDuration.valueOf(System.currentTimeMillis() - time, TimeUnit.MILLISECONDS);
        TimeDuration retryCacheExpiryDuration = RaftServerConfigKeys.RetryCache.expiryTime(properties);
        Assert.assertTrue(duration.compareTo(retryCacheExpiryDuration) >= 0);
    }
}
Also used : RaftClientReply(org.apache.ratis.protocol.RaftClientReply) TimeDuration(org.apache.ratis.util.TimeDuration) RaftClient(org.apache.ratis.client.RaftClient)

Example 3 with RaftClient

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

the class RaftExceptionBaseTest method testStaleReadException.

@Test
public void testStaleReadException() throws Exception {
    RaftTestUtil.waitForLeader(cluster);
    try (RaftClient client = cluster.createClient()) {
        final RaftPeerId follower = cluster.getFollowers().iterator().next().getId();
        testFailureCase("sendStaleRead(..) with a large commit index", () -> client.sendStaleRead(Message.EMPTY, 1_000_000_000L, follower), StateMachineException.class, StaleReadException.class);
    }
}
Also used : RaftClient(org.apache.ratis.client.RaftClient) Test(org.junit.Test)

Example 4 with RaftClient

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

the class RaftExceptionBaseTest method testLogAppenderBufferCapacity.

@Test
public void testLogAppenderBufferCapacity() throws Exception {
    RaftTestUtil.waitForLeader(cluster);
    final RaftPeerId leaderId = cluster.getLeader().getId();
    final RaftClient client = cluster.createClient(leaderId);
    byte[] bytes = new byte[8192];
    Arrays.fill(bytes, (byte) 1);
    SimpleMessage msg = new SimpleMessage(new String(bytes));
    try {
        client.send(msg);
        Assert.fail("Expected StateMachineException  not thrown");
    } catch (StateMachineException sme) {
        Assert.assertTrue(sme.getMessage().contains("exceeds the max buffer limit"));
    }
}
Also used : SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftClient(org.apache.ratis.client.RaftClient) Test(org.junit.Test)

Example 5 with RaftClient

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

the class RaftExceptionBaseTest method testNotLeaderExceptionWithReconf.

@Test
public void testNotLeaderExceptionWithReconf() throws Exception {
    Assert.assertNotNull(RaftTestUtil.waitForLeader(cluster));
    final RaftPeerId leaderId = cluster.getLeader().getId();
    final RaftClient client = cluster.createClient(leaderId);
    // enforce leader change
    RaftPeerId newLeader = RaftTestUtil.changeLeader(cluster, leaderId);
    // also add two new peers
    // add two more peers
    MiniRaftCluster.PeerChanges change = cluster.addNewPeers(new String[] { "ss1", "ss2" }, true);
    // trigger setConfiguration
    LOG.info("Start changing the configuration: {}", Arrays.asList(change.allPeersInNewConf));
    try (final RaftClient c2 = cluster.createClient(newLeader)) {
        RaftClientReply reply = c2.setConfiguration(change.allPeersInNewConf);
        Assert.assertTrue(reply.isSuccess());
    }
    LOG.info(cluster.printServers());
    RaftClientRpc rpc = client.getClientRpc();
    RaftClientReply reply = null;
    // it is possible that the remote peer's rpc server is not ready. need retry
    for (int i = 0; reply == null && i < 10; i++) {
        try {
            reply = rpc.sendRequest(cluster.newRaftClientRequest(ClientId.randomId(), leaderId, new SimpleMessage("m1")));
        } catch (IOException ignored) {
            Thread.sleep(1000);
        }
    }
    Assert.assertNotNull(reply);
    Assert.assertFalse(reply.isSuccess());
    final NotLeaderException nle = reply.getNotLeaderException();
    Objects.requireNonNull(nle);
    Assert.assertEquals(newLeader, nle.getSuggestedLeader().getId());
    Collection<RaftPeer> peers = cluster.getPeers();
    RaftPeer[] peersFromReply = reply.getNotLeaderException().getPeers();
    Assert.assertEquals(peers.size(), peersFromReply.length);
    for (RaftPeer p : peersFromReply) {
        Assert.assertTrue(peers.contains(p));
    }
    reply = client.send(new SimpleMessage("m2"));
    Assert.assertTrue(reply.isSuccess());
    client.close();
}
Also used : SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) IOException(java.io.IOException) RaftClient(org.apache.ratis.client.RaftClient) RaftClientRpc(org.apache.ratis.client.RaftClientRpc) Test(org.junit.Test)

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