|
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__
|
@@ -192,6 +192,7 @@ def __init__(self, host, port, afi, **configs):
|
192 | 192 | self.port = port
|
193 | 193 | self.afi = afi
|
194 | 194 | self.in_flight_requests = collections.deque()
|
| 195 | + self._api_versions = None |
195 | 196 |
|
196 | 197 | self.config = copy.copy(self.DEFAULT_CONFIG)
|
197 | 198 | for key in self.config:
|
@@ -870,23 +871,31 @@ def _next_correlation_id(self):
|
870 | 871 | self._correlation_id = (self._correlation_id + 1) % 2**31
|
871 | 872 | return self._correlation_id
|
872 | 873 |
|
873 |
| - def _check_api_version_response(self, response): |
| 874 | + def _handle_api_version_response(self, response): |
| 875 | + error_type = Errors.for_code(response.error_code) |
| 876 | + assert error_type is Errors.NoError, "API version check failed" |
| 877 | + self._api_versions = dict([ |
| 878 | + (api_key, (min_version, max_version)) |
| 879 | + for api_key, min_version, max_version in response.api_versions |
| 880 | + ]) |
| 881 | + return self._api_versions |
| 882 | + |
| 883 | + def _infer_broker_version_from_api_versions(self, api_versions): |
874 | 884 | # The logic here is to check the list of supported request versions
|
875 | 885 | # in descending order. As soon as we find one that works, return it
|
876 | 886 | test_cases = [
|
877 | 887 | # format (<broker verion>, <needed struct>)
|
878 |
| - ((0, 10, 1), MetadataRequest[2]) |
| 888 | + ((0, 11, 0), MetadataRequest[4]), |
| 889 | + ((0, 10, 2), OffsetFetchRequest[2]), |
| 890 | + ((0, 10, 1), MetadataRequest[2]), |
879 | 891 | ]
|
880 | 892 |
|
881 |
| - error_type = Errors.for_code(response.error_code) |
882 |
| - assert error_type is Errors.NoError, "API version check failed" |
883 |
| - max_versions = dict([ |
884 |
| - (api_key, max_version) |
885 |
| - for api_key, _, max_version in response.api_versions |
886 |
| - ]) |
887 | 893 | # Get the best match of test cases
|
888 | 894 | for broker_version, struct in sorted(test_cases, reverse=True):
|
889 |
| - if max_versions.get(struct.API_KEY, -1) >= struct.API_VERSION: |
| 895 | + if struct.API_KEY not in api_versions: |
| 896 | + continue |
| 897 | + min_version, max_version = api_versions[struct.API_KEY] |
| 898 | + if min_version <= struct.API_VERSION <= max_version: |
890 | 899 | return broker_version
|
891 | 900 |
|
892 | 901 | # We know that ApiVersionResponse is only supported in 0.10+
|
@@ -974,7 +983,8 @@ def connect():
|
974 | 983 | if isinstance(request, ApiVersionRequest[0]):
|
975 | 984 | # Starting from 0.10 kafka broker we determine version
|
976 | 985 | # by looking at ApiVersionResponse
|
977 |
| - version = self._check_api_version_response(f.value) |
| 986 | + api_versions = self._handle_api_version_response(f.value) |
| 987 | + version = self._infer_broker_version_from_api_versions(api_versions) |
978 | 988 | log.info('Broker version identifed as %s', '.'.join(map(str, version)))
|
979 | 989 | log.info('Set configuration api_version=%s to skip auto'
|
980 | 990 | ' check_version requests on startup', version)
|
|
0 commit comments