This is an automated email from the ASF dual-hosted git repository.
rexxiong pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/celeborn.git
The following commit(s) were added to refs/heads/main by this push:
new 216152d03 [CELEBORN-1632] Support to apply ratis local raft_meta_conf
command with RESTful api
216152d03 is described below
commit 216152d038e854f59cc6dd3201210ab8700035f9
Author: Wang, Fei <[email protected]>
AuthorDate: Thu Oct 24 16:09:18 2024 +0800
[CELEBORN-1632] Support to apply ratis local raft_meta_conf command with
RESTful api
### What changes were proposed in this pull request?
Sub-task of CELEBORN-1628.
Support to apply ratis local raft_meta_conf with RESTful api.
See
https://celeborn.apache.org/docs/latest/celeborn_ratis_shell/#local-raftmetaconf
```
$ celeborn-ratis sh local raftMetaConf -peers
<[P0_ID|]P0_HOST:P0_PORT,[P1_ID|]P1_HOST:P1_PORT,[P2_ID|]P2_HOST:P2_PORT> -path
<PARENT_PATH_OF_RAFT_META_CONF>
```
The implementation is same with
https://github.com/apache/ratis/blob/e96ed1a33840385446f4e647864a169467da5ab7/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/local/RaftMetaConfCommand.java#L122-L133
### Why are the changes needed?
We have implemented the RESTful implementation for all the others
ratis-shell command.
<img width="1219" alt="image"
src="https://github.com/user-attachments/assets/4367ddbd-3c55-449a-a1bc-75d6c18e8918">
| Ratis Shell | RESTful api |
|----------------------|---------------------------------|
| election transfer | `/ratis/election/transfer` |
| election stepDown | `/ratis/election/step_down` |
| election pause | `/ratis/election/pause` |
| election resume | `/ratis/election/resume` |
| group info | `/masters` |
| peer add | `/ratis/peer/add` |
| peer remove | `/ratis/peer/remove` |
| peer setPriority | `/ratis/peer/set_priority` |
| snapshot create | `/ratis/snapshot/create` |
And the local raftMetaConf command is the last one.
I closed the ticket CELEBORN-1632 before, I thought it is a local command
and wonder whether it is necessary to implement it with RESTful api.
But we have implemented all the others, so I decide to implement it as well.
### Does this PR introduce _any_ user-facing change?
A new API.
The implementation is same with
https://github.com/apache/ratis/blob/e96ed1a33840385446f4e647864a169467da5ab7/ratis-shell/src/main/java/org/apache/ratis/shell/cli/sh/local/RaftMetaConfCommand.java#L122-L133
### How was this patch tested?


<img width="960" alt="image"
src="https://github.com/user-attachments/assets/b302a680-baea-4709-b77f-a2b1946b8dff">
<img width="1471" alt="image"
src="https://github.com/user-attachments/assets/4bf090ba-c6f4-4f49-aa57-8dd2c897ff30">
<img width="871" alt="image"
src="https://github.com/user-attachments/assets/9959072c-5e96-48f5-911e-546c05a0c443">
Closes #2829 from turboFei/local_raft_conf.
Authored-by: Wang, Fei <[email protected]>
Signed-off-by: Shuang <[email protected]>
---
.../deploy/master/http/api/v1/RatisResource.scala | 90 +++++++++++++-
.../apache/celeborn/rest/v1/master/RatisApi.java | 138 +++++++++++++++++++++
.../v1/model/RatisLocalRaftMetaConfRequest.java | 120 ++++++++++++++++++
.../src/main/openapi3/master_rest_v1.yaml | 44 +++++++
4 files changed, 388 insertions(+), 4 deletions(-)
diff --git
a/master/src/main/scala/org/apache/celeborn/service/deploy/master/http/api/v1/RatisResource.scala
b/master/src/main/scala/org/apache/celeborn/service/deploy/master/http/api/v1/RatisResource.scala
index 44e4ab1ff..04e94c4ba 100644
---
a/master/src/main/scala/org/apache/celeborn/service/deploy/master/http/api/v1/RatisResource.scala
+++
b/master/src/main/scala/org/apache/celeborn/service/deploy/master/http/api/v1/RatisResource.scala
@@ -17,27 +17,32 @@
package org.apache.celeborn.service.deploy.master.http.api.v1
-import javax.ws.rs.{BadRequestException, Consumes, Path, POST, Produces}
-import javax.ws.rs.core.MediaType
+import java.nio.charset.StandardCharsets
+import java.nio.file.Paths
+import javax.ws.rs.{BadRequestException, Consumes, GET, NotFoundException,
Path, POST, Produces}
+import javax.ws.rs.core.{MediaType, Response}
import scala.collection.JavaConverters._
import io.swagger.v3.oas.annotations.media.{Content, Schema}
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.tags.Tag
+import org.apache.commons.io.IOUtils
+import org.apache.ratis.proto.RaftProtos.{LogEntryProto,
RaftConfigurationProto, RaftPeerProto, RaftPeerRole}
import org.apache.ratis.protocol.{LeaderElectionManagementRequest,
RaftClientReply, RaftPeer, SetConfigurationRequest, SnapshotManagementRequest,
TransferLeadershipRequest}
import org.apache.ratis.rpc.CallId
+import org.apache.ratis.server.storage.RaftStorageDirectory
+import org.apache.ratis.thirdparty.com.google.protobuf.ByteString
import org.apache.celeborn.common.CelebornConf
import org.apache.celeborn.common.internal.Logging
-import org.apache.celeborn.rest.v1.model.{HandleResponse,
RatisElectionTransferRequest, RatisPeerAddRequest, RatisPeerRemoveRequest,
RatisPeerSetPriorityRequest}
+import org.apache.celeborn.rest.v1.model.{HandleResponse,
RatisElectionTransferRequest, RatisLocalRaftMetaConfRequest,
RatisPeerAddRequest, RatisPeerRemoveRequest, RatisPeerSetPriorityRequest}
import org.apache.celeborn.server.common.http.api.ApiRequestContext
import org.apache.celeborn.service.deploy.master.Master
import
org.apache.celeborn.service.deploy.master.clustermeta.ha.{HAMasterMetaManager,
HARaftServer}
import
org.apache.celeborn.service.deploy.master.http.api.MasterHttpResourceUtils.{ensureMasterHAEnabled,
ensureMasterIsLeader}
@Tag(name = "Ratis")
-@Produces(Array(MediaType.APPLICATION_JSON))
@Consumes(Array(MediaType.APPLICATION_JSON))
class RatisResource extends ApiRequestContext with Logging {
private def master = httpService.asInstanceOf[Master]
@@ -51,6 +56,7 @@ class RatisResource extends ApiRequestContext with Logging {
description = "Transfer the group leader to the specified server.")
@POST
@Path("/election/transfer")
+ @Produces(Array(MediaType.APPLICATION_JSON))
def electionTransfer(request: RatisElectionTransferRequest): HandleResponse =
ensureMasterIsLeader(master) {
transferLeadership(request.getPeerAddress)
@@ -64,6 +70,7 @@ class RatisResource extends ApiRequestContext with Logging {
description = "Make the group leader step down its leadership.")
@POST
@Path("/election/step_down")
+ @Produces(Array(MediaType.APPLICATION_JSON))
def electionStepDown(): HandleResponse = ensureMasterIsLeader(master) {
transferLeadership(null)
}
@@ -77,6 +84,7 @@ class RatisResource extends ApiRequestContext with Logging {
" Then, the current server would not start a leader election.")
@POST
@Path("/election/pause")
+ @Produces(Array(MediaType.APPLICATION_JSON))
def electionPause(): HandleResponse = ensureMasterHAEnabled(master) {
applyElectionOp(new LeaderElectionManagementRequest.Pause)
}
@@ -89,6 +97,7 @@ class RatisResource extends ApiRequestContext with Logging {
description = "Resume leader election at the current server.")
@POST
@Path("/election/resume")
+ @Produces(Array(MediaType.APPLICATION_JSON))
def electionResume(): HandleResponse = ensureMasterHAEnabled(master) {
applyElectionOp(new LeaderElectionManagementRequest.Resume)
}
@@ -101,6 +110,7 @@ class RatisResource extends ApiRequestContext with Logging {
description = "Add new peers to the raft group.")
@POST
@Path("/peer/add")
+ @Produces(Array(MediaType.APPLICATION_JSON))
def peerAdd(request: RatisPeerAddRequest): HandleResponse =
ensureLeaderElectionMemberMajorityAddEnabled(master) {
if (request.getPeers.isEmpty) {
@@ -146,6 +156,7 @@ class RatisResource extends ApiRequestContext with Logging {
description = "Remove peers from the raft group.")
@POST
@Path("/peer/remove")
+ @Produces(Array(MediaType.APPLICATION_JSON))
def peerRemove(request: RatisPeerRemoveRequest): HandleResponse =
ensureLeaderElectionMemberMajorityAddEnabled(master) {
if (request.getPeers.isEmpty) {
@@ -183,6 +194,7 @@ class RatisResource extends ApiRequestContext with Logging {
description = "Set the priority of the peers in the raft group.")
@POST
@Path("/peer/set_priority")
+ @Produces(Array(MediaType.APPLICATION_JSON))
def peerSetPriority(request: RatisPeerSetPriorityRequest): HandleResponse =
ensureLeaderElectionMemberMajorityAddEnabled(master) {
if (request.getAddressPriorities.isEmpty) {
@@ -218,6 +230,7 @@ class RatisResource extends ApiRequestContext with Logging {
description = "Trigger the current server to take snapshot.")
@POST
@Path("/snapshot/create")
+ @Produces(Array(MediaType.APPLICATION_JSON))
def createSnapshot(): HandleResponse = ensureMasterHAEnabled(master) {
val request = SnapshotManagementRequest.newCreate(
ratisServer.getClientId,
@@ -235,6 +248,75 @@ class RatisResource extends ApiRequestContext with Logging
{
}
}
+ @ApiResponse(
+ responseCode = "200",
+ content = Array(new Content(
+ mediaType = MediaType.APPLICATION_OCTET_STREAM,
+ schema = new Schema(implementation = classOf[Response]))),
+ description = "Get the raft-meta.conf file of the current server.")
+ @GET
+ @Path("/local/raft_meta_conf")
+ @Produces(Array(MediaType.APPLICATION_OCTET_STREAM))
+ def getLocalRaftMetaConf(): Response = ensureMasterHAEnabled(master) {
+ val raftMetaConfFile = Paths.get(
+ master.conf.haMasterRatisStorageDir,
+ ratisServer.getGroupId.getUuid.toString,
+ RaftStorageDirectory.CURRENT_DIR_NAME,
+ "raft-meta.conf")
+
+ if (!raftMetaConfFile.toFile.exists()) {
+ throw new NotFoundException(s"File $raftMetaConfFile not found.")
+ }
+
+ Response.ok(IOUtils.toByteArray(raftMetaConfFile.toUri))
+ .header("Content-Disposition", "attachment; filename=\"raft-meta.conf\"")
+ .build()
+ }
+
+ @ApiResponse(
+ responseCode = "200",
+ content = Array(new Content(
+ mediaType = MediaType.APPLICATION_OCTET_STREAM,
+ schema = new Schema(implementation = classOf[Response]))),
+ description = "Generate a new-raft-meta.conf file based on original
raft-meta.conf" +
+ " and new peers, which is used to move a raft node to a new node.")
+ @POST
+ @Path("/local/raft_meta_conf")
+ @Produces(Array(MediaType.APPLICATION_OCTET_STREAM))
+ def generateNewRaftMetaConf(request: RatisLocalRaftMetaConfRequest):
Response =
+ ensureMasterHAEnabled(master) {
+ if (request.getPeers.isEmpty) {
+ throw new BadRequestException("No peers specified.")
+ }
+
+ val groupInfo = ratisServer.getGroupInfo
+
+ val existingPeers = getRaftPeers().map(_.getRaftPeerProto)
+ val newPeers = request.getPeers.asScala.map { peer =>
+ RaftPeerProto.newBuilder()
+
.setId(ByteString.copyFrom(peer.getId.getBytes(StandardCharsets.UTF_8)))
+ .setAddress(peer.getAddress)
+ .setStartupRole(RaftPeerRole.FOLLOWER)
+ .build()
+ }
+
+ val remainingPeers =
+ existingPeers.filterNot(p => newPeers.exists(_.getId.toStringUtf8 ==
p.getId.toStringUtf8))
+ val allPeers = remainingPeers ++ newPeers
+
+ val newIndex = groupInfo.getLogIndex + 1
+ logInfo(s"Generating new-raft-meta.conf with remaining peers:" +
+ s" $remainingPeers and new peers: $newPeers, index: $newIndex.")
+
+ val generateLogEntryProto = LogEntryProto.newBuilder()
+ .setConfigurationEntry(RaftConfigurationProto.newBuilder()
+ .addAllPeers(allPeers.asJava).build())
+ .setIndex(newIndex).build()
+ Response.ok(generateLogEntryProto.toByteArray)
+ .header("Content-Disposition", "attachment;
filename=\"new-raft-meta.conf\"")
+ .build()
+ }
+
private def transferLeadership(peerAddress: String): HandleResponse = {
val newLeaderId = Option(peerAddress).map { addr =>
getRaftPeers().find(_.getAddress == addr).map(_.getId).getOrElse(
diff --git
a/openapi/openapi-client/src/main/java/org/apache/celeborn/rest/v1/master/RatisApi.java
b/openapi/openapi-client/src/main/java/org/apache/celeborn/rest/v1/master/RatisApi.java
index 60640c615..8c42ca7f7 100644
---
a/openapi/openapi-client/src/main/java/org/apache/celeborn/rest/v1/master/RatisApi.java
+++
b/openapi/openapi-client/src/main/java/org/apache/celeborn/rest/v1/master/RatisApi.java
@@ -25,8 +25,10 @@ import org.apache.celeborn.rest.v1.master.invoker.BaseApi;
import org.apache.celeborn.rest.v1.master.invoker.Configuration;
import org.apache.celeborn.rest.v1.master.invoker.Pair;
+import java.io.File;
import org.apache.celeborn.rest.v1.model.HandleResponse;
import org.apache.celeborn.rest.v1.model.RatisElectionTransferRequest;
+import org.apache.celeborn.rest.v1.model.RatisLocalRaftMetaConfRequest;
import org.apache.celeborn.rest.v1.model.RatisPeerAddRequest;
import org.apache.celeborn.rest.v1.model.RatisPeerRemoveRequest;
import org.apache.celeborn.rest.v1.model.RatisPeerSetPriorityRequest;
@@ -186,6 +188,142 @@ public class RatisApi extends BaseApi {
);
}
+ /**
+ *
+ * Generate a new-raft-meta.conf file based on original raft-meta.conf and
new peers, which is used to move a raft node to a new node.
+ * @param ratisLocalRaftMetaConfRequest (optional)
+ * @return File
+ * @throws ApiException if fails to make API call
+ */
+ public File generateNewRaftMetaConf(RatisLocalRaftMetaConfRequest
ratisLocalRaftMetaConfRequest) throws ApiException {
+ return this.generateNewRaftMetaConf(ratisLocalRaftMetaConfRequest,
Collections.emptyMap());
+ }
+
+
+ /**
+ *
+ * Generate a new-raft-meta.conf file based on original raft-meta.conf and
new peers, which is used to move a raft node to a new node.
+ * @param ratisLocalRaftMetaConfRequest (optional)
+ * @param additionalHeaders additionalHeaders for this call
+ * @return File
+ * @throws ApiException if fails to make API call
+ */
+ public File generateNewRaftMetaConf(RatisLocalRaftMetaConfRequest
ratisLocalRaftMetaConfRequest, Map<String, String> additionalHeaders) throws
ApiException {
+ Object localVarPostBody = ratisLocalRaftMetaConfRequest;
+
+ // create path and map variables
+ String localVarPath = "/api/v1/ratis/local/raft_meta_conf";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List<Pair> localVarQueryParams = new ArrayList<Pair>();
+ List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
+ Map<String, String> localVarHeaderParams = new HashMap<String, String>();
+ Map<String, String> localVarCookieParams = new HashMap<String, String>();
+ Map<String, Object> localVarFormParams = new HashMap<String, Object>();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "application/octet-stream"
+ };
+ final String localVarAccept =
apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+ "application/json"
+ };
+ final String localVarContentType =
apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { "basic" };
+
+ TypeReference<File> localVarReturnType = new TypeReference<File>() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "POST",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
+ /**
+ *
+ * Get the raft-meta.conf file of the current server.
+ * @return File
+ * @throws ApiException if fails to make API call
+ */
+ public File getLocalRaftMetaConf() throws ApiException {
+ return this.getLocalRaftMetaConf(Collections.emptyMap());
+ }
+
+
+ /**
+ *
+ * Get the raft-meta.conf file of the current server.
+ * @param additionalHeaders additionalHeaders for this call
+ * @return File
+ * @throws ApiException if fails to make API call
+ */
+ public File getLocalRaftMetaConf(Map<String, String> additionalHeaders)
throws ApiException {
+ Object localVarPostBody = null;
+
+ // create path and map variables
+ String localVarPath = "/api/v1/ratis/local/raft_meta_conf";
+
+ StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ String localVarQueryParameterBaseName;
+ List<Pair> localVarQueryParams = new ArrayList<Pair>();
+ List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
+ Map<String, String> localVarHeaderParams = new HashMap<String, String>();
+ Map<String, String> localVarCookieParams = new HashMap<String, String>();
+ Map<String, Object> localVarFormParams = new HashMap<String, Object>();
+
+
+ localVarHeaderParams.putAll(additionalHeaders);
+
+
+
+ final String[] localVarAccepts = {
+ "application/octet-stream"
+ };
+ final String localVarAccept =
apiClient.selectHeaderAccept(localVarAccepts);
+
+ final String[] localVarContentTypes = {
+
+ };
+ final String localVarContentType =
apiClient.selectHeaderContentType(localVarContentTypes);
+
+ String[] localVarAuthNames = new String[] { "basic" };
+
+ TypeReference<File> localVarReturnType = new TypeReference<File>() {};
+ return apiClient.invokeAPI(
+ localVarPath,
+ "GET",
+ localVarQueryParams,
+ localVarCollectionQueryParams,
+ localVarQueryStringJoiner.toString(),
+ localVarPostBody,
+ localVarHeaderParams,
+ localVarCookieParams,
+ localVarFormParams,
+ localVarAccept,
+ localVarContentType,
+ localVarAuthNames,
+ localVarReturnType
+ );
+ }
+
/**
*
* Pause leader election at the current server. Then, the current server
would not start a leader election.
diff --git
a/openapi/openapi-client/src/main/java/org/apache/celeborn/rest/v1/model/RatisLocalRaftMetaConfRequest.java
b/openapi/openapi-client/src/main/java/org/apache/celeborn/rest/v1/model/RatisLocalRaftMetaConfRequest.java
new file mode 100644
index 000000000..d78c760ff
--- /dev/null
+++
b/openapi/openapi-client/src/main/java/org/apache/celeborn/rest/v1/model/RatisLocalRaftMetaConfRequest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.celeborn.rest.v1.model;
+
+import java.util.Objects;
+import java.util.Arrays;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.annotation.JsonValue;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.celeborn.rest.v1.model.RatisPeer;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+
+/**
+ * RatisLocalRaftMetaConfRequest
+ */
+@JsonPropertyOrder({
+ RatisLocalRaftMetaConfRequest.JSON_PROPERTY_PEERS
+})
[email protected](value =
"org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator
version: 7.8.0")
+public class RatisLocalRaftMetaConfRequest {
+ public static final String JSON_PROPERTY_PEERS = "peers";
+ private List<RatisPeer> peers = new ArrayList<>();
+
+ public RatisLocalRaftMetaConfRequest() {
+ }
+
+ public RatisLocalRaftMetaConfRequest peers(List<RatisPeer> peers) {
+
+ this.peers = peers;
+ return this;
+ }
+
+ public RatisLocalRaftMetaConfRequest addPeersItem(RatisPeer peersItem) {
+ if (this.peers == null) {
+ this.peers = new ArrayList<>();
+ }
+ this.peers.add(peersItem);
+ return this;
+ }
+
+ /**
+ * The new peers to generate a new-raft-meta.conf file with existing peers.
+ * @return peers
+ */
+ @javax.annotation.Nonnull
+ @JsonProperty(JSON_PROPERTY_PEERS)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+
+ public List<RatisPeer> getPeers() {
+ return peers;
+ }
+
+
+ @JsonProperty(JSON_PROPERTY_PEERS)
+ @JsonInclude(value = JsonInclude.Include.ALWAYS)
+ public void setPeers(List<RatisPeer> peers) {
+ this.peers = peers;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ RatisLocalRaftMetaConfRequest ratisLocalRaftMetaConfRequest =
(RatisLocalRaftMetaConfRequest) o;
+ return Objects.equals(this.peers, ratisLocalRaftMetaConfRequest.peers);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(peers);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class RatisLocalRaftMetaConfRequest {\n");
+ sb.append(" peers: ").append(toIndentedString(peers)).append("\n");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+
+}
+
diff --git a/openapi/openapi-client/src/main/openapi3/master_rest_v1.yaml
b/openapi/openapi-client/src/main/openapi3/master_rest_v1.yaml
index 60528efcb..a4b2802ce 100644
--- a/openapi/openapi-client/src/main/openapi3/master_rest_v1.yaml
+++ b/openapi/openapi-client/src/main/openapi3/master_rest_v1.yaml
@@ -448,6 +448,39 @@ paths:
schema:
$ref: '#/components/schemas/HandleResponse'
+ /api/v1/ratis/local/raft_meta_conf:
+ get:
+ tags:
+ - Ratis
+ operationId: getLocalRaftMetaConf
+ description: Get the raft-meta.conf file of the current server.
+ responses:
+ "200":
+ description: The request was successful.
+ content:
+ application/octet-stream:
+ schema:
+ type: string
+ format: binary
+ post:
+ tags:
+ - Ratis
+ operationId: generateNewRaftMetaConf
+ description: Generate a new-raft-meta.conf file based on original
raft-meta.conf and new peers, which is used to move a raft node to a new node.
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/RatisLocalRaftMetaConfRequest'
+ responses:
+ "200":
+ description: The request was successful.
+ content:
+ application/octet-stream:
+ schema:
+ type: string
+ format: binary
+
components:
schemas:
ConfigData:
@@ -1027,6 +1060,17 @@ components:
additionalProperties:
type: integer
+ RatisLocalRaftMetaConfRequest:
+ type: object
+ properties:
+ peers:
+ type: array
+ description: The new peers to generate a new-raft-meta.conf file
with existing peers.
+ items:
+ $ref: '#/components/schemas/RatisPeer'
+ required:
+ - peers
+
HandleResponse:
type: object
properties: