0

I'm using kafka-python library to manage my kafka cluster. I want to add the quotas features (alter/describe), these features are not yet implented in kafka-python library but they are available in kafka protocol doc here.

AlterClientQuotas API (Key: 49):

Requests:

AlterClientQuotas Request (Version: 0) => [entries] validate_only 
entries => [entity] [ops] 
  entity => entity_type entity_name 
    entity_type => STRING
    entity_name => NULLABLE_STRING
 ops => key value remove 
    key => STRING
    value => FLOAT64
    remove => BOOLEAN
validate_only => BOOLEAN

Responses:

AlterClientQuotas Response (Version: 0) => throttle_time_ms [entries] 
 throttle_time_ms => INT32
 entries => error_code error_message [entity] 
   error_code => INT16
   error_message => NULLABLE_STRING
   entity => entity_type entity_name 
     entity_type => STRING
     entity_name => NULLABLE_STRING

To implement these features I'm adding the following code

kafka/protocol/admin.py

from kafka.protocol.api import Request, Response

class AlterClientQuotasResponse_v0(Response):
    API_KEY = 49
    API_VERSION = 0
    SCHEMA = Schema(
        ("throttle_time_ms", Int32),
        (
            "entries",
            Array(
                ("error_code", Int16),
                ("error_message", String),
                ("match", CompactString("utf-8")),
                (
                    "entity",
                    Array(
                        ("entity_type", String("utf-8")),
                        ("entity_name", String("utf-8")),
                    ),
                ),
            ),
        ),
    )

class AlterClientQuotasResponse_v1(Response):
    API_KEY = 49
    API_VERSION = 0
    SCHEMA = Schema(
        ("throttle_time_ms", Int32),
        (
            "entries",
            Array(
                ("error_code", Int16),
                ("error_message", String),
                ("match", CompactString("utf-8")),
                (
                    "entity",
                    Array(
                        ("entity_type", String("utf-8")),
                        ("entity_name", String("utf-8")),
                    ),
                ),
                ("tags", TaggedFields),
            ),
        ),
    )

class AlterClientQuotasRequest_v0(Request):
    API_KEY = 49
    API_VERSION = 0
    RESPONSE_TYPE = AlterClientQuotasResponse_v0
    SCHEMA = Schema(
        (
            "entries", Array(
                ("entity_type", String("utf-8")),
                ("entity_name", String("utf-8")),
            )
        ),
        (
            "ops", Array(
                ("key", String("utf-8")),
                ("value", Float64),
                ("remove", Boolean),
            )
        ),
        ("validate_only", Boolean)
    )

class AlterClientQuotasRequest_v1(Request):
    API_KEY = 49
    API_VERSION = 0
    RESPONSE_TYPE = AlterClientQuotasResponse_v1
    SCHEMA = Schema(
        (
            "entries", Array(
                ("entity_type", String("utf-8")),
                ("entity_name", String("utf-8")),
            )
        ),
        (
            "ops", Array(
                ("key", String("utf-8")),
                ("value", Float64),
                ("remove", Boolean),
            )
        ),
        ("validate_only", Boolean),
        ("tags", TaggedFields),
    )

AlterClientQuotasResponse = [
    AlterClientQuotasResponse_v0,
    AlterClientQuotasResponse_v1
]
AlterClientQuotasRequest = [
    AlterClientQuotasRequest_v0,
    AlterClientQuotasRequest_v1
]

kafka/admin/client.py

request = AlterClientQuotasRequest[0](
  entries=[("user", "<...>.producer"),],
  ops=[("producer_byte_rate", 1024, False),],
  validate_only=True,
  #tags={}
)
print("--> Quota Request :", request)
future = self._send_request_to_node(self._client.least_loaded_node(), request)
self._wait_for_futures([future])
print("-->>> FUTURE Value", future.value)

Running the code below gets the follwing errors :

  1. client output

    File /<...>/py310/lib/python3.10/site-packages/kafka/admin/client.py:1342, in KafkaAdminClient._wait_for_futures(self, futures) 1339 self._client.poll(future=future) 1341 if future.failed(): -> 1342 raise future.exception

    KafkaConnectionError: KafkaConnectionError: socket disconnected
    
  2. server output

    Feb 03 11:24:25 broker-05: org.apache.kafka.common.errors.InvalidRequestException: Error getting request for apiKey: ALTER_CLIENT_QUOTAS, apiVersion: 0, connectionId: , listenerName: ListenerName(SECURED), principal: User: Feb 03 11:24:25 broker-05 Caused by: java.lang.RuntimeException: Tried to allocate a collection of size 292211, but there are only 71 bytes remaining. Feb 03 11:24:25 broker-05 at org.apache.kafka.common.message.AlterClientQuotasRequestData$EntryData.read(AlterClientQuotasRequestData.java:347) Feb 03 11:24:25 broker-05 at org.apache.kafka.common.message.AlterClientQuotasRequestData$EntryData.(AlterClientQuotasRequestData.java:300) Feb 03 11:24:25 broker-05 at org.apache.kafka.common.message.AlterClientQuotasRequestData.read(AlterClientQuotasRequestData.java:125) Feb 03 11:24:25 broker-05 at org.apache.kafka.common.message.AlterClientQuotasRequestData.(AlterClientQuotasRequestData.java:73) Feb 03 11:24:25 broker-05 at org.apache.kafka.common.requests.AlterClientQuotasRequest.parse(AlterClientQuotasRequest.java:142) Feb 03 11:24:25 broker-05 at org.apache.kafka.common.requests.AbstractRequest.doParseRequest(AbstractRequest.java:269) Feb 03 11:24:25 broker-05 at org.apache.kafka.common.requests.AbstractRequest.parseRequest(AbstractRequest.java:165) Feb 03 11:24:25 broker-05 at org.apache.kafka.common.requests.RequestContext.parseRequest(RequestContext.java:95) Feb 03 11:24:25 broker-05 at kafka.network.RequestChannel$Request.(RequestChannel.scala:101) Feb 03 11:24:25 broker-05 at kafka.network.Processor.$anonfun$processCompletedReceives$1(SocketServer.scala:1096) Feb 03 11:24:25 broker-05 at java.base/java.util.LinkedHashMap$LinkedValues.forEach(LinkedHashMap.java:608) Feb 03 11:24:25 broker-05 at kafka.network.Processor.processCompletedReceives(SocketServer.scala:1074) Feb 03 11:24:25 broker-05 at kafka.network.Processor.run(SocketServer.scala:960) Feb 03 11:24:25 broker-05 at java.base/java.lang.Thread.run(Thread.java:829)

Has anyone been able to implement this ? help please ?

Thank you !

a.anghour
  • 21
  • 4

0 Answers0