You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by ru...@apache.org on 2020/12/13 23:32:02 UTC

[incubator-ratis] branch master updated: RATIS-1236. Move out the leader only methods from ServerProtoUtils. (#351)

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

runzhiwang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ratis.git


The following commit(s) were added to refs/heads/master by this push:
     new 17a2198  RATIS-1236. Move out the leader only methods from ServerProtoUtils. (#351)
17a2198 is described below

commit 17a2198b0016a66494da4344d218593ed2c4d7de
Author: Tsz-Wo Nicholas Sze <sz...@apache.org>
AuthorDate: Mon Dec 14 07:31:53 2020 +0800

    RATIS-1236. Move out the leader only methods from ServerProtoUtils. (#351)
    
    * RATIS-1236. Move out the leader only methods from ServerProtoUtils.
    
    * Fix a bug
---
 .../org/apache/ratis/server/RaftConfiguration.java |  3 +
 .../ratis/server/impl/RaftConfigurationImpl.java   |  3 +-
 .../apache/ratis/server/impl/ServerImplUtils.java  | 11 ++++
 .../apache/ratis/server/impl/ServerProtoUtils.java | 71 +--------------------
 .../org/apache/ratis/server/impl/ServerState.java  | 10 +--
 .../server/leader/InstallSnapshotRequests.java     |  9 ++-
 .../ratis/server/leader/LeaderProtoUtils.java      | 73 ++++++++++++++++++++++
 .../ratis/server/leader/LogAppenderBase.java       |  4 +-
 .../apache/ratis/server/protocol/TermIndex.java    |  9 +++
 .../apache/ratis/server/raftlog/LogProtoUtils.java | 12 ++++
 .../apache/ratis/server/storage/RaftStorage.java   |  4 +-
 11 files changed, 125 insertions(+), 84 deletions(-)

diff --git a/ratis-server/src/main/java/org/apache/ratis/server/RaftConfiguration.java b/ratis-server/src/main/java/org/apache/ratis/server/RaftConfiguration.java
index 2f6cc0f..ffff90c 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/RaftConfiguration.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/RaftConfiguration.java
@@ -44,4 +44,7 @@ public interface RaftConfiguration {
 
   /** @return all the peers in the previous configuration. */
   Collection<RaftPeer> getPreviousPeers();
+
+  /** @return the index of the corresponding log entry for the current configuration. */
+  long getLogEntryIndex();
 }
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftConfigurationImpl.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftConfigurationImpl.java
index 5469ce1..32ded03 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftConfigurationImpl.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftConfigurationImpl.java
@@ -226,7 +226,8 @@ final class RaftConfigurationImpl implements RaftConfiguration {
     return true;
   }
 
-  long getLogEntryIndex() {
+  @Override
+  public long getLogEntryIndex() {
     return logEntryIndex;
   }
 
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerImplUtils.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerImplUtils.java
index db452da..cf92150 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerImplUtils.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerImplUtils.java
@@ -20,7 +20,9 @@ package org.apache.ratis.server.impl;
 import org.apache.ratis.conf.Parameters;
 import org.apache.ratis.conf.RaftProperties;
 import org.apache.ratis.protocol.RaftGroup;
+import org.apache.ratis.protocol.RaftPeer;
 import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.server.RaftConfiguration;
 import org.apache.ratis.server.RaftServer;
 import org.apache.ratis.server.protocol.TermIndex;
 import org.apache.ratis.server.raftlog.RaftLog;
@@ -30,6 +32,7 @@ import org.apache.ratis.util.JavaUtils;
 import org.apache.ratis.util.TimeDuration;
 
 import java.io.IOException;
+import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 
@@ -66,6 +69,14 @@ public final class ServerImplUtils {
     return proxy;
   }
 
+  public static RaftConfiguration newRaftConfiguration(List<RaftPeer> conf, long index, List<RaftPeer> oldConf) {
+    final RaftConfigurationImpl.Builder b = RaftConfigurationImpl.newBuilder()
+        .setConf(conf)
+        .setLogEntryIndex(index);
+    Optional.ofNullable(oldConf).filter(p -> p.size() > 0).ifPresent(b::setOldConf);
+    return b.build();
+  }
+
   static long effectiveCommitIndex(long leaderCommitIndex, TermIndex followerPrevious, int numAppendEntries) {
     final long p = Optional.ofNullable(followerPrevious).map(TermIndex::getIndex).orElse(RaftLog.LEAST_VALID_LOG_INDEX);
     return Math.min(leaderCommitIndex, p + numAppendEntries);
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 dc13a0f..30c5fa7 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
@@ -23,14 +23,13 @@ import org.apache.ratis.proto.RaftProtos.AppendEntriesReplyProto.AppendResult;
 import org.apache.ratis.protocol.RaftGroupMemberId;
 import org.apache.ratis.protocol.RaftPeer;
 import org.apache.ratis.protocol.RaftPeerId;
-import org.apache.ratis.server.RaftConfiguration;
 import org.apache.ratis.server.protocol.TermIndex;
 import org.apache.ratis.server.raftlog.LogProtoUtils;
-import org.apache.ratis.util.Preconditions;
 import org.apache.ratis.util.ProtoUtils;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Optional;
 
 /** Server proto utilities for internal use. */
 public interface ServerProtoUtils {
@@ -38,13 +37,6 @@ public interface ServerProtoUtils {
     return p == null? null: TermIndex.newTermIndex(p.getTerm(), p.getIndex());
   }
 
-  static TermIndexProto toTermIndexProto(TermIndex ti) {
-    return ti == null? null: TermIndexProto.newBuilder()
-        .setTerm(ti.getTerm())
-        .setIndex(ti.getIndex())
-        .build();
-  }
-
   static TermIndex toTermIndex(LogEntryProto entry) {
     return entry == null ? null :
         TermIndex.newTermIndex(entry.getTerm(), entry.getIndex());
@@ -122,18 +114,6 @@ public interface ServerProtoUtils {
     return ProtoUtils.toString(proto.getServerReply()) + "-t" + proto.getTerm() + "," + proto.getResult() + s;
   }
 
-  static RaftConfigurationImpl toRaftConfiguration(LogEntryProto entry) {
-    Preconditions.assertTrue(entry.hasConfigurationEntry());
-    final RaftConfigurationProto proto = entry.getConfigurationEntry();
-    final RaftConfigurationImpl.Builder b = RaftConfigurationImpl.newBuilder()
-        .setConf(ProtoUtils.toRaftPeers(proto.getPeersList()))
-        .setLogEntryIndex(entry.getIndex());
-    if (proto.getOldPeersCount() > 0) {
-      b.setOldConf(ProtoUtils.toRaftPeers(proto.getOldPeersList()));
-    }
-    return b.build();
-  }
-
   static RaftRpcReplyProto.Builder toRaftRpcReplyProtoBuilder(
       RaftPeerId requestorId, RaftGroupMemberId replyId, boolean success) {
     return ClientProtoUtils.toRaftRpcReplyProtoBuilder(
@@ -160,9 +140,7 @@ public interface ServerProtoUtils {
     final RequestVoteRequestProto.Builder b = RequestVoteRequestProto.newBuilder()
         .setServerRequest(toRaftRpcRequestProtoBuilder(requestorId, replyId))
         .setCandidateTerm(term);
-    if (lastEntry != null) {
-      b.setCandidateLastEntry(toTermIndexProto(lastEntry));
-    }
+    Optional.ofNullable(lastEntry).map(TermIndex::toProto).ifPresent(b::setCandidateLastEntry);
     return b.build();
   }
 
@@ -200,47 +178,6 @@ public interface ServerProtoUtils {
     return builder.build();
   }
 
-  @SuppressWarnings("checkstyle:parameternumber")
-  static InstallSnapshotRequestProto toInstallSnapshotRequestProto(
-      RaftGroupMemberId requestorId, RaftPeerId replyId, String requestId, int requestIndex,
-      long term, TermIndex lastTermIndex, List<FileChunkProto> chunks,
-      long totalSize, boolean done, RaftConfiguration raftConfiguration) {
-    final InstallSnapshotRequestProto.SnapshotChunkProto.Builder snapshotChunkProto =
-        InstallSnapshotRequestProto.SnapshotChunkProto.newBuilder()
-            .setRequestId(requestId)
-            .setRequestIndex(requestIndex)
-            .setTermIndex(toTermIndexProto(lastTermIndex))
-            .addAllFileChunks(chunks)
-            .setTotalSize(totalSize)
-            .setDone(done);
-    // term is not going to used by installSnapshot to update the RaftConfiguration
-    final LogEntryProto confLogEntryProto = LogProtoUtils.toLogEntryProto(raftConfiguration, null,
-        ((RaftConfigurationImpl)raftConfiguration).getLogEntryIndex());
-    return InstallSnapshotRequestProto.newBuilder()
-        .setServerRequest(toRaftRpcRequestProtoBuilder(requestorId, replyId))
-        .setLastRaftConfigurationLogEntryProto(confLogEntryProto)
-        .setLeaderTerm(term)
-        .setSnapshotChunk(snapshotChunkProto)
-        .build();
-  }
-
-  static InstallSnapshotRequestProto toInstallSnapshotRequestProto(
-      RaftGroupMemberId requestorId, RaftPeerId replyId, long leaderTerm,
-      TermIndex firstAvailable, RaftConfiguration raftConfiguration) {
-    final InstallSnapshotRequestProto.NotificationProto.Builder notificationProto =
-        InstallSnapshotRequestProto.NotificationProto.newBuilder()
-            .setFirstAvailableTermIndex(toTermIndexProto(firstAvailable));
-    // term is not going to used by installSnapshot to update the RaftConfiguration
-    final LogEntryProto confLogEntryProto = LogProtoUtils.toLogEntryProto(raftConfiguration, null,
-        ((RaftConfigurationImpl)raftConfiguration).getLogEntryIndex());
-    return InstallSnapshotRequestProto.newBuilder()
-        .setServerRequest(toRaftRpcRequestProtoBuilder(requestorId, replyId))
-        .setLastRaftConfigurationLogEntryProto(confLogEntryProto)
-        .setLeaderTerm(leaderTerm)
-        .setNotification(notificationProto)
-        .build();
-  }
-
   @SuppressWarnings("parameternumber")
   static AppendEntriesReplyProto toAppendEntriesReplyProto(
       RaftPeerId requestorId, RaftGroupMemberId replyId, long term,
@@ -277,9 +214,7 @@ public interface ServerProtoUtils {
       b.addAllEntries(entries);
     }
 
-    if (previous != null) {
-      b.setPreviousLog(toTermIndexProto(previous));
-    }
+    Optional.ofNullable(previous).map(TermIndex::toProto).ifPresent(b::setPreviousLog);
     ProtoUtils.addCommitInfos(commitInfos, b::addCommitInfos);
     return b.build();
   }
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
index 88189d6..396486b 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
@@ -23,6 +23,7 @@ import org.apache.ratis.protocol.exceptions.StateMachineException;
 import org.apache.ratis.server.RaftConfiguration;
 import org.apache.ratis.server.RaftServerConfigKeys;
 import org.apache.ratis.server.protocol.TermIndex;
+import org.apache.ratis.server.raftlog.LogProtoUtils;
 import org.apache.ratis.server.raftlog.RaftLog;
 import org.apache.ratis.server.raftlog.memory.MemoryRaftLog;
 import org.apache.ratis.server.raftlog.segmented.SegmentedRaftLog;
@@ -166,8 +167,8 @@ class ServerState implements Closeable {
     sm.initialize(server.getRaftServer(), gid, storage);
     // get the raft configuration from raft metafile
     RaftConfiguration raftConf = storage.readRaftConfiguration();
-    if (raftConf instanceof RaftConfigurationImpl) {
-      setRaftConf(((RaftConfigurationImpl)raftConf).getLogEntryIndex(), raftConf);
+    if (raftConf != null) {
+      setRaftConf(raftConf.getLogEntryIndex(), raftConf);
     }
   }
 
@@ -360,13 +361,12 @@ class ServerState implements Closeable {
   }
 
   boolean isConfCommitted() {
-    return getLog().getLastCommittedIndex() >=
-        getRaftConf().getLogEntryIndex();
+    return getLog().getLastCommittedIndex() >= getRaftConf().getLogEntryIndex();
   }
 
   void setRaftConf(LogEntryProto entry) {
     if (entry.hasConfigurationEntry()) {
-      setRaftConf(entry.getIndex(), ServerProtoUtils.toRaftConfiguration(entry));
+      setRaftConf(entry.getIndex(), LogProtoUtils.toRaftConfiguration(entry));
     }
   }
 
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/leader/InstallSnapshotRequests.java b/ratis-server/src/main/java/org/apache/ratis/server/leader/InstallSnapshotRequests.java
index 31e32dc..34a3d2a 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/leader/InstallSnapshotRequests.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/leader/InstallSnapshotRequests.java
@@ -19,16 +19,15 @@ package org.apache.ratis.server.leader;
 
 import org.apache.ratis.proto.RaftProtos.FileChunkProto;
 import org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto;
+import org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto.SnapshotChunkProto;
 import org.apache.ratis.protocol.RaftPeerId;
 import org.apache.ratis.server.RaftServer;
-import org.apache.ratis.server.impl.ServerProtoUtils;
 import org.apache.ratis.server.storage.FileChunkReader;
 import org.apache.ratis.server.storage.FileInfo;
 import org.apache.ratis.statemachine.SnapshotInfo;
 import org.apache.ratis.util.JavaUtils;
 
 import java.io.IOException;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
@@ -119,9 +118,9 @@ class InstallSnapshotRequests implements Iterable<InstallSnapshotRequestProto> {
     final long totalSize = snapshot.getFiles().stream().mapToLong(FileInfo::getFileSize).reduce(Long::sum).orElseThrow(
         () -> new IllegalStateException("Failed to compute total size for snapshot " + snapshot));
     synchronized (server) {
-      return ServerProtoUtils.toInstallSnapshotRequestProto(server.getMemberId(), followerId,
-          requestId, requestIndex++, server.getInfo().getCurrentTerm(), snapshot.getTermIndex(),
-          Collections.singletonList(chunk), totalSize, done, server.getRaftConf());
+      final SnapshotChunkProto.Builder b = LeaderProtoUtils.toSnapshotChunkProtoBuilder(
+          requestId, requestIndex++, snapshot.getTermIndex(), chunk, totalSize, done);
+      return LeaderProtoUtils.toInstallSnapshotRequestProto(server, followerId, b);
     }
   }
 
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/leader/LeaderProtoUtils.java b/ratis-server/src/main/java/org/apache/ratis/server/leader/LeaderProtoUtils.java
new file mode 100644
index 0000000..8c3fbdf
--- /dev/null
+++ b/ratis-server/src/main/java/org/apache/ratis/server/leader/LeaderProtoUtils.java
@@ -0,0 +1,73 @@
+/*
+ * 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.leader;
+
+import org.apache.ratis.proto.RaftProtos.FileChunkProto;
+import org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto;
+import org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto.NotificationProto;
+import org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto.SnapshotChunkProto;
+import org.apache.ratis.proto.RaftProtos.LogEntryProto;
+import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.server.RaftConfiguration;
+import org.apache.ratis.server.RaftServer;
+import org.apache.ratis.server.impl.ServerProtoUtils;
+import org.apache.ratis.server.protocol.TermIndex;
+import org.apache.ratis.server.raftlog.LogProtoUtils;
+
+import java.util.Collections;
+
+/** Leader only proto utilities. */
+final class LeaderProtoUtils {
+  private LeaderProtoUtils() {}
+
+  static SnapshotChunkProto.Builder toSnapshotChunkProtoBuilder(String requestId, int requestIndex,
+      TermIndex lastTermIndex, FileChunkProto chunk, long totalSize, boolean done) {
+    return SnapshotChunkProto.newBuilder()
+        .setRequestId(requestId)
+        .setRequestIndex(requestIndex)
+        .setTermIndex(lastTermIndex.toProto())
+        .addAllFileChunks(Collections.singleton(chunk))
+        .setTotalSize(totalSize)
+        .setDone(done);
+  }
+
+  static InstallSnapshotRequestProto toInstallSnapshotRequestProto(
+      RaftServer.Division server, RaftPeerId replyId, SnapshotChunkProto.Builder chunk) {
+    return toInstallSnapshotRequestProtoBuilder(server, replyId)
+        .setSnapshotChunk(chunk)
+        .build();
+  }
+
+  static InstallSnapshotRequestProto toInstallSnapshotRequestProto(
+      RaftServer.Division server, RaftPeerId replyId, TermIndex firstAvailable) {
+    return toInstallSnapshotRequestProtoBuilder(server, replyId)
+        .setNotification(NotificationProto.newBuilder().setFirstAvailableTermIndex(firstAvailable.toProto()))
+        .build();
+  }
+
+  private static InstallSnapshotRequestProto.Builder toInstallSnapshotRequestProtoBuilder(
+      RaftServer.Division server, RaftPeerId replyId) {
+    // term is not going to used by installSnapshot to update the RaftConfiguration
+    final RaftConfiguration conf = server.getRaftConf();
+    final LogEntryProto confLogEntryProto = LogProtoUtils.toLogEntryProto(conf, null, conf.getLogEntryIndex());
+    return InstallSnapshotRequestProto.newBuilder()
+        .setServerRequest(ServerProtoUtils.toRaftRpcRequestProtoBuilder(server.getMemberId(), replyId))
+        .setLeaderTerm(server.getInfo().getCurrentTerm())
+        .setLastRaftConfigurationLogEntryProto(confLogEntryProto);
+  }
+}
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/leader/LogAppenderBase.java b/ratis-server/src/main/java/org/apache/ratis/server/leader/LogAppenderBase.java
index 43a84c0..c433e3d 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/leader/LogAppenderBase.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/leader/LogAppenderBase.java
@@ -23,7 +23,6 @@ import org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto;
 import org.apache.ratis.proto.RaftProtos.LogEntryProto;
 import org.apache.ratis.server.RaftServer;
 import org.apache.ratis.server.RaftServerConfigKeys;
-import org.apache.ratis.server.impl.ServerProtoUtils;
 import org.apache.ratis.server.protocol.TermIndex;
 import org.apache.ratis.server.raftlog.RaftLog;
 import org.apache.ratis.server.raftlog.RaftLog.EntryWithData;
@@ -179,8 +178,7 @@ public abstract class LogAppenderBase implements LogAppender {
   public InstallSnapshotRequestProto newInstallSnapshotNotificationRequest(TermIndex firstAvailableLogTermIndex) {
     Preconditions.assertTrue(firstAvailableLogTermIndex.getIndex() > 0);
     synchronized (server) {
-      return ServerProtoUtils.toInstallSnapshotRequestProto(server.getMemberId(), getFollowerId(),
-          server.getInfo().getCurrentTerm(), firstAvailableLogTermIndex, server.getRaftConf());
+      return LeaderProtoUtils.toInstallSnapshotRequestProto(server, getFollowerId(), firstAvailableLogTermIndex);
     }
   }
 
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/protocol/TermIndex.java b/ratis-server/src/main/java/org/apache/ratis/server/protocol/TermIndex.java
index ab9a030..5f514de 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/protocol/TermIndex.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/protocol/TermIndex.java
@@ -17,6 +17,7 @@
  */
 package org.apache.ratis.server.protocol;
 
+import org.apache.ratis.proto.RaftProtos.TermIndexProto;
 import org.apache.ratis.server.impl.ServerImplUtils;
 
 import java.util.function.LongFunction;
@@ -31,6 +32,14 @@ public interface TermIndex extends Comparable<TermIndex> {
   /** @return the index. */
   long getIndex();
 
+  /** @return the {@link TermIndexProto}. */
+  default TermIndexProto toProto() {
+    return TermIndexProto.newBuilder()
+        .setTerm(getTerm())
+        .setIndex(getIndex())
+        .build();
+  }
+
   /** A term number is valid iff it is greater than zero. */
   static boolean isValidTerm(int term) {
     return term > 0;
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/raftlog/LogProtoUtils.java b/ratis-server/src/main/java/org/apache/ratis/server/raftlog/LogProtoUtils.java
index ff7a027..cf426d4 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/raftlog/LogProtoUtils.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/raftlog/LogProtoUtils.java
@@ -20,13 +20,16 @@ package org.apache.ratis.server.raftlog;
 import org.apache.ratis.proto.RaftProtos.*;
 import org.apache.ratis.protocol.ClientId;
 import org.apache.ratis.protocol.RaftClientRequest;
+import org.apache.ratis.protocol.RaftPeer;
 import org.apache.ratis.server.RaftConfiguration;
+import org.apache.ratis.server.impl.ServerImplUtils;
 import org.apache.ratis.server.protocol.TermIndex;
 import org.apache.ratis.thirdparty.com.google.protobuf.ByteString;
 import org.apache.ratis.util.Preconditions;
 import org.apache.ratis.util.ProtoUtils;
 
 import java.util.Arrays;
+import java.util.List;
 import java.util.Optional;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -191,4 +194,13 @@ public final class LogProtoUtils {
         .ifPresent(b::setStateMachineEntry);
     return b.build();
   }
+
+  public static RaftConfiguration toRaftConfiguration(LogEntryProto entry) {
+    Preconditions.assertTrue(entry.hasConfigurationEntry());
+    final RaftConfigurationProto proto = entry.getConfigurationEntry();
+    final List<RaftPeer> conf = ProtoUtils.toRaftPeers(proto.getPeersList());
+    final List<RaftPeer> oldConf = proto.getOldPeersCount() == 0? null
+        : ProtoUtils.toRaftPeers(proto.getOldPeersList());
+    return ServerImplUtils.newRaftConfiguration(conf, entry.getIndex(), oldConf);
+  }
 }
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorage.java b/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorage.java
index 785d725..ea2d8d9 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorage.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorage.java
@@ -20,7 +20,7 @@ package org.apache.ratis.server.storage;
 import org.apache.ratis.proto.RaftProtos.LogEntryProto;
 import org.apache.ratis.server.RaftServerConfigKeys.Log.CorruptionPolicy;
 import org.apache.ratis.server.RaftConfiguration;
-import org.apache.ratis.server.impl.ServerProtoUtils;
+import org.apache.ratis.server.raftlog.LogProtoUtils;
 import org.apache.ratis.server.storage.RaftStorageDirectory.StorageState;
 import org.apache.ratis.util.JavaUtils;
 import org.apache.ratis.util.Preconditions;
@@ -147,7 +147,7 @@ public class RaftStorage implements Closeable {
     File confFile = storageDir.getMetaConfFile();
     try (FileInputStream fio = new FileInputStream(confFile)) {
       LogEntryProto confProto = LogEntryProto.newBuilder().mergeFrom(fio).build();
-      return ServerProtoUtils.toRaftConfiguration(confProto);
+      return LogProtoUtils.toRaftConfiguration(confProto);
     } catch (Exception e) {
       LOG.error("Failed reading configuration from file:" + confFile, e);
       return null;