Skip to content

Commit db64bba

Browse files
committed
avoid beta protocols when downgrading and added some protocol checks
1 parent 508ae46 commit db64bba

3 files changed

Lines changed: 46 additions & 15 deletions

File tree

cassandra/__init__.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ class ProtocolVersion(object):
164164
A tuple of all supported protocol versions
165165
"""
166166

167+
BETA_VERSIONS = (V5,)
168+
"""
169+
A tuple of all beta protocol versions
170+
"""
171+
167172
MIN_SUPPORTED = min(SUPPORTED_VERSIONS)
168173
"""
169174
Minimum protocol version supported by this driver.
@@ -174,6 +179,31 @@ class ProtocolVersion(object):
174179
Maximum protocol versioni supported by this driver.
175180
"""
176181

182+
@classmethod
183+
def get_lower_supported(cls, previous_version):
184+
"""
185+
Return the lower supported protocol version. Beta versions are omitted.
186+
"""
187+
try:
188+
version = next(v for v in sorted(ProtocolVersion.SUPPORTED_VERSIONS, reverse=True) if
189+
v not in ProtocolVersion.BETA_VERSIONS and v < previous_version)
190+
except StopIteration:
191+
version = 0
192+
193+
return version
194+
195+
@classmethod
196+
def uses_int_query_flags(cls, version):
197+
return version >= cls.V5
198+
199+
@classmethod
200+
def uses_prepare_flags(cls, version):
201+
return version >= cls.V5
202+
203+
@classmethod
204+
def uses_error_code_map(cls, version):
205+
return version >= cls.V5
206+
177207

178208
class SchemaChangeType(object):
179209
DROPPED = 'DROPPED'

cassandra/cluster.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,14 +1113,15 @@ def protocol_downgrade(self, host_addr, previous_version):
11131113
if self._protocol_version_explicit:
11141114
raise DriverException("ProtocolError returned from server while using explicitly set client protocol_version %d" % (previous_version,))
11151115

1116-
try:
1117-
new_version = next(v for v in sorted(ProtocolVersion.SUPPORTED_VERSIONS, reverse=True) if v < previous_version)
1118-
log.warning("Downgrading core protocol version from %d to %d for %s. "
1119-
"To avoid this, it is best practice to explicitly set Cluster(protocol_version) to the version supported by your cluster. "
1120-
"http://datastax.github.io/python-driver/api/cassandra/cluster.html#cassandra.cluster.Cluster.protocol_version", self.protocol_version, new_version, host_addr)
1121-
self.protocol_version = new_version
1122-
except StopIteration:
1123-
raise DriverException("Cannot downgrade protocol version below minimum supported version: %d" % (ProtocolVersion.MIN_SUPPORTED,))
1116+
new_version = ProtocolVersion.get_lower_supported(previous_version)
1117+
if new_version < ProtocolVersion.MIN_SUPPORTED:
1118+
raise DriverException(
1119+
"Cannot downgrade protocol version below minimum supported version: %d" % (ProtocolVersion.MIN_SUPPORTED,))
1120+
1121+
log.warning("Downgrading core protocol version from %d to %d for %s. "
1122+
"To avoid this, it is best practice to explicitly set Cluster(protocol_version) to the version supported by your cluster. "
1123+
"http://datastax.github.io/python-driver/api/cassandra/cluster.html#cassandra.cluster.Cluster.protocol_version", self.protocol_version, new_version, host_addr)
1124+
self.protocol_version = new_version
11241125

11251126
def connect(self, keyspace=None, wait_for_all_pools=False):
11261127
"""

cassandra/protocol.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from six.moves import range
2323
import io
2424

25+
from cassandra import ProtocolVersion
2526
from cassandra import type_codes, DriverException
2627
from cassandra import (Unavailable, WriteTimeout, ReadTimeout,
2728
WriteFailure, ReadFailure, FunctionFailure,
@@ -260,7 +261,7 @@ def recv_error_info(f, protocol_version):
260261
received_responses = read_int(f)
261262
required_responses = read_int(f)
262263

263-
if protocol_version >= 5:
264+
if ProtocolVersion.uses_error_code_map(protocol_version):
264265
error_code_map = read_error_code_map(f)
265266
failures = len(error_code_map)
266267
else:
@@ -308,7 +309,7 @@ def recv_error_info(f, protocol_version):
308309
received_responses = read_int(f)
309310
required_responses = read_int(f)
310311

311-
if protocol_version >= 5:
312+
if ProtocolVersion.uses_error_code_map(protocol_version):
312313
error_code_map = read_error_code_map(f)
313314
failures = len(error_code_map)
314315
else:
@@ -557,7 +558,7 @@ def send_body(self, f, protocol_version):
557558
if self.timestamp is not None:
558559
flags |= _PROTOCOL_TIMESTAMP
559560

560-
if protocol_version >= 5:
561+
if ProtocolVersion.uses_int_query_flags(protocol_version):
561562
write_uint(f, flags)
562563
else:
563564
write_byte(f, flags)
@@ -772,15 +773,14 @@ def __init__(self, query):
772773

773774
def send_body(self, f, protocol_version):
774775
write_longstring(f, self.query)
775-
if protocol_version >= 5:
776+
if ProtocolVersion.uses_prepare_flags(protocol_version):
776777
# Write the flags byte; with 0 value for now, but this should change in PYTHON-678
777778
write_uint(f, 0)
778779

779780

780781
class ExecuteMessage(_MessageType):
781782
opcode = 0x0A
782783
name = 'EXECUTE'
783-
784784
def __init__(self, query_id, query_params, consistency_level,
785785
serial_consistency_level=None, fetch_size=None,
786786
paging_state=None, timestamp=None, skip_meta=False):
@@ -828,7 +828,7 @@ def send_body(self, f, protocol_version):
828828
if self.skip_meta:
829829
flags |= _SKIP_METADATA_FLAG
830830

831-
if protocol_version >= 5:
831+
if ProtocolVersion.uses_int_query_flags(protocol_version):
832832
write_uint(f, flags)
833833
else:
834834
write_byte(f, flags)
@@ -882,7 +882,7 @@ def send_body(self, f, protocol_version):
882882
if self.timestamp is not None:
883883
flags |= _PROTOCOL_TIMESTAMP
884884

885-
if protocol_version >= 5:
885+
if ProtocolVersion.uses_int_query_flags(protocol_version):
886886
write_int(f, flags)
887887
else:
888888
write_byte(f, flags)

0 commit comments

Comments
 (0)