|
17 | 17 | from kafka.metrics.stats import Avg, Count, Max, Rate
|
18 | 18 | from kafka.protocol.api import RequestHeader
|
19 | 19 | from kafka.protocol.admin import SaslHandShakeRequest
|
20 |
| -from kafka.protocol.commit import GroupCoordinatorResponse |
| 20 | +from kafka.protocol.commit import GroupCoordinatorResponse, OffsetFetchRequest |
21 | 21 | from kafka.protocol.metadata import MetadataRequest
|
22 | 22 | from kafka.protocol.types import Int32
|
23 | 23 | from kafka.version import __version__
|
@@ -195,6 +195,7 @@ def __init__(self, host, port, afi, **configs):
|
195 | 195 | self._init_port = port
|
196 | 196 | self._init_afi = afi
|
197 | 197 | self.in_flight_requests = collections.deque()
|
| 198 | + self._api_versions = None |
198 | 199 |
|
199 | 200 | self.config = copy.copy(self.DEFAULT_CONFIG)
|
200 | 201 | for key in self.config:
|
@@ -874,23 +875,31 @@ def _next_correlation_id(self):
|
874 | 875 | self._correlation_id = (self._correlation_id + 1) % 2**31
|
875 | 876 | return self._correlation_id
|
876 | 877 |
|
877 |
| - def _check_api_version_response(self, response): |
| 878 | + def _handle_api_version_response(self, response): |
| 879 | + error_type = Errors.for_code(response.error_code) |
| 880 | + assert error_type is Errors.NoError, "API version check failed" |
| 881 | + self._api_versions = dict([ |
| 882 | + (api_key, (min_version, max_version)) |
| 883 | + for api_key, min_version, max_version in response.api_versions |
| 884 | + ]) |
| 885 | + return self._api_versions |
| 886 | + |
| 887 | + def _infer_broker_version_from_api_versions(self, api_versions): |
878 | 888 | # The logic here is to check the list of supported request versions
|
879 | 889 | # in descending order. As soon as we find one that works, return it
|
880 | 890 | test_cases = [
|
881 | 891 | # format (<broker verion>, <needed struct>)
|
882 |
| - ((0, 10, 1), MetadataRequest[2]) |
| 892 | + ((0, 11, 0), MetadataRequest[4]), |
| 893 | + ((0, 10, 2), OffsetFetchRequest[2]), |
| 894 | + ((0, 10, 1), MetadataRequest[2]), |
883 | 895 | ]
|
884 | 896 |
|
885 |
| - error_type = Errors.for_code(response.error_code) |
886 |
| - assert error_type is Errors.NoError, "API version check failed" |
887 |
| - max_versions = dict([ |
888 |
| - (api_key, max_version) |
889 |
| - for api_key, _, max_version in response.api_versions |
890 |
| - ]) |
891 | 897 | # Get the best match of test cases
|
892 | 898 | for broker_version, struct in sorted(test_cases, reverse=True):
|
893 |
| - if max_versions.get(struct.API_KEY, -1) >= struct.API_VERSION: |
| 899 | + if struct.API_KEY not in api_versions: |
| 900 | + continue |
| 901 | + min_version, max_version = api_versions[struct.API_KEY] |
| 902 | + if min_version <= struct.API_VERSION <= max_version: |
894 | 903 | return broker_version
|
895 | 904 |
|
896 | 905 | # We know that ApiVersionResponse is only supported in 0.10+
|
@@ -978,7 +987,8 @@ def connect():
|
978 | 987 | if isinstance(request, ApiVersionRequest[0]):
|
979 | 988 | # Starting from 0.10 kafka broker we determine version
|
980 | 989 | # by looking at ApiVersionResponse
|
981 |
| - version = self._check_api_version_response(f.value) |
| 990 | + api_versions = self._handle_api_version_response(f.value) |
| 991 | + version = self._infer_broker_version_from_api_versions(api_versions) |
982 | 992 | log.info('Broker version identifed as %s', '.'.join(map(str, version)))
|
983 | 993 | log.info('Set configuration api_version=%s to skip auto'
|
984 | 994 | ' check_version requests on startup', version)
|
|
0 commit comments