mirror of https://github.com/apache/kafka.git
KAFKA-10852: AlterIsr should not be throttled (#9747)
Set it as a cluster action and update the handler in KafkaApis. We keep the `throttleTimeMs` field since we intend to enable throttling in the future (especially relevant when we switch to the built-in quorum mode). Reviewers: David Arthur <mumrah@gmail.com>
This commit is contained in:
parent
78b74debe4
commit
5e5daf47ef
|
|
@ -251,7 +251,7 @@ public enum ApiKeys {
|
|||
EndQuorumEpochRequestData.SCHEMAS, EndQuorumEpochResponseData.SCHEMAS),
|
||||
DESCRIBE_QUORUM(55, "DescribeQuorum", true, false,
|
||||
DescribeQuorumRequestData.SCHEMAS, DescribeQuorumResponseData.SCHEMAS),
|
||||
ALTER_ISR(56, "AlterIsr", AlterIsrRequestData.SCHEMAS, AlterIsrResponseData.SCHEMAS),
|
||||
ALTER_ISR(56, "AlterIsr", true, AlterIsrRequestData.SCHEMAS, AlterIsrResponseData.SCHEMAS),
|
||||
UPDATE_FEATURES(57, "UpdateFeatures",
|
||||
UpdateFeaturesRequestData.SCHEMAS, UpdateFeaturesResponseData.SCHEMAS, true),
|
||||
ENVELOPE(58, "Envelope", true, false, EnvelopeRequestData.SCHEMAS, EnvelopeResponseData.SCHEMAS);
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@ import org.apache.kafka.common.protocol.types.BoundField;
|
|||
import org.apache.kafka.common.protocol.types.Schema;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class ApiKeysTest {
|
||||
|
||||
|
|
@ -43,6 +44,11 @@ public class ApiKeysTest {
|
|||
ApiKeys.PRODUCE.requestSchema((short) ApiKeys.PRODUCE.requestSchemas.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlterIsrIsClusterAction() {
|
||||
assertTrue(ApiKeys.ALTER_ISR.clusterAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* All valid client responses which may be throttled should have a field named
|
||||
* 'throttle_time_ms' to return the throttle time to the client. Exclusions are
|
||||
|
|
@ -55,11 +61,14 @@ public class ApiKeysTest {
|
|||
*/
|
||||
@Test
|
||||
public void testResponseThrottleTime() {
|
||||
List<ApiKeys> authenticationKeys = Arrays.asList(ApiKeys.SASL_HANDSHAKE, ApiKeys.SASL_AUTHENTICATE);
|
||||
Set<ApiKeys> authenticationKeys = EnumSet.of(ApiKeys.SASL_HANDSHAKE, ApiKeys.SASL_AUTHENTICATE);
|
||||
// Newer protocol apis include throttle time ms even for cluster actions
|
||||
Set<ApiKeys> clusterActionsWithThrottleTimeMs = EnumSet.of(ApiKeys.ALTER_ISR);
|
||||
for (ApiKeys apiKey: ApiKeys.values()) {
|
||||
Schema responseSchema = apiKey.responseSchema(apiKey.latestVersion());
|
||||
BoundField throttleTimeField = responseSchema.get(CommonFields.THROTTLE_TIME_MS.name);
|
||||
if (apiKey.clusterAction || authenticationKeys.contains(apiKey))
|
||||
if ((apiKey.clusterAction && !clusterActionsWithThrottleTimeMs.contains(apiKey))
|
||||
|| authenticationKeys.contains(apiKey))
|
||||
assertNull("Unexpected throttle time field: " + apiKey, throttleTimeField);
|
||||
else
|
||||
assertNotNull("Throttle time field missing: " + apiKey, throttleTimeField);
|
||||
|
|
|
|||
|
|
@ -3238,20 +3238,15 @@ class KafkaApis(val requestChannel: RequestChannel,
|
|||
|
||||
def handleAlterIsrRequest(request: RequestChannel.Request): Unit = {
|
||||
val alterIsrRequest = request.body[AlterIsrRequest]
|
||||
authorizeClusterOperation(request, CLUSTER_ACTION)
|
||||
|
||||
if (!authorize(request.context, CLUSTER_ACTION, CLUSTER, CLUSTER_NAME)) {
|
||||
sendResponseMaybeThrottle(request, requestThrottleMs =>
|
||||
alterIsrRequest.getErrorResponse(requestThrottleMs, Errors.CLUSTER_AUTHORIZATION_FAILED.exception))
|
||||
} else if (!controller.isActive) {
|
||||
sendResponseMaybeThrottle(request, requestThrottleMs =>
|
||||
alterIsrRequest.getErrorResponse(requestThrottleMs, Errors.NOT_CONTROLLER.exception()))
|
||||
} else {
|
||||
controller.alterIsrs(alterIsrRequest.data,
|
||||
alterIsrResp => sendResponseMaybeThrottle(request, requestThrottleMs =>
|
||||
new AlterIsrResponse(alterIsrResp.setThrottleTimeMs(requestThrottleMs))
|
||||
)
|
||||
if (!controller.isActive)
|
||||
sendResponseExemptThrottle(request, alterIsrRequest.getErrorResponse(
|
||||
AbstractResponse.DEFAULT_THROTTLE_TIME, Errors.NOT_CONTROLLER.exception))
|
||||
else
|
||||
controller.alterIsrs(alterIsrRequest.data, alterIsrResp =>
|
||||
sendResponseExemptThrottle(request, new AlterIsrResponse(alterIsrResp))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def handleUpdateFeatures(request: RequestChannel.Request): Unit = {
|
||||
|
|
|
|||
|
|
@ -718,7 +718,7 @@ class RequestQuotaTest extends BaseRequestTest {
|
|||
val exemptTarget = exemptRequestMetricValue + 0.02
|
||||
val clientId = apiKey.toString
|
||||
val client = Client(clientId, apiKey)
|
||||
val updated = client.runUntil(response => exemptRequestMetricValue > exemptTarget)
|
||||
val updated = client.runUntil(_ => exemptRequestMetricValue > exemptTarget)
|
||||
|
||||
assertTrue(s"Exempt-request-time metric not updated: $client", updated)
|
||||
assertTrue(s"Client should not have been throttled: $client", throttleTimeMetricValue(clientId).isNaN)
|
||||
|
|
@ -727,13 +727,13 @@ class RequestQuotaTest extends BaseRequestTest {
|
|||
private def checkUnauthorizedRequestThrottle(apiKey: ApiKeys): Unit = {
|
||||
val clientId = "unauthorized-" + apiKey.toString
|
||||
val client = Client(clientId, apiKey)
|
||||
val throttled = client.runUntil(response => throttleTimeMetricValue(clientId) > 0.0)
|
||||
val throttled = client.runUntil(_ => throttleTimeMetricValue(clientId) > 0.0)
|
||||
assertTrue(s"Unauthorized client should have been throttled: $client", throttled)
|
||||
}
|
||||
}
|
||||
|
||||
object RequestQuotaTest {
|
||||
val ClusterActions = ApiKeys.enabledApis.asScala.toSet.filter(apiKey => apiKey.clusterAction)
|
||||
val ClusterActions = ApiKeys.enabledApis.asScala.filter(_.clusterAction).toSet
|
||||
val SaslActions = Set(ApiKeys.SASL_HANDSHAKE, ApiKeys.SASL_AUTHENTICATE)
|
||||
val ClientActions = ApiKeys.enabledApis.asScala.toSet -- ClusterActions -- SaslActions
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue