Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions raft/src/main/java/org/apache/kafka/raft/KafkaRaftClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2207,6 +2207,40 @@ private boolean handleFetchSnapshotResponse(
return true;
}

/**
* Handle a AddVoter request. This API is used to dynamically add a new voter
* to the quorum. The request must be sent to the current quorum leader, and will
* only succeed if the leader has committed its current epoch and HWM.
*
* The request may include an optional clusterId. If provided, it must match this
* cluster's id, otherwise the request will be rejected.
*
* The new voter is validated against the current voter set. If the voter is already
* present, or if the request does not include a valid voter id or endpoint, the
* request will fail immediately.
*
* When valid, the leader tentatively adds the new voter and sends it an ApiVersions
* request to verify protocol compatibility. This is an asynchronous step:
* the ApiVersionsResponse will later be handled in {@link #handleApiVersionsResponse},
* where the leader decides whether to keep the voter (if compatible) or remove it
* again (if incompatible or unreachable).
*
* This API may return the following errors:
*
* - {@link Errors#INCONSISTENT_CLUSTER_ID} if the cluster id is provided but does
* not match this cluster's id
* - {@link Errors#FENCED_LEADER_EPOCH} if the epoch is smaller than this node's epoch
* - {@link Errors#UNKNOWN_LEADER_EPOCH} if the epoch is larger than this node's epoch
* - {@link Errors#NOT_LEADER_OR_FOLLOWER} if the request was sent to a broker that
* is not the current quorum leader
* - {@link Errors#BROKER_NOT_AVAILABLE} if this node is currently shutting down
* - {@link Errors#REQUEST_TIMED_OUT} if the leader is still processing a previous
* voter change, or if the high watermark has not yet advanced
* - {@link Errors#DUPLICATE_VOTER} if the requested voter id already exists in the
* current voter set
* - {@link Errors#UNSUPPORTED_VERSION} if the cluster does not support kraft.version 1
* - {@link Errors#INVALID_REQUEST} if the request does not include a valid voter or endpoint
*/
private CompletableFuture<AddRaftVoterResponseData> handleAddVoterRequest(
RaftRequest.Inbound requestMetadata,
long currentTimeMs
Expand Down Expand Up @@ -2310,6 +2344,42 @@ private boolean handleAddVoterResponse(
}
}

/**
* Handle a RemoveVoter request. This API is used to dynamically remove an existing
* voter from the quorum. The request must be sent to the current quorum leader,
* and will only succeed if the leader has committed its current epoch and HWM.
*
* The request may include an optional clusterId. If provided, it must match this
* cluster's id, otherwise the request will be rejected.
*
* The voter is validated against the current voter set. If the voter does not exist,
* or if the request does not include a valid voter id or endpoint, the request will
* fail immediately.
*
* This API performs several checks before committing the removal:
* - Ensures the leader is not currently processing another voter change request.
* - Checks that the high watermark has been established and the current epoch is committed.
* - Validates that the cluster supports the required kraft.version for reconfiguration.
* - Confirms that there are no uncommitted voter changes pending in the log.
*
* When all checks pass, the voter is removed from the voter set and a new VotersRecord
* is appended to the log.
*
* This API may return the following errors:
*
* - {@link Errors#INCONSISTENT_CLUSTER_ID} if the cluster id is provided but does
* not match this cluster's id
* - {@link Errors#FENCED_LEADER_EPOCH} if the epoch is smaller than this node's epoch
* - {@link Errors#UNKNOWN_LEADER_EPOCH} if the epoch is larger than this node's epoch
* - {@link Errors#NOT_LEADER_OR_FOLLOWER} if the request was sent to a broker that
* is not the current quorum leader
* - {@link Errors#BROKER_NOT_AVAILABLE} if this node is currently shutting down
* - {@link Errors#REQUEST_TIMED_OUT} if the leader is still processing a previous
* voter change, or if the high watermark has not yet advanced
* - {@link Errors#VOTER_NOT_FOUND} if the specified voter does not exist in the current set
* - {@link Errors#UNSUPPORTED_VERSION} if the cluster does not support the required kraft.version
* - {@link Errors#INVALID_REQUEST} if the request does not include a valid voter or endpoint
*/
private CompletableFuture<RemoveRaftVoterResponseData> handleRemoveVoterRequest(
RaftRequest.Inbound requestMetadata,
long currentTimeMs
Expand Down Expand Up @@ -2372,6 +2442,27 @@ private boolean handleRemoveVoterResponse(
}
}

/**
* Handle an UpdateVoter request. This API is used to update the metadata (endpoints
* and supported KRaft version range) of an existing voter in the quorum. The request
* should be sent to the current quorum leader, and will only succeed if the leader
* has committed its current epoch and HWM.
*
* This API may return the following errors:
*
* - {@link Errors#INCONSISTENT_CLUSTER_ID} if the cluster id is provided but does
* not match this cluster's id
* - {@link Errors#FENCED_LEADER_EPOCH} if the epoch is smaller than this node's epoch
* - {@link Errors#UNKNOWN_LEADER_EPOCH} if the epoch is larger than this node's epoch
* - {@link Errors#NOT_LEADER_OR_FOLLOWER} if the request was sent to a broker that
* is not the current quorum leader
* - {@link Errors#BROKER_NOT_AVAILABLE} if this node is currently shutting down
* - {@link Errors#REQUEST_TIMED_OUT} if the leader is still processing a previous
* voter change, or if the high watermark has not yet advanced
* - {@link Errors#INVALID_REQUEST} if the request does not include a valid voter id,
* directory id, endpoint, or KRaft version
* - {@link Errors#VOTER_NOT_FOUND} if the specified voter does not exist in the current set
*/
private CompletableFuture<UpdateRaftVoterResponseData> handleUpdateVoterRequest(
RaftRequest.Inbound requestMetadata,
long currentTimeMs
Expand Down