You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by as...@apache.org on 2021/02/19 17:30:51 UTC

[ignite-3] branch ignite-14149 updated: IGNITE-14149 Services.

This is an automated email from the ASF dual-hosted git repository.

ascherbakov pushed a commit to branch ignite-14149
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/ignite-14149 by this push:
     new d70fe7d  IGNITE-14149 Services.
d70fe7d is described below

commit d70fe7d4fff6b9722e3bbefe69404f99e7c3e17c
Author: Alexey Scherbakov <al...@gmail.com>
AuthorDate: Fri Feb 19 20:30:37 2021 +0300

    IGNITE-14149 Services.
---
 modules/raft-client/pom.xml                        |   5 +-
 .../ignite/raft/client/rpc/RaftGroupRpcClient.java |  37 +++---
 .../client/rpc/impl/RaftGroupRpcClientImpl.java    | 127 ++++++++++++---------
 .../service/RaftGroupClientRequestListener.java    |  12 ++
 .../service/RaftGroupClientRequestService.java     |  10 ++
 .../client/service/RaftGroupClientService.java     |   8 --
 .../client/service/RaftGroupManagmentService.java  | 122 ++++++++++++++++++++
 .../raft/client/service/RaftGroupMgmtService.java  |   5 -
 .../impl/RaftGroupClientRequestServiceImpl.java    |  17 +++
 .../impl/RaftGroupManagementServiceImpl.java       |  66 +++++++++++
 .../ignite/raft/client/RaftGroupRpcClientTest.java |   3 +-
 11 files changed, 329 insertions(+), 83 deletions(-)

diff --git a/modules/raft-client/pom.xml b/modules/raft-client/pom.xml
index 05f2489..6242962 100644
--- a/modules/raft-client/pom.xml
+++ b/modules/raft-client/pom.xml
@@ -50,7 +50,10 @@
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
-
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/rpc/RaftGroupRpcClient.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/rpc/RaftGroupRpcClient.java
index acdac5b..986fd71 100644
--- a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/rpc/RaftGroupRpcClient.java
+++ b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/rpc/RaftGroupRpcClient.java
@@ -16,11 +16,12 @@
  */
 package org.apache.ignite.raft.client.rpc;
 
-import java.util.concurrent.Future;
+import java.util.concurrent.CompletableFuture;
 import org.apache.ignite.raft.State;
 import org.apache.ignite.raft.PeerId;
 import org.apache.ignite.raft.rpc.Message;
 import org.apache.ignite.raft.rpc.RaftGroupMessage;
+import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.raft.client.RaftClientCommonMessages.AddLearnersRequest;
 import static org.apache.ignite.raft.client.RaftClientCommonMessages.AddPeerRequest;
