@@ -2058,16 +2058,18 @@ void generateLeaderAndIsrUpdates(String context,
2058
2058
ControllerResult <AlterPartitionReassignmentsResponseData >
2059
2059
alterPartitionReassignments (AlterPartitionReassignmentsRequestData request ) {
2060
2060
List <ApiMessageAndVersion > records = BoundedList .newArrayBacked (MAX_RECORDS_PER_USER_OP );
2061
+ boolean allowRFChange = request .allowReplicationFactorChange ();
2061
2062
AlterPartitionReassignmentsResponseData result =
2062
- new AlterPartitionReassignmentsResponseData ().setErrorMessage (null );
2063
+ new AlterPartitionReassignmentsResponseData ().setErrorMessage (null )
2064
+ .setAllowReplicationFactorChange (allowRFChange );
2063
2065
int successfulAlterations = 0 , totalAlterations = 0 ;
2064
2066
for (ReassignableTopic topic : request .topics ()) {
2065
2067
ReassignableTopicResponse topicResponse = new ReassignableTopicResponse ().
2066
2068
setName (topic .name ());
2067
2069
for (ReassignablePartition partition : topic .partitions ()) {
2068
2070
ApiError error = ApiError .NONE ;
2069
2071
try {
2070
- alterPartitionReassignment (topic .name (), partition , records );
2072
+ alterPartitionReassignment (topic .name (), partition , records , allowRFChange );
2071
2073
successfulAlterations ++;
2072
2074
} catch (Throwable e ) {
2073
2075
log .info ("Unable to alter partition reassignment for " +
@@ -2090,7 +2092,8 @@ void generateLeaderAndIsrUpdates(String context,
2090
2092
2091
2093
void alterPartitionReassignment (String topicName ,
2092
2094
ReassignablePartition target ,
2093
- List <ApiMessageAndVersion > records ) {
2095
+ List <ApiMessageAndVersion > records ,
2096
+ boolean allowRFChange ) {
2094
2097
Uuid topicId = topicsByName .get (topicName );
2095
2098
if (topicId == null ) {
2096
2099
throw new UnknownTopicOrPartitionException ("Unable to find a topic " +
@@ -2111,7 +2114,7 @@ void alterPartitionReassignment(String topicName,
2111
2114
if (target .replicas () == null ) {
2112
2115
record = cancelPartitionReassignment (topicName , tp , part );
2113
2116
} else {
2114
- record = changePartitionReassignment (tp , part , target );
2117
+ record = changePartitionReassignment (tp , part , target , allowRFChange );
2115
2118
}
2116
2119
record .ifPresent (records ::add );
2117
2120
}
@@ -2175,18 +2178,23 @@ Optional<ApiMessageAndVersion> cancelPartitionReassignment(String topicName,
2175
2178
* @param tp The topic id and partition id.
2176
2179
* @param part The existing partition info.
2177
2180
* @param target The target partition info.
2181
+ * @param allowRFChange Validate if partition replication factor can change. KIP-860
2178
2182
*
2179
2183
* @return The ChangePartitionRecord for the new partition assignment,
2180
2184
* or empty if no change is needed.
2181
2185
*/
2182
2186
Optional <ApiMessageAndVersion > changePartitionReassignment (TopicIdPartition tp ,
2183
2187
PartitionRegistration part ,
2184
- ReassignablePartition target ) {
2188
+ ReassignablePartition target ,
2189
+ boolean allowRFChange ) {
2185
2190
// Check that the requested partition assignment is valid.
2186
2191
PartitionAssignment currentAssignment = new PartitionAssignment (Replicas .toList (part .replicas ), part ::directory );
2187
2192
PartitionAssignment targetAssignment = new PartitionAssignment (target .replicas (), clusterDescriber );
2188
2193
2189
2194
validateManualPartitionAssignment (targetAssignment , OptionalInt .empty ());
2195
+ if (!allowRFChange ) {
2196
+ validatePartitionReplicationFactorUnchanged (part , target );
2197
+ }
2190
2198
2191
2199
List <Integer > currentReplicas = Replicas .toList (part .replicas );
2192
2200
PartitionReassignmentReplicas reassignment =
@@ -2406,6 +2414,30 @@ private void updatePartitionInfo(
2406
2414
newPartInfo .elr );
2407
2415
}
2408
2416
2417
+ private void validatePartitionReplicationFactorUnchanged (PartitionRegistration part ,
2418
+ ReassignablePartition target ) {
2419
+ int currentReassignmentSetSize ;
2420
+ if (isReassignmentInProgress (part )) {
2421
+ Set <Integer > set = new HashSet <>();
2422
+ for (int r : part .replicas ) {
2423
+ set .add (r );
2424
+ }
2425
+ for (int r : part .addingReplicas ) {
2426
+ set .add (r );
2427
+ }
2428
+ for (int r : part .removingReplicas ) {
2429
+ set .remove (r );
2430
+ }
2431
+ currentReassignmentSetSize = set .size ();
2432
+ } else {
2433
+ currentReassignmentSetSize = part .replicas .length ;
2434
+ }
2435
+ if (currentReassignmentSetSize != target .replicas ().size ()) {
2436
+ throw new InvalidReplicationFactorException ("The replication factor is changed from " +
2437
+ currentReassignmentSetSize + " to " + target .replicas ().size ());
2438
+ }
2439
+ }
2440
+
2409
2441
private static final class IneligibleReplica {
2410
2442
private final int replicaId ;
2411
2443
private final String reason ;
0 commit comments