Skip to content

Commit 1de685b

Browse files
authored
Merge pull request #1099 from datastax/python-1232
PYTHON-1232: protocol v5 out of beta
2 parents 95fae2f + 4a00c22 commit 1de685b

File tree

8 files changed

+63
-24
lines changed

8 files changed

+63
-24
lines changed

cassandra/__init__.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,12 @@ class ProtocolVersion(object):
161161

162162
V5 = 5
163163
"""
164-
v5, in beta from 3.x+
164+
v5, in beta from 3.x+. Finalised in 4.0-beta5
165+
"""
166+
167+
V6 = 6
168+
"""
169+
v6, in beta from 4.0-beta5
165170
"""
166171

167172
DSE_V1 = 0x41
@@ -174,12 +179,12 @@ class ProtocolVersion(object):
174179
DSE private protocol v2, supported in DSE 6.0+
175180
"""
176181

177-
SUPPORTED_VERSIONS = (DSE_V2, DSE_V1, V5, V4, V3, V2, V1)
182+
SUPPORTED_VERSIONS = (DSE_V2, DSE_V1, V6, V5, V4, V3, V2, V1)
178183
"""
179184
A tuple of all supported protocol versions
180185
"""
181186

182-
BETA_VERSIONS = (V5,)
187+
BETA_VERSIONS = (V6,)
183188
"""
184189
A tuple of all beta protocol versions
185190
"""

cassandra/cluster.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
BatchMessage, RESULT_KIND_PREPARED,
6464
RESULT_KIND_SET_KEYSPACE, RESULT_KIND_ROWS,
6565
RESULT_KIND_SCHEMA_CHANGE, ProtocolHandler,
66-
RESULT_KIND_VOID)
66+
RESULT_KIND_VOID, ProtocolException)
6767
from cassandra.metadata import Metadata, protect_name, murmur3, _NodeInfo
6868
from cassandra.policies import (TokenAwarePolicy, DCAwareRoundRobinPolicy, SimpleConvictionPolicy,
6969
ExponentialReconnectionPolicy, HostDistance,
@@ -3548,6 +3548,14 @@ def _try_connect(self, host):
35483548
break
35493549
except ProtocolVersionUnsupported as e:
35503550
self._cluster.protocol_downgrade(host.endpoint, e.startup_version)
3551+
except ProtocolException as e:
3552+
# protocol v5 is out of beta in C* >=4.0-beta5 and is now the default driver
3553+
# protocol version. If the protocol version was not explicitly specified,
3554+
# and that the server raises a beta protocol error, we should downgrade.
3555+
if not self._cluster._protocol_version_explicit and e.is_beta_protocol_error:
3556+
self._cluster.protocol_downgrade(host.endpoint, self._cluster.protocol_version)
3557+
else:
3558+
raise
35513559

35523560
log.debug("[control connection] Established new connection %r, "
35533561
"registering watchers and refreshing schema and topology",

cassandra/connection.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,10 @@ def _connect_socket(self):
897897
for args in self.sockopts:
898898
self._socket.setsockopt(*args)
899899

900+
def _enable_compression(self):
901+
if self._compressor:
902+
self.compressor = self._compressor
903+
900904
def _enable_checksumming(self):
901905
self._io_buffer.set_checksumming_buffer()
902906
self._is_checksumming_enabled = True
@@ -1328,8 +1332,7 @@ def _handle_startup_response(self, startup_response, did_authenticate=False):
13281332
self.authenticator.__class__.__name__)
13291333

13301334
log.debug("Got ReadyMessage on new connection (%s) from %s", id(self), self.endpoint)
1331-
if self._compressor:
1332-
self.compressor = self._compressor
1335+
self._enable_compression()
13331336

13341337
if ProtocolVersion.has_checksumming_support(self.protocol_version):
13351338
self._enable_checksumming()
@@ -1345,6 +1348,10 @@ def _handle_startup_response(self, startup_response, did_authenticate=False):
13451348
"if DSE authentication is configured with transitional mode" % (self.host,))
13461349
raise AuthenticationFailed('Remote end requires authentication')
13471350

1351+
self._enable_compression()
1352+
if ProtocolVersion.has_checksumming_support(self.protocol_version):
1353+
self._enable_checksumming()
1354+
13481355
if isinstance(self.authenticator, dict):
13491356
log.debug("Sending credentials-based auth response on %s", self)
13501357
cm = CredentialsMessage(creds=self.authenticator)

cassandra/protocol.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ class ProtocolException(ErrorMessageSub):
180180
summary = 'Protocol error'
181181
error_code = 0x000A
182182

183+
@property
184+
def is_beta_protocol_error(self):
185+
return 'USE_BETA flag is unset' in str(self)
186+
183187

184188
class BadCredentials(ErrorMessageSub):
185189
summary = 'Bad credentials'

tests/integration/__init__.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,6 @@ def get_default_protocol():
207207
if DSE_VERSION:
208208
return ProtocolVersion.DSE_V2
209209
else:
210-
global ALLOW_BETA_PROTOCOL
211-
ALLOW_BETA_PROTOCOL = True
212210
return ProtocolVersion.V5
213211
if CASSANDRA_VERSION >= Version('3.10'):
214212
if DSE_VERSION:
@@ -234,9 +232,12 @@ def get_supported_protocol_versions():
234232
3.X -> 4, 3
235233
3.10(C*) -> 5(beta),4,3
236234
3.10(DSE) -> DSE_V1,4,3
237-
4.0(C*) -> 5(beta),4,3
235+
4.0(C*) -> 6(beta),5,4,3
238236
4.0(DSE) -> DSE_v2, DSE_V1,4,3
239237
` """
238+
if CASSANDRA_VERSION >= Version('4.0-beta5'):
239+
if not DSE_VERSION:
240+
return (3, 4, 5, 6)
240241
if CASSANDRA_VERSION >= Version('4.0-a'):
241242
if DSE_VERSION:
242243
return (3, 4, ProtocolVersion.DSE_V1, ProtocolVersion.DSE_V2)
@@ -316,7 +317,7 @@ def _id_and_mark(f):
316317
notprotocolv1 = unittest.skipUnless(PROTOCOL_VERSION > 1, 'Protocol v1 not supported')
317318
lessthenprotocolv4 = unittest.skipUnless(PROTOCOL_VERSION < 4, 'Protocol versions 4 or greater not supported')
318319
greaterthanprotocolv3 = unittest.skipUnless(PROTOCOL_VERSION >= 4, 'Protocol versions less than 4 are not supported')
319-
protocolv5 = unittest.skipUnless(5 in get_supported_protocol_versions(), 'Protocol versions less than 5 are not supported')
320+
protocolv6 = unittest.skipUnless(6 in get_supported_protocol_versions(), 'Protocol versions less than 6 are not supported')
320321
greaterthancass20 = unittest.skipUnless(CASSANDRA_VERSION >= Version('2.1'), 'Cassandra version 2.1 or greater required')
321322
greaterthancass21 = unittest.skipUnless(CASSANDRA_VERSION >= Version('2.2'), 'Cassandra version 2.2 or greater required')
322323
greaterthanorequalcass30 = unittest.skipUnless(CASSANDRA_VERSION >= Version('3.0'), 'Cassandra version 3.0 or greater required')

tests/integration/simulacron/test_empty_column.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
from cassandra.cqlengine.connection import set_session
2828
from cassandra.cqlengine.models import Model
2929

30-
from tests.integration import PROTOCOL_VERSION, requiressimulacron
31-
from tests.integration.simulacron import SimulacronCluster
30+
from tests.integration import requiressimulacron
31+
from tests.integration.simulacron import PROTOCOL_VERSION, SimulacronCluster
3232
from tests.integration.simulacron.utils import PrimeQuery, prime_request
3333

3434

tests/integration/standard/test_cluster.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from tests import notwindows
4343
from tests.integration import use_singledc, get_server_versions, CASSANDRA_VERSION, \
4444
execute_until_pass, execute_with_long_wait_retry, get_node, MockLoggingHandler, get_unsupported_lower_protocol, \
45-
get_unsupported_upper_protocol, protocolv5, local, CASSANDRA_IP, greaterthanorequalcass30, lessthanorequalcass40, \
45+
get_unsupported_upper_protocol, protocolv6, local, CASSANDRA_IP, greaterthanorequalcass30, lessthanorequalcass40, \
4646
DSE_VERSION, TestCluster, PROTOCOL_VERSION
4747
from tests.integration.util import assert_quiescent_pool_state
4848
import sys
@@ -261,6 +261,18 @@ def test_protocol_negotiation(self):
261261
elif DSE_VERSION and DSE_VERSION >= Version("5.1"):
262262
self.assertEqual(updated_protocol_version, cassandra.ProtocolVersion.DSE_V1)
263263
self.assertEqual(updated_cluster_version, cassandra.ProtocolVersion.DSE_V1)
264+
elif CASSANDRA_VERSION >= Version('4.0-beta5'):
265+
self.assertEqual(updated_protocol_version, cassandra.ProtocolVersion.V5)
266+
self.assertEqual(updated_cluster_version, cassandra.ProtocolVersion.V5)
267+
elif CASSANDRA_VERSION >= Version('4.0-a'):
268+
self.assertEqual(updated_protocol_version, cassandra.ProtocolVersion.V4)
269+
self.assertEqual(updated_cluster_version, cassandra.ProtocolVersion.V4)
270+
elif CASSANDRA_VERSION >= Version('3.11'):
271+
self.assertEqual(updated_protocol_version, cassandra.ProtocolVersion.V4)
272+
self.assertEqual(updated_cluster_version, cassandra.ProtocolVersion.V4)
273+
elif CASSANDRA_VERSION >= Version('3.0'):
274+
self.assertEqual(updated_protocol_version, cassandra.ProtocolVersion.V4)
275+
self.assertEqual(updated_cluster_version, cassandra.ProtocolVersion.V4)
264276
elif CASSANDRA_VERSION >= Version('2.2'):
265277
self.assertEqual(updated_protocol_version, 4)
266278
self.assertEqual(updated_cluster_version, 4)
@@ -1473,42 +1485,42 @@ def test_prepare_on_ignored_hosts(self):
14731485
cluster.shutdown()
14741486

14751487

1476-
@protocolv5
1488+
@protocolv6
14771489
class BetaProtocolTest(unittest.TestCase):
14781490

1479-
@protocolv5
1491+
@protocolv6
14801492
def test_invalid_protocol_version_beta_option(self):
14811493
"""
1482-
Test cluster connection with protocol v5 and beta flag not set
1494+
Test cluster connection with protocol v6 and beta flag not set
14831495
14841496
@since 3.7.0
1485-
@jira_ticket PYTHON-614
1486-
@expected_result client shouldn't connect with V5 and no beta flag set
1497+
@jira_ticket PYTHON-614, PYTHON-1232
1498+
@expected_result client shouldn't connect with V6 and no beta flag set
14871499
14881500
@test_category connection
14891501
"""
14901502

1491-
cluster = TestCluster(protocol_version=cassandra.ProtocolVersion.V5, allow_beta_protocol_version=False)
1503+
cluster = TestCluster(protocol_version=cassandra.ProtocolVersion.V6, allow_beta_protocol_version=False)
14921504
try:
14931505
with self.assertRaises(NoHostAvailable):
14941506
cluster.connect()
14951507
except Exception as e:
14961508
self.fail("Unexpected error encountered {0}".format(e.message))
14971509

1498-
@protocolv5
1510+
@protocolv6
14991511
def test_valid_protocol_version_beta_options_connect(self):
15001512
"""
15011513
Test cluster connection with protocol version 5 and beta flag set
15021514
15031515
@since 3.7.0
1504-
@jira_ticket PYTHON-614
1505-
@expected_result client should connect with protocol v5 and beta flag set.
1516+
@jira_ticket PYTHON-614, PYTHON-1232
1517+
@expected_result client should connect with protocol v6 and beta flag set.
15061518
15071519
@test_category connection
15081520
"""
1509-
cluster = Cluster(protocol_version=cassandra.ProtocolVersion.V5, allow_beta_protocol_version=True)
1521+
cluster = Cluster(protocol_version=cassandra.ProtocolVersion.V6, allow_beta_protocol_version=True)
15101522
session = cluster.connect()
1511-
self.assertEqual(cluster.protocol_version, cassandra.ProtocolVersion.V5)
1523+
self.assertEqual(cluster.protocol_version, cassandra.ProtocolVersion.V6)
15121524
self.assertTrue(session.execute("select release_version from system.local")[0])
15131525
cluster.shutdown()
15141526

tests/unit/test_cluster.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ def test_protocol_downgrade_test(self):
209209
lower = ProtocolVersion.get_lower_supported(ProtocolVersion.DSE_V2)
210210
self.assertEqual(ProtocolVersion.DSE_V1, lower)
211211
lower = ProtocolVersion.get_lower_supported(ProtocolVersion.DSE_V1)
212+
self.assertEqual(ProtocolVersion.V5,lower)
213+
lower = ProtocolVersion.get_lower_supported(ProtocolVersion.V5)
212214
self.assertEqual(ProtocolVersion.V4,lower)
213215
lower = ProtocolVersion.get_lower_supported(ProtocolVersion.V4)
214216
self.assertEqual(ProtocolVersion.V3,lower)

0 commit comments

Comments
 (0)