Repository: incubator-ratis Updated Branches: refs/heads/master 0b22e0935 -> d4ec63a0b
RATIS-427. Better group info API in RaftClient. Project: http://git-wip-us.apache.org/repos/asf/incubator-ratis/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ratis/commit/d4ec63a0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ratis/tree/d4ec63a0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ratis/diff/d4ec63a0 Branch: refs/heads/master Commit: d4ec63a0b93c5fd64d0c9b769e99f723d43e43b8 Parents: 0b22e09 Author: Tsz Wo Nicholas Sze <[email protected]> Authored: Mon Nov 26 16:33:31 2018 -0800 Committer: Tsz Wo Nicholas Sze <[email protected]> Committed: Mon Nov 26 16:33:31 2018 -0800 ---------------------------------------------------------------------- .../org/apache/ratis/client/RaftClient.java | 6 +- .../ratis/client/impl/ClientProtoUtils.java | 8 +- .../ratis/client/impl/RaftClientImpl.java | 16 +- .../apache/ratis/protocol/GroupListReply.java | 10 +- .../org/apache/ratis/protocol/RaftPeer.java | 19 ++ .../java/org/apache/ratis/util/ProtoUtils.java | 17 +- .../hadooprpc/TestGroupInfoWithHadoopRpc.java | 25 +++ .../TestServerInformationWithHadoopRpc.java | 25 --- .../ratis/server/impl/RaftServerImpl.java | 2 +- .../ratis/server/impl/RaftServerProxy.java | 2 +- .../ratis/server/impl/ServerProtoUtils.java | 2 +- .../ratis/server/impl/GroupInfoBaseTest.java | 155 ++++++++++++++++ .../server/impl/ServerInformationBaseTest.java | 177 ------------------- .../ratis/grpc/TestGroupInfoWithGrpc.java | 25 +++ .../grpc/TestServerInformationWithGrpc.java | 25 --- .../ratis/netty/TestGroupInfoWithNetty.java | 25 +++ .../netty/TestServerInformationWithNetty.java | 25 --- .../TestGroupInfoWithSimulatedRpc.java | 25 +++ .../TestServerInformationWithSimulatedRpc.java | 25 --- 19 files changed, 303 insertions(+), 311 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-client/src/main/java/org/apache/ratis/client/RaftClient.java ---------------------------------------------------------------------- diff --git a/ratis-client/src/main/java/org/apache/ratis/client/RaftClient.java b/ratis-client/src/main/java/org/apache/ratis/client/RaftClient.java index 3929164..deb91f8 100644 --- a/ratis-client/src/main/java/org/apache/ratis/client/RaftClient.java +++ b/ratis-client/src/main/java/org/apache/ratis/client/RaftClient.java @@ -103,11 +103,11 @@ public interface RaftClient extends Closeable { /** Send groupRemove request to the given server (not the raft service). */ RaftClientReply groupRemove(RaftGroupId groupId, boolean deleteDirectory, RaftPeerId server) throws IOException; - /** Send getGroups request to the given server.*/ - RaftClientReply getGroups(RaftPeerId server) throws IOException; + /** Send getGroupList request to the given server.*/ + GroupListReply getGroupList(RaftPeerId server) throws IOException; /** Send getGroupInfo request to the given server.*/ - RaftClientReply getGroupInfo(RaftGroupId group, RaftPeerId server) throws IOException; + GroupInfoReply getGroupInfo(RaftGroupId group, RaftPeerId server) throws IOException; /** @return a {@link Builder}. */ static Builder newBuilder() { http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java ---------------------------------------------------------------------- diff --git a/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java b/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java index 5b03145..4378443 100644 --- a/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java +++ b/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java @@ -24,6 +24,7 @@ import org.apache.ratis.util.ProtoUtils; import org.apache.ratis.util.ReflectionUtils; import java.util.Arrays; +import java.util.List; import java.util.stream.Collectors; import static org.apache.ratis.proto.RaftProtos.RaftClientReplyProto.ExceptionDetailsCase.NOTLEADEREXCEPTION; @@ -158,7 +159,7 @@ public interface ClientProtoUtils { NotLeaderExceptionProto.newBuilder(); final RaftPeer suggestedLeader = nle.getSuggestedLeader(); if (suggestedLeader != null) { - nleBuilder.setSuggestedLeader(ProtoUtils.toRaftPeerProto(suggestedLeader)); + nleBuilder.setSuggestedLeader(suggestedLeader.getRaftPeerProto()); } nleBuilder.addAllPeersInConf( ProtoUtils.toRaftPeerProtos(Arrays.asList(nle.getPeers()))); @@ -253,8 +254,9 @@ public interface ClientProtoUtils { final RaftRpcReplyProto rp = replyProto.getRpcReply(); ClientId clientId = ClientId.valueOf(rp.getRequestorId()); final RaftGroupId groupId = ProtoUtils.toRaftGroupId(rp.getRaftGroupId()); - final Iterable<RaftGroupId> groupInfos = replyProto.getGroupIdList().stream() - .map(id -> ProtoUtils.toRaftGroupId(id)).collect(Collectors.toList()); + final List<RaftGroupId> groupInfos = replyProto.getGroupIdList().stream() + .map(ProtoUtils::toRaftGroupId) + .collect(Collectors.toList()); return new GroupListReply(clientId, RaftPeerId.valueOf(rp.getReplyId()), groupId, rp.getCallId(), rp.getSuccess(), groupInfos); } http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-client/src/main/java/org/apache/ratis/client/impl/RaftClientImpl.java ---------------------------------------------------------------------- diff --git a/ratis-client/src/main/java/org/apache/ratis/client/impl/RaftClientImpl.java b/ratis-client/src/main/java/org/apache/ratis/client/impl/RaftClientImpl.java index 36508b9..22c958f 100644 --- a/ratis-client/src/main/java/org/apache/ratis/client/impl/RaftClientImpl.java +++ b/ratis-client/src/main/java/org/apache/ratis/client/impl/RaftClientImpl.java @@ -20,7 +20,6 @@ package org.apache.ratis.client.impl; import org.apache.ratis.client.RaftClient; import org.apache.ratis.client.RaftClientConfigKeys; import org.apache.ratis.client.RaftClientRpc; -import org.apache.ratis.retry.RetryPolicies; import org.apache.ratis.retry.RetryPolicy; import org.apache.ratis.conf.RaftProperties; import org.apache.ratis.protocol.*; @@ -247,20 +246,21 @@ final class RaftClientImpl implements RaftClient { } @Override - public RaftClientReply getGroups(RaftPeerId server) - throws IOException { + public GroupListReply getGroupList(RaftPeerId server) throws IOException { Objects.requireNonNull(server, "server == null"); - return sendRequest(new GroupListRequest(clientId, server, - groupId, nextCallId())); + final RaftClientReply reply = sendRequest(new GroupListRequest(clientId, server, groupId, nextCallId())); + Preconditions.assertTrue(reply instanceof GroupListReply, () -> "Unexpected reply: " + reply); + return (GroupListReply)reply; } @Override - public RaftClientReply getGroupInfo(RaftGroupId raftGroupId, RaftPeerId server) throws IOException { + public GroupInfoReply getGroupInfo(RaftGroupId raftGroupId, RaftPeerId server) throws IOException { Objects.requireNonNull(server, "server == null"); RaftGroupId rgi = raftGroupId == null ? groupId : raftGroupId; - return sendRequest(new GroupInfoRequest(clientId, server, - rgi, nextCallId())); + final RaftClientReply reply = sendRequest(new GroupInfoRequest(clientId, server, rgi, nextCallId())); + Preconditions.assertTrue(reply instanceof GroupInfoReply, () -> "Unexpected reply: " + reply); + return (GroupInfoReply)reply; } private void addServers(Stream<RaftPeer> peersInNewConf) { http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-common/src/main/java/org/apache/ratis/protocol/GroupListReply.java ---------------------------------------------------------------------- diff --git a/ratis-common/src/main/java/org/apache/ratis/protocol/GroupListReply.java b/ratis-common/src/main/java/org/apache/ratis/protocol/GroupListReply.java index 77dfdf2..5a9b000 100644 --- a/ratis-common/src/main/java/org/apache/ratis/protocol/GroupListReply.java +++ b/ratis-common/src/main/java/org/apache/ratis/protocol/GroupListReply.java @@ -17,27 +17,29 @@ */ package org.apache.ratis.protocol; +import java.util.List; + /** * The response of server information request. Sent from server to client. */ public class GroupListReply extends RaftClientReply { - private final Iterable<RaftGroupId> groupIds; + private final List<RaftGroupId> groupIds; public GroupListReply( - RaftClientRequest request, Iterable<RaftGroupId> groupIds) { + RaftClientRequest request, List<RaftGroupId> groupIds) { super(request, null); this.groupIds = groupIds; } public GroupListReply( ClientId clientId, RaftPeerId serverId, RaftGroupId groupId, - long callId, boolean success, Iterable<RaftGroupId> groupIds) { + long callId, boolean success, List<RaftGroupId> groupIds) { super(clientId, serverId, groupId, callId, success, null, null, 0L, null); this.groupIds = groupIds; } - public Iterable<RaftGroupId> getGroupIds() { + public List<RaftGroupId> getGroupIds() { return groupIds; } } http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-common/src/main/java/org/apache/ratis/protocol/RaftPeer.java ---------------------------------------------------------------------- diff --git a/ratis-common/src/main/java/org/apache/ratis/protocol/RaftPeer.java b/ratis-common/src/main/java/org/apache/ratis/protocol/RaftPeer.java index 68252f3..e721f15 100644 --- a/ratis-common/src/main/java/org/apache/ratis/protocol/RaftPeer.java +++ b/ratis-common/src/main/java/org/apache/ratis/protocol/RaftPeer.java @@ -17,10 +17,13 @@ */ package org.apache.ratis.protocol; +import org.apache.ratis.proto.RaftProtos.RaftPeerProto; +import org.apache.ratis.util.JavaUtils; import org.apache.ratis.util.NetUtils; import java.net.InetSocketAddress; import java.util.Objects; +import java.util.function.Supplier; /** * A {@link RaftPeer} is a server in a Raft cluster. @@ -40,6 +43,8 @@ public class RaftPeer { /** The address of the peer. */ private final String address; + private final Supplier<RaftPeerProto> raftPeerProto; + /** Construct a peer with the given id and a null address. */ public RaftPeer(RaftPeerId id) { this(id, (String)null); @@ -54,6 +59,16 @@ public class RaftPeer { public RaftPeer(RaftPeerId id, String address) { this.id = Objects.requireNonNull(id, "id == null"); this.address = address; + this.raftPeerProto = JavaUtils.memoize(this::buildRaftPeerProto); + } + + private RaftPeerProto buildRaftPeerProto() { + final RaftPeerProto.Builder builder = RaftPeerProto.newBuilder() + .setId(getId().toByteString()); + if (getAddress() != null) { + builder.setAddress(getAddress()); + } + return builder.build(); } /** @return The id of the peer. */ @@ -66,6 +81,10 @@ public class RaftPeer { return address; } + public RaftPeerProto getRaftPeerProto() { + return raftPeerProto.get(); + } + @Override public String toString() { return id + ":" + address; http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-common/src/main/java/org/apache/ratis/util/ProtoUtils.java ---------------------------------------------------------------------- diff --git a/ratis-common/src/main/java/org/apache/ratis/util/ProtoUtils.java b/ratis-common/src/main/java/org/apache/ratis/util/ProtoUtils.java index e30aab1..35ee012 100644 --- a/ratis-common/src/main/java/org/apache/ratis/util/ProtoUtils.java +++ b/ratis-common/src/main/java/org/apache/ratis/util/ProtoUtils.java @@ -78,15 +78,6 @@ public interface ProtoUtils { ByteString.EMPTY : ByteString.copyFrom(bytes, offset, size); } - static RaftPeerProto toRaftPeerProto(RaftPeer peer) { - RaftPeerProto.Builder builder = RaftPeerProto.newBuilder() - .setId(peer.getId().toByteString()); - if (peer.getAddress() != null) { - builder.setAddress(peer.getAddress()); - } - return builder.build(); - } - static RaftPeer toRaftPeer(RaftPeerProto p) { return new RaftPeer(RaftPeerId.valueOf(p.getId()), p.getAddress()); } @@ -111,7 +102,7 @@ public interface ProtoUtils { @Override public RaftPeerProto next() { - return toRaftPeerProto(i.next()); + return i.next().getRaftPeerProto(); } }; } @@ -136,14 +127,14 @@ public interface ProtoUtils { static CommitInfoProto toCommitInfoProto(RaftPeer peer, long commitIndex) { return CommitInfoProto.newBuilder() - .setServer(toRaftPeerProto(peer)) + .setServer(peer.getRaftPeerProto()) .setCommitIndex(commitIndex) .build(); } - static void addCommitInfos(Collection<CommitInfoProto> commitInfos, Consumer<CommitInfoProto> adder) { + static void addCommitInfos(Collection<CommitInfoProto> commitInfos, Consumer<CommitInfoProto> accumulator) { if (commitInfos != null && !commitInfos.isEmpty()) { - commitInfos.stream().forEach(i -> adder.accept(i)); + commitInfos.forEach(accumulator); } } http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestGroupInfoWithHadoopRpc.java ---------------------------------------------------------------------- diff --git a/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestGroupInfoWithHadoopRpc.java b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestGroupInfoWithHadoopRpc.java new file mode 100644 index 0000000..03dda36 --- /dev/null +++ b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestGroupInfoWithHadoopRpc.java @@ -0,0 +1,25 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ratis.hadooprpc; + +import org.apache.ratis.server.impl.GroupInfoBaseTest; + +public class TestGroupInfoWithHadoopRpc + extends GroupInfoBaseTest<MiniRaftClusterWithHadoopRpc> + implements MiniRaftClusterWithHadoopRpc.Factory.Get{ +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestServerInformationWithHadoopRpc.java ---------------------------------------------------------------------- diff --git a/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestServerInformationWithHadoopRpc.java b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestServerInformationWithHadoopRpc.java deleted file mode 100644 index 8de6112..0000000 --- a/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestServerInformationWithHadoopRpc.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.ratis.hadooprpc; - -import org.apache.ratis.server.impl.ServerInformationBaseTest; - -public class TestServerInformationWithHadoopRpc - extends ServerInformationBaseTest<MiniRaftClusterWithHadoopRpc> - implements MiniRaftClusterWithHadoopRpc.Factory.Get{ -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java index 9a810c3..30ccdc7 100644 --- a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java +++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java @@ -352,7 +352,7 @@ public class RaftServerImpl implements RaftServerProtocol, RaftServerAsynchronou public RoleInfoProto getRoleInfoProto() { RaftPeerRole currentRole = role.getCurrentRole(); RoleInfoProto.Builder roleInfo = RoleInfoProto.newBuilder() - .setSelf(ProtoUtils.toRaftPeerProto(getPeer())) + .setSelf(getPeer().getRaftPeerProto()) .setRole(currentRole) .setRoleElapsedTimeMs(role.getRoleElapsedTimeMs()); switch (currentRole) { http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java index 803873a..c3ca1f7 100644 --- a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java +++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java @@ -221,7 +221,7 @@ public class RaftServerProxy implements RaftServer { } @Override - public Iterable<RaftGroupId> getGroupIds() { + public List<RaftGroupId> getGroupIds() { return impls.getGroupIds(); } http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java index ceac18b..bfec9b4 100644 --- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java +++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java @@ -331,7 +331,7 @@ public interface ServerProtoUtils { return ServerRpcProto.getDefaultInstance(); } return ServerRpcProto.newBuilder() - .setId(ProtoUtils.toRaftPeerProto(peer)) + .setId(peer.getRaftPeerProto()) .setLastRpcElapsedTimeMs(delay) .build(); } http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-server/src/test/java/org/apache/ratis/server/impl/GroupInfoBaseTest.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/server/impl/GroupInfoBaseTest.java b/ratis-server/src/test/java/org/apache/ratis/server/impl/GroupInfoBaseTest.java new file mode 100644 index 0000000..2437bff --- /dev/null +++ b/ratis-server/src/test/java/org/apache/ratis/server/impl/GroupInfoBaseTest.java @@ -0,0 +1,155 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ratis.server.impl; + +import org.apache.log4j.Level; +import org.apache.ratis.BaseTest; +import org.apache.ratis.MiniRaftCluster; +import org.apache.ratis.client.RaftClient; +import org.apache.ratis.protocol.*; +import org.apache.ratis.proto.RaftProtos.CommitInfoProto; +import org.apache.ratis.util.LogUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public abstract class GroupInfoBaseTest<CLUSTER extends MiniRaftCluster> + extends BaseTest + implements MiniRaftCluster.Factory.Get<CLUSTER> { + { + LogUtils.setLogLevel(RaftServerImpl.LOG, Level.DEBUG); + LogUtils.setLogLevel(RaftClient.LOG, Level.DEBUG); + } + + @Test + public void testGroupInfo() throws Exception { + runWithNewCluster(3, this::runTest); + } + + private void runTest(CLUSTER cluster) throws Exception { + // all the peers in the cluster are in the same group, get it. + RaftGroup group = cluster.getGroup(); + + List<RaftPeer> peers = cluster.getPeers(); + + //Multi-raft with the second group + RaftGroup group2 = RaftGroup.valueOf(RaftGroupId.randomId(), peers); + for(RaftPeer peer : peers) { + try(final RaftClient client = cluster.createClient(peer.getId())) { + client.groupAdd(group2, peer.getId()); + } + } + // check that all the peers return the list where both groups are included. And able to return GroupInfo + // for each of them. + for (RaftPeer peer : peers) { + try (final RaftClient client = cluster.createClient(peer.getId())) { + GroupListReply info = client.getGroupList(peer.getId()); + List<RaftGroupId> groupList = info.getGroupIds().stream() + .filter(id -> group.getGroupId().equals(id)).collect(Collectors.toList()); + assert (groupList.size() == 1); + final GroupInfoReply gi = client.getGroupInfo(groupList.get(0), peer.getId()); + assert (sameGroup(group, gi.getGroup())); + groupList = info.getGroupIds().stream() + .filter(id -> group2.getGroupId().equals(id)).collect(Collectors.toList()); + assert (groupList.size() == 1); + final GroupInfoReply gi2 = client.getGroupInfo(groupList.get(0), peer.getId()); + assert (sameGroup(group2, gi2.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 getGroupList + for(RaftPeer peer : peers) { + if (peer.getId().equals(killedFollower)) { + continue; + } + try(final RaftClient client = cluster.createClient(peer.getId())) { + GroupListReply info = client.getGroupList(peer.getId()); + Assert.assertEquals(1, info.getGroupIds().stream().filter(id -> group.getGroupId().equals(id)).count()); + for(CommitInfoProto i : info.getCommitInfos()) { + if (RaftPeerId.valueOf(i.getServer().getId()).equals(killedFollower)) { + Assert.assertTrue(i.getCommitIndex() <= maxCommit); + } else { + Assert.assertTrue(i.getCommitIndex() > maxCommit); + } + } + } + } + } + + RaftClientReply sendMessages(int n, MiniRaftCluster cluster) throws Exception { + LOG.info("sendMessages: " + n); + RaftClientReply reply = null; + try(final RaftClient client = cluster.createClient()) { + for(int i = 0; i < n; i++) { + reply = client.send(Message.valueOf("m" + i)); + } + } + return reply; + } + + private boolean sameGroup(RaftGroup expected, RaftGroup given) { + if (!expected.getGroupId().toString().equals( + given.getGroupId().toString())) { + return false; + } + Collection<RaftPeer> expectedPeers = expected.getPeers(); + Collection<RaftPeer> givenPeers = given.getPeers(); + if (expectedPeers.size() != givenPeers.size()) { + return false; + } + for (RaftPeer peerGiven : givenPeers) { + boolean found = false; + for (RaftPeer peerExpect : expectedPeers) { + if (peerGiven.getId().toString().equals( + peerExpect.getId().toString())) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-server/src/test/java/org/apache/ratis/server/impl/ServerInformationBaseTest.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/server/impl/ServerInformationBaseTest.java b/ratis-server/src/test/java/org/apache/ratis/server/impl/ServerInformationBaseTest.java deleted file mode 100644 index 77a4209..0000000 --- a/ratis-server/src/test/java/org/apache/ratis/server/impl/ServerInformationBaseTest.java +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.ratis.server.impl; - -import org.apache.log4j.Level; -import org.apache.ratis.BaseTest; -import org.apache.ratis.MiniRaftCluster; -import org.apache.ratis.client.RaftClient; -import org.apache.ratis.protocol.*; -import org.apache.ratis.proto.RaftProtos.CommitInfoProto; -import org.apache.ratis.util.LogUtils; -import org.junit.Assert; -import org.junit.Test; - -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import static org.apache.ratis.util.Preconditions.assertTrue; - -public abstract class ServerInformationBaseTest<CLUSTER extends MiniRaftCluster> - extends BaseTest - implements MiniRaftCluster.Factory.Get<CLUSTER> { - static { - LogUtils.setLogLevel(RaftServerImpl.LOG, Level.DEBUG); - LogUtils.setLogLevel(RaftClient.LOG, Level.DEBUG); - } - - @Test - public void testServerInformation() throws Exception { - runTest(3); - } - - 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(); - - //Multi-raft with the second group - RaftGroup group2 = RaftGroup.valueOf(RaftGroupId.randomId(), peers); - for(RaftPeer peer : peers) { - try(final RaftClient client = cluster.createClient(peer.getId())) { - client.groupAdd(group2, peer.getId()); - } - } - // check that all the peers return the list where both groups are included. And able to return GroupInfo - // for each of them. - for (RaftPeer peer : peers) { - try (final RaftClient client = cluster.createClient(peer.getId())) { - RaftClientReply reply = client.getGroups(peer.getId()); - assertTrue(reply instanceof GroupListReply); - GroupListReply info = (GroupListReply) reply; - List<RaftGroupId> groupList = (StreamSupport - .stream(info.getGroupIds().spliterator(), false) - .filter(id -> group.getGroupId().equals(id)).collect(Collectors.toList())); - assert (groupList.size() == 1); - reply = client.getGroupInfo(groupList.get(0), peer.getId()); - assertTrue(reply instanceof GroupInfoReply); - GroupInfoReply gi = (GroupInfoReply) reply; - assert (sameGroup(group, gi.getGroup())); - groupList = (StreamSupport - .stream(info.getGroupIds().spliterator(), false) - .filter(id -> group2.getGroupId().equals(id)).collect(Collectors.toList())); - assert (groupList.size() == 1); - reply = client.getGroupInfo(groupList.get(0), peer.getId()); - assertTrue(reply instanceof GroupInfoReply); - gi = (GroupInfoReply) reply; - assert (sameGroup(group2, gi.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 getGroups - for(RaftPeer peer : peers) { - if (peer.getId().equals(killedFollower)) { - continue; - } - try(final RaftClient client = cluster.createClient(peer.getId())) { - RaftClientReply reply = client.getGroups(peer.getId()); - assertTrue(reply instanceof GroupListReply); - GroupListReply info = (GroupListReply)reply; - assertTrue(StreamSupport - .stream(info.getGroupIds().spliterator(), false) - .filter(id -> group.getGroupId().equals(id)).collect(Collectors.toList()).size() == 1); - 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(); - } - - RaftClientReply sendMessages(int n, MiniRaftCluster cluster) throws Exception { - LOG.info("sendMessages: " + n); - RaftClientReply reply = null; - try(final RaftClient client = cluster.createClient()) { - for(int i = 0; i < n; i++) { - reply = client.send(Message.valueOf("m" + i)); - } - } - return reply; - } - - private boolean sameGroup(RaftGroup expected, RaftGroup given) { - if (!expected.getGroupId().toString().equals( - given.getGroupId().toString())) { - return false; - } - Collection<RaftPeer> expectedPeers = expected.getPeers(); - Collection<RaftPeer> givenPeers = given.getPeers(); - if (expectedPeers.size() != givenPeers.size()) { - return false; - } - for (RaftPeer peerGiven : givenPeers) { - boolean found = false; - for (RaftPeer peerExpect : expectedPeers) { - if (peerGiven.getId().toString().equals( - peerExpect.getId().toString())) { - found = true; - break; - } - } - if (!found) { - return false; - } - } - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-test/src/test/java/org/apache/ratis/grpc/TestGroupInfoWithGrpc.java ---------------------------------------------------------------------- diff --git a/ratis-test/src/test/java/org/apache/ratis/grpc/TestGroupInfoWithGrpc.java b/ratis-test/src/test/java/org/apache/ratis/grpc/TestGroupInfoWithGrpc.java new file mode 100644 index 0000000..ef4e6c7 --- /dev/null +++ b/ratis-test/src/test/java/org/apache/ratis/grpc/TestGroupInfoWithGrpc.java @@ -0,0 +1,25 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ratis.grpc; + +import org.apache.ratis.server.impl.GroupInfoBaseTest; + +public class TestGroupInfoWithGrpc + extends GroupInfoBaseTest<MiniRaftClusterWithGrpc> + implements MiniRaftClusterWithGrpc.FactoryGet { +} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-test/src/test/java/org/apache/ratis/grpc/TestServerInformationWithGrpc.java ---------------------------------------------------------------------- diff --git a/ratis-test/src/test/java/org/apache/ratis/grpc/TestServerInformationWithGrpc.java b/ratis-test/src/test/java/org/apache/ratis/grpc/TestServerInformationWithGrpc.java deleted file mode 100644 index 30be724..0000000 --- a/ratis-test/src/test/java/org/apache/ratis/grpc/TestServerInformationWithGrpc.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.ratis.grpc; - -import org.apache.ratis.server.impl.ServerInformationBaseTest; - -public class TestServerInformationWithGrpc - extends ServerInformationBaseTest<MiniRaftClusterWithGrpc> - implements MiniRaftClusterWithGrpc.FactoryGet { -} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-test/src/test/java/org/apache/ratis/netty/TestGroupInfoWithNetty.java ---------------------------------------------------------------------- diff --git a/ratis-test/src/test/java/org/apache/ratis/netty/TestGroupInfoWithNetty.java b/ratis-test/src/test/java/org/apache/ratis/netty/TestGroupInfoWithNetty.java new file mode 100644 index 0000000..ea0320d --- /dev/null +++ b/ratis-test/src/test/java/org/apache/ratis/netty/TestGroupInfoWithNetty.java @@ -0,0 +1,25 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ratis.netty; + +import org.apache.ratis.server.impl.GroupInfoBaseTest; + +public class TestGroupInfoWithNetty + extends GroupInfoBaseTest<MiniRaftClusterWithNetty> + implements MiniRaftClusterWithNetty.FactoryGet { +} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-test/src/test/java/org/apache/ratis/netty/TestServerInformationWithNetty.java ---------------------------------------------------------------------- diff --git a/ratis-test/src/test/java/org/apache/ratis/netty/TestServerInformationWithNetty.java b/ratis-test/src/test/java/org/apache/ratis/netty/TestServerInformationWithNetty.java deleted file mode 100644 index d1bcae4..0000000 --- a/ratis-test/src/test/java/org/apache/ratis/netty/TestServerInformationWithNetty.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.ratis.netty; - -import org.apache.ratis.server.impl.ServerInformationBaseTest; - -public class TestServerInformationWithNetty - extends ServerInformationBaseTest<MiniRaftClusterWithNetty> - implements MiniRaftClusterWithNetty.FactoryGet { -} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-test/src/test/java/org/apache/ratis/server/simulation/TestGroupInfoWithSimulatedRpc.java ---------------------------------------------------------------------- diff --git a/ratis-test/src/test/java/org/apache/ratis/server/simulation/TestGroupInfoWithSimulatedRpc.java b/ratis-test/src/test/java/org/apache/ratis/server/simulation/TestGroupInfoWithSimulatedRpc.java new file mode 100644 index 0000000..e115e31 --- /dev/null +++ b/ratis-test/src/test/java/org/apache/ratis/server/simulation/TestGroupInfoWithSimulatedRpc.java @@ -0,0 +1,25 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ratis.server.simulation; + +import org.apache.ratis.server.impl.GroupInfoBaseTest; + +public class TestGroupInfoWithSimulatedRpc + extends GroupInfoBaseTest<MiniRaftClusterWithSimulatedRpc> + implements MiniRaftClusterWithSimulatedRpc.FactoryGet { +} http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/d4ec63a0/ratis-test/src/test/java/org/apache/ratis/server/simulation/TestServerInformationWithSimulatedRpc.java ---------------------------------------------------------------------- diff --git a/ratis-test/src/test/java/org/apache/ratis/server/simulation/TestServerInformationWithSimulatedRpc.java b/ratis-test/src/test/java/org/apache/ratis/server/simulation/TestServerInformationWithSimulatedRpc.java deleted file mode 100644 index f7025a5..0000000 --- a/ratis-test/src/test/java/org/apache/ratis/server/simulation/TestServerInformationWithSimulatedRpc.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.ratis.server.simulation; - -import org.apache.ratis.server.impl.ServerInformationBaseTest; - -public class TestServerInformationWithSimulatedRpc - extends ServerInformationBaseTest<MiniRaftClusterWithSimulatedRpc> - implements MiniRaftClusterWithSimulatedRpc.FactoryGet { -}