@@ -39,14 +40,22 @@ import static org.apache.ignite.raft.client.RaftClientCommonMessages.TransferLea
 
 /**
  * Low-level raft group RPC client.
+ * <p>
+ * Additionally maintains raft group state.
  */
 public interface RaftGroupRpcClient {
     /**
      * @param groupId Group id.
-     * @param refresh Refresh state.
-     * @return Current group state.
+     * @return Current group state or null if state is not yet initalized.
      */
-    State state(String groupId, boolean refresh);
+    @Nullable State state(String groupId);
+
+    /**
+     * Refreshes a state of initialized group.
+     * @param groupId Group id.
+     * @return A future.
+     */
+    CompletableFuture<PeerId> refreshLeader(String groupId);
 
     /**
      * Adds a voring peer to the raft group.
@@ -54,7 +63,7 @@ public interface RaftGroupRpcClient {
      * @param request   request data
      * @return A future with the result
      */
-    Future<AddPeerResponse> addPeer(AddPeerRequest request);
+    CompletableFuture<AddPeerResponse> addPeer(AddPeerRequest request);
 
     /**
      * Removes a peer from the raft group.
@@ -63,7 +72,7 @@ public interface RaftGroupRpcClient {
      * @param request   request data
      * @return a future with result
      */
-    Future<RemovePeerResponse> removePeer(RemovePeerRequest request);
+    CompletableFuture<RemovePeerResponse> removePeer(RemovePeerRequest request);
 
     /**
      * Locally resets raft group peers. Intended for recovering from a group unavailability at the price of consistency.
@@ -72,7 +81,7 @@ public interface RaftGroupRpcClient {
      * @param request   request data
      * @return A future with result.
      */
-    Future<StatusResponse> resetPeers(PeerId peerId, ResetPeerRequest request);
+    CompletableFuture<StatusResponse> resetPeers(PeerId peerId, ResetPeerRequest request);
 
     /**
      * Takes a local snapshot.
@@ -82,7 +91,7 @@ public interface RaftGroupRpcClient {
      * @param done      callback
      * @return a future with result
      */
-    Future<StatusResponse> snapshot(PeerId peerId, SnapshotRequest request);
+    CompletableFuture<StatusResponse> snapshot(PeerId peerId, SnapshotRequest request);
 
     /**
      * Change peers.
@@ -92,7 +101,7 @@ public interface RaftGroupRpcClient {
      * @param done      callback
      * @return a future with result
      */
-    Future<ChangePeersResponse> changePeers(ChangePeersRequest request);
+    CompletableFuture<ChangePeersResponse> changePeers(ChangePeersRequest request);
 
     /**
      * Adds learners.
@@ -102,7 +111,7 @@ public interface RaftGroupRpcClient {
      * @param done      callback
      * @return a future with result
      */
-    Future<LearnersOpResponse> addLearners(AddLearnersRequest request);
+    CompletableFuture<LearnersOpResponse> addLearners(AddLearnersRequest request);
 
     /**
      * Removes learners.
@@ -112,7 +121,7 @@ public interface RaftGroupRpcClient {
      * @param done      callback
      * @return a future with result
      */
-    Future<LearnersOpResponse> removeLearners(RemoveLearnersRequest request);
+    CompletableFuture<LearnersOpResponse> removeLearners(RemoveLearnersRequest request);
 
     /**
      * Resets learners to new set.
@@ -122,7 +131,7 @@ public interface RaftGroupRpcClient {
      * @param done      callback
      * @return a future with result
      */
-    Future<LearnersOpResponse> resetLearners(ResetLearnersRequest request);
+    CompletableFuture<LearnersOpResponse> resetLearners(ResetLearnersRequest request);
 
     /**
      * Transfer leadership to other peer.
@@ -132,7 +141,7 @@ public interface RaftGroupRpcClient {
      * @param done      callback
      * @return a future with result
      */
-    Future<StatusResponse> transferLeader(TransferLeaderRequest request);
+    CompletableFuture<StatusResponse> transferLeader(TransferLeaderRequest request);
 
     /**
      * Performs a custom action defined by specific request on the raft group leader.
@@ -142,5 +151,5 @@ public interface RaftGroupRpcClient {
      * @param done      callback
      * @return a future with result
      */
-    <R extends Message> Future<R> sendCustom(RaftGroupMessage request);
+    <R extends Message> CompletableFuture<R> sendCustom(RaftGroupMessage request);
 }
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/rpc/impl/RaftGroupRpcClientImpl.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/rpc/impl/RaftGroupRpcClientImpl.java
index 86dbd4c..d7dc4c8 100644
--- a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/rpc/impl/RaftGroupRpcClientImpl.java
+++ b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/rpc/impl/RaftGroupRpcClientImpl.java
@@ -7,8 +7,9 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
 import org.apache.ignite.raft.PeerId;
 import org.apache.ignite.raft.RaftException;
 import org.apache.ignite.raft.State;
@@ -45,43 +46,75 @@ public class RaftGroupRpcClientImpl implements RaftGroupRpcClient {
         executor = Executors.newWorkStealingPool();
     }
 
-    @Override public State state(String groupId, boolean refresh) {
-        return states.get(groupId);
+    @Override public State state(String groupId) {
+        State newState = new State();
+
+        State state = states.putIfAbsent(groupId, newState);
+
+        if (state == null)
+            state = newState;
+
+        return state;
+    }
+
+    @Override public CompletableFuture<PeerId> refreshLeader(String groupId) {
+        State state = state(groupId);
+
+        if (state.getLeader() == null) {
+            synchronized (state) {
+                PeerId leader = state.getLeader();
+
+                if (leader == null) {
+                    return refreshLeader(initialCfgNodes.iterator().next(), groupId).
+                        thenApply(new Function<RaftClientCommonMessages.GetLeaderResponse, PeerId>() {
+                            @Override public PeerId apply(RaftClientCommonMessages.GetLeaderResponse getLeaderResponse) {
+                                PeerId leaderId = getLeaderResponse.getLeaderId();
+
+                                state.setLeader(leaderId);
+
+                                return leaderId;
+                            }
+                        });
+                }
+            }
+        }
+
+        return CompletableFuture.completedFuture(state.getLeader());
     }
 
-    @Override public Future<RaftClientCommonMessages.AddPeerResponse> addPeer(RaftClientCommonMessages.AddPeerRequest request) {
+    @Override public CompletableFuture<RaftClientCommonMessages.AddPeerResponse> addPeer(RaftClientCommonMessages.AddPeerRequest request) {
         return null;
     }
 
-    @Override public Future<RaftClientCommonMessages.RemovePeerResponse> removePeer(RaftClientCommonMessages.RemovePeerRequest request) {
+    @Override public CompletableFuture<RaftClientCommonMessages.RemovePeerResponse> removePeer(RaftClientCommonMessages.RemovePeerRequest request) {
         return null;
     }
 
-    @Override public Future<StatusResponse> resetPeers(PeerId peerId, RaftClientCommonMessages.ResetPeerRequest request) {
+    @Override public CompletableFuture<StatusResponse> resetPeers(PeerId peerId, RaftClientCommonMessages.ResetPeerRequest request) {
         return null;
     }
 
-    @Override public Future<StatusResponse> snapshot(PeerId peerId, RaftClientCommonMessages.SnapshotRequest request) {
+    @Override public CompletableFuture<StatusResponse> snapshot(PeerId peerId, RaftClientCommonMessages.SnapshotRequest request) {
         return null;
     }
 
-    @Override public Future<RaftClientCommonMessages.ChangePeersResponse> changePeers(RaftClientCommonMessages.ChangePeersRequest request) {
+    @Override public CompletableFuture<RaftClientCommonMessages.ChangePeersResponse> changePeers(RaftClientCommonMessages.ChangePeersRequest request) {
         return null;
     }
 
-    @Override public Future<RaftClientCommonMessages.LearnersOpResponse> addLearners(RaftClientCommonMessages.AddLearnersRequest request) {
+    @Override public CompletableFuture<RaftClientCommonMessages.LearnersOpResponse> addLearners(RaftClientCommonMessages.AddLearnersRequest request) {
         return null;
     }
 
-    @Override public Future<RaftClientCommonMessages.LearnersOpResponse> removeLearners(RaftClientCommonMessages.RemoveLearnersRequest request) {
+    @Override public CompletableFuture<RaftClientCommonMessages.LearnersOpResponse> removeLearners(RaftClientCommonMessages.RemoveLearnersRequest request) {
         return null;
     }
 
-    @Override public Future<RaftClientCommonMessages.LearnersOpResponse> resetLearners(RaftClientCommonMessages.ResetLearnersRequest request) {
+    @Override public CompletableFuture<RaftClientCommonMessages.LearnersOpResponse> resetLearners(RaftClientCommonMessages.ResetLearnersRequest request) {
         return null;
     }
 
-    @Override public Future<StatusResponse> transferLeader(RaftClientCommonMessages.TransferLeaderRequest request) {
+    @Override public CompletableFuture<StatusResponse> transferLeader(RaftClientCommonMessages.TransferLeaderRequest request) {
         return null;
     }
 
@@ -102,57 +135,43 @@ public class RaftGroupRpcClientImpl implements RaftGroupRpcClient {
         return fut;
     }
 
-    @Override public <R extends Message> Future<R> sendCustom(RaftGroupMessage request) {
-        State newState = new State();
-
-        State state = states.putIfAbsent(request.getGroupId(), newState);
-
-        if (state == null)
-            state = newState;
+    @Override public <R extends Message> CompletableFuture<R> sendCustom(RaftGroupMessage request) {
+        State state = state(request.getGroupId());
 
         CompletableFuture<R> fut = new CompletableFuture<>();
 
         fut.orTimeout(defaultTimeout, TimeUnit.MILLISECONDS);
 
-        if (state.getLeader() == null) {
-            synchronized (state) {
-                PeerId leader = state.getLeader();
-
-                if (leader == null) {
-                    CompletableFuture<RaftClientCommonMessages.GetLeaderResponse> fut0 =
-                        refreshLeader(initialCfgNodes.iterator().next(), request.getGroupId()); // TODO asch search all nodes.
-
-                    try {
-                        state.setLeader(fut0.get(defaultTimeout, TimeUnit.MILLISECONDS).getLeaderId());
-                    }
-                    catch (Exception e) {
-                        fut.completeExceptionally(e);
-
-                        return fut;
-                    }
+        CompletableFuture<PeerId> fut0 = refreshLeader(request.getGroupId());
+
+        // TODO implement clean chaining.
+        fut0.whenComplete(new BiConsumer<PeerId, Throwable>() {
+            @Override public void accept(PeerId peerId, Throwable error) {
+                if (error == null) {
+                    rpcClient.invokeAsync(state.getLeader().getNode(), request, new InvokeCallback<R>() {
+                        @Override public void complete(R response, Throwable err) {
+                            if (err != null)
+                                fut.completeExceptionally(err);
+                            else {
+                                if (response instanceof StatusResponse) {
+                                    StatusResponse resp = (StatusResponse) response;
+
+                                    // Translate error response to exception with the code.
+                                    if (resp.getStatusCode() != 0)
+                                        fut.completeExceptionally(new RaftException(resp.getStatusCode(), resp.getStatusMsg()));
+                                    else
+                                        fut.complete(response);
+                                } else
+                                    fut.complete(response);
+                            }
+                        }
+                    }, executor, defaultTimeout);
                 }
-            }
-        }
-
-        rpcClient.invokeAsync(state.getLeader().getNode(), request, new InvokeCallback<R>() {
-            @Override public void complete(R response, Throwable err) {
-                if (err != null)
-                    fut.completeExceptionally(err);
                 else {
-                    if (response instanceof StatusResponse) {
-                        StatusResponse resp = (StatusResponse) response;
-
-                        // Translate error response to exception with the code.
-                        if (resp.getStatusCode() != 0)
-                            fut.completeExceptionally(new RaftException(resp.getStatusCode(), resp.getStatusMsg()));
-                        else
-                            fut.complete(response);
-                    }
-                    else
-                        fut.complete(response);
+                    fut.completeExceptionally(error);
                 }
             }
-        }, executor, defaultTimeout);
+        });
 
         return fut;
     }
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientRequestListener.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientRequestListener.java
new file mode 100644
index 0000000..3649a41
--- /dev/null
+++ b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientRequestListener.java
@@ -0,0 +1,12 @@
+package org.apache.ignite.raft.client.service;
+
+import java.util.Iterator;
+
+/**
+ * A listener for raft group clien requests.
+ */
+public interface RaftGroupClientRequestListener {
+    void onReads(Iterator iterator);
+
+    void onWrites(Iterator iterator);
+}
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientRequestService.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientRequestService.java
new file mode 100644
index 0000000..9fdc19e
--- /dev/null
+++ b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientRequestService.java
@@ -0,0 +1,10 @@
+package org.apache.ignite.raft.client.service;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ *
+ */
+public interface RaftGroupClientRequestService {
+    <T, R> CompletableFuture<R> submit(T request);
+}
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientService.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientService.java
deleted file mode 100644
index 82f71f7..0000000
--- a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupClientService.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.apache.ignite.raft.client.service;
-
-/**
- *
- */
-public interface RaftGroupClientService {
-    <T, R> R submit(T request);
-}
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupManagmentService.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupManagmentService.java
new file mode 100644
index 0000000..725d3e1
--- /dev/null
+++ b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupManagmentService.java
@@ -0,0 +1,122 @@
+package org.apache.ignite.raft.client.service;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.raft.PeerId;
+import org.jetbrains.annotations.Nullable;
+
+/** */
+public interface RaftGroupManagmentService {
+    /**
+     * @param groupId
+     * @return Peer id.
+     */
+    @Nullable PeerId getLeader(String groupId);
+
+    /**
+     * @param groupId
+     * @return List of peers.
+     */
+    @Nullable List<PeerId> getPeers(String groupId);
+
+    /**
+     * @param groupId
+     * @return List of peers.
+     */
+    @Nullable List<PeerId> getLearners(String groupId);
+
+    /**
+     * Adds a voring peer to the raft group.
+     *
+     * @param request   request data
+     * @return A future with the result
+     */
+    CompletableFuture<PeersChangeState> addPeer(PeerId peerId);
+
+    /**
+     * Removes a peer from the raft group.
+     *
+     * @param endpoint  server address
+     * @param request   request data
+     * @return a future with result
+     */
+    CompletableFuture<PeersChangeState> removePeer(PeerId peerId);
+
+    /**
+     * Locally resets raft group peers. Intended for recovering from a group unavailability at the price of consistency.
+     *
+     * @param peerId Node to execute the configuration reset.
+     * @param request   request data
+     * @return A future with result.
+     */
+    CompletableFuture<Void> resetPeers(PeerId peerId, List<PeerId> peers);
+
+    /**
+     * Takes a local snapshot.
+     *
+     * @param peerId  Peer id.
+     * @param request   request data
+     * @param done      callback
+     * @return a future with result
+     */
+    CompletableFuture<Void> snapshot(PeerId peerId);
+
+    /**
+     * Change peers.
+     *
+     * @param endpoint  server address
+     * @param request   request data
+     * @param done      callback
+     * @return a future with result
+     */
+    CompletableFuture<PeersChangeState> changePeers(List<PeerId> peers);
+
+    /**
+     * Adds learners.
+     *
+     * @param endpoint  server address
+     * @param request   request data
+     * @param done      callback
+     * @return a future with result
+     */
+    CompletableFuture<PeersChangeState> addLearners(List<PeerId> peers);
+
+    /**
+     * Removes learners.
+     *
+     * @param endpoint  server address
+     * @param request   request data
+     * @param done      callback
+     * @return a future with result
+     */
+    CompletableFuture<PeersChangeState> removeLearners(List<PeerId> peers);
+
+    /**
+     * Resets learners to new set.
+     *
+     * @param endpoint  server address
+     * @param request   request data
+     * @param done      callback
+     * @return a future with result
+     */
+    CompletableFuture<PeersChangeState> resetLearners(List<PeerId> peers);
+
+    /**
+     * Transfer leadership to other peer.
+     *
+     * @param endpoint  server address
+     * @param request   request data
+     * @param done      callback
+     * @return a future with result
+     */
+    CompletableFuture<Void> transferLeader(PeerId newLeader);
+
+    /**
+     * Represents a change in peers list.
+     */
+    interface PeersChangeState {
+        List<PeerId> getOld();
+
+        List<PeerId> getNew();
+    }
+}
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupMgmtService.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupMgmtService.java
deleted file mode 100644
index ae86483..0000000
--- a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/RaftGroupMgmtService.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.apache.ignite.raft.client.service;
-
-/** */
-public interface RaftGroupMgmtService {
-}
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/impl/RaftGroupClientRequestServiceImpl.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/impl/RaftGroupClientRequestServiceImpl.java
new file mode 100644
index 0000000..303a90e
--- /dev/null
+++ b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/impl/RaftGroupClientRequestServiceImpl.java
@@ -0,0 +1,17 @@
+package org.apache.ignite.raft.client.service.impl;
+
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.raft.client.rpc.RaftGroupRpcClient;
+import org.apache.ignite.raft.client.service.RaftGroupClientRequestService;
+
+public class RaftGroupClientRequestServiceImpl implements RaftGroupClientRequestService {
+    private RaftGroupRpcClient rpcClient;
+
+    public RaftGroupClientRequestServiceImpl(RaftGroupRpcClient rpcClient) {
+        this.rpcClient = rpcClient;
+    }
+
+    @Override public <T, R> CompletableFuture<R> submit(T request) {
+        return null;
+    }
+}
diff --git a/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/impl/RaftGroupManagementServiceImpl.java b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/impl/RaftGroupManagementServiceImpl.java
new file mode 100644
index 0000000..ff3749f
--- /dev/null
+++ b/modules/raft-client/src/main/java/org/apache/ignite/raft/client/service/impl/RaftGroupManagementServiceImpl.java
@@ -0,0 +1,66 @@
+package org.apache.ignite.raft.client.service.impl;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.raft.PeerId;
+import org.apache.ignite.raft.State;
+import org.apache.ignite.raft.client.rpc.RaftGroupRpcClient;
+import org.apache.ignite.raft.client.service.RaftGroupManagmentService;
+import org.apache.ignite.raft.rpc.Node;
+import org.jetbrains.annotations.Nullable;
+
+public class RaftGroupManagementServiceImpl implements RaftGroupManagmentService {
+    private RaftGroupRpcClient rpcClient;
+
+    public RaftGroupManagementServiceImpl(RaftGroupRpcClient rpcClient) {
+        this.rpcClient = rpcClient;
+    }
+
+    @Override public @Nullable PeerId getLeader(String groupId) {
+        return rpcClient.state(groupId).getLeader();
+    }
+
+    @Override public @Nullable List<PeerId> getPeers(String groupId) {
+        return rpcClient.state(groupId).getPeers();
+    }
+
+    @Override public @Nullable List<PeerId> getLearners(String groupId) {
+        return rpcClient.state(groupId).getLearners();
+    }
+
+    @Override public CompletableFuture<PeersChangeState> addPeer(PeerId peerId) {
+        return null;
+    }
+
+    @Override public CompletableFuture<PeersChangeState> removePeer(PeerId peerId) {
+        return null;
+    }
+
+    @Override public CompletableFuture<Void> resetPeers(PeerId peerId, List<PeerId> peers) {
+        return null;
+    }
+
+    @Override public CompletableFuture<Void> snapshot(PeerId peerId) {
+        return null;
+    }
+
+    @Override public CompletableFuture<PeersChangeState> changePeers(List<PeerId> peers) {
+        return null;
+    }
+
+    @Override public CompletableFuture<PeersChangeState> addLearners(List<PeerId> peers) {
+        return null;
+    }
+
+    @Override public CompletableFuture<PeersChangeState> removeLearners(List<PeerId> peers) {
+        return null;
+    }
+
+    @Override public CompletableFuture<PeersChangeState> resetLearners(List<PeerId> peers) {
+        return null;
+    }
+
+    @Override public CompletableFuture<Void> transferLeader(PeerId newLeader) {
+        return null;
+    }
+}
diff --git a/modules/raft-client/src/test/java/org/apache/ignite/raft/client/RaftGroupRpcClientTest.java b/modules/raft-client/src/test/java/org/apache/ignite/raft/client/RaftGroupRpcClientTest.java
index 5aa14b5..e7012e2 100644
--- a/modules/raft-client/src/test/java/org/apache/ignite/raft/client/RaftGroupRpcClientTest.java
+++ b/modules/raft-client/src/test/java/org/apache/ignite/raft/client/RaftGroupRpcClientTest.java
@@ -47,9 +47,10 @@ public class RaftGroupRpcClientTest {
 
         Future<Message> fut = client.sendCustom(req);
 
-        State state = client.state(groupId, false);
+        State state = client.state(groupId);
 
         // Expecting raft group state to be transparently loaded on first request.
+        // TODO FIXME broken
         assertEquals(leader, state.getLeader());
 
         assertTrue(fut.get() instanceof JunkResponse);