use of com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException in project java-driver by datastax.
the class ProtocolVersionInitialNegotiationIT method should_fail_if_provided_v4_is_not_supported_oss.
@CassandraRequirement(max = "2.2", description = "Only C* in [*,2.2[ has V4 unsupported")
@Test
public void should_fail_if_provided_v4_is_not_supported_oss() {
Assume.assumeFalse("This test is only for OSS C*", ccm.getDseVersion().isPresent());
DriverConfigLoader loader = SessionUtils.configLoaderBuilder().withString(DefaultDriverOption.PROTOCOL_VERSION, "V4").build();
try (CqlSession ignored = SessionUtils.newSession(ccm, loader)) {
fail("Expected an AllNodesFailedException");
} catch (AllNodesFailedException anfe) {
Throwable cause = anfe.getAllErrors().values().iterator().next().get(0);
assertThat(cause).isInstanceOf(UnsupportedProtocolVersionException.class);
UnsupportedProtocolVersionException unsupportedException = (UnsupportedProtocolVersionException) cause;
assertThat(unsupportedException.getAttemptedVersions()).containsOnly(DefaultProtocolVersion.V4);
}
}
use of com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException in project java-driver by datastax.
the class ChannelFactoryProtocolNegotiationTest method should_fail_if_version_specified_and_not_supported_by_server.
@Test
@UseDataProvider("unsupportedProtocolCodes")
public void should_fail_if_version_specified_and_not_supported_by_server(int errorCode) {
// Given
when(defaultProfile.isDefined(DefaultDriverOption.PROTOCOL_VERSION)).thenReturn(true);
when(defaultProfile.getString(DefaultDriverOption.PROTOCOL_VERSION)).thenReturn("V4");
when(protocolVersionRegistry.fromName("V4")).thenReturn(DefaultProtocolVersion.V4);
ChannelFactory factory = newChannelFactory();
// When
CompletionStage<DriverChannel> channelFuture = factory.connect(SERVER_ADDRESS, DriverChannelOptions.DEFAULT, NoopNodeMetricUpdater.INSTANCE);
Frame requestFrame = readOutboundFrame();
assertThat(requestFrame.message).isInstanceOf(Options.class);
writeInboundFrame(requestFrame, TestResponses.supportedResponse("mock_key", "mock_value"));
requestFrame = readOutboundFrame();
assertThat(requestFrame.protocolVersion).isEqualTo(DefaultProtocolVersion.V4.getCode());
// Server does not support v4
writeInboundFrame(requestFrame, new Error(errorCode, "Invalid or unsupported protocol version"));
// Then
assertThatStage(channelFuture).isFailed(e -> {
assertThat(e).isInstanceOf(UnsupportedProtocolVersionException.class).hasMessageContaining("Host does not support protocol version V4");
assertThat(((UnsupportedProtocolVersionException) e).getAttemptedVersions()).containsExactly(DefaultProtocolVersion.V4);
});
}
use of com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException in project java-driver by datastax.
the class ChannelFactory method connect.
private void connect(EndPoint endPoint, DriverChannelOptions options, NodeMetricUpdater nodeMetricUpdater, ProtocolVersion currentVersion, boolean isNegotiating, List<ProtocolVersion> attemptedVersions, CompletableFuture<DriverChannel> resultFuture) {
NettyOptions nettyOptions = context.getNettyOptions();
Bootstrap bootstrap = new Bootstrap().group(nettyOptions.ioEventLoopGroup()).channel(nettyOptions.channelClass()).option(ChannelOption.ALLOCATOR, nettyOptions.allocator()).handler(initializer(endPoint, currentVersion, options, nodeMetricUpdater, resultFuture));
nettyOptions.afterBootstrapInitialized(bootstrap);
ChannelFuture connectFuture = bootstrap.connect(endPoint.resolve());
connectFuture.addListener(cf -> {
if (connectFuture.isSuccess()) {
Channel channel = connectFuture.channel();
DriverChannel driverChannel = new DriverChannel(endPoint, channel, context.getWriteCoalescer(), currentVersion);
// cluster name for future connections.
if (isNegotiating) {
ChannelFactory.this.protocolVersion = currentVersion;
}
if (ChannelFactory.this.clusterName == null) {
ChannelFactory.this.clusterName = driverChannel.getClusterName();
}
Map<String, List<String>> supportedOptions = driverChannel.getOptions();
if (ChannelFactory.this.productType == null && supportedOptions != null) {
List<String> productTypes = supportedOptions.get("PRODUCT_TYPE");
String productType = productTypes != null && !productTypes.isEmpty() ? productTypes.get(0) : UNKNOWN_PRODUCT_TYPE;
ChannelFactory.this.productType = productType;
DriverConfig driverConfig = context.getConfig();
if (driverConfig instanceof TypesafeDriverConfig && productType.equals(DATASTAX_CLOUD_PRODUCT_TYPE)) {
((TypesafeDriverConfig) driverConfig).overrideDefaults(ImmutableMap.of(DefaultDriverOption.REQUEST_CONSISTENCY, ConsistencyLevel.LOCAL_QUORUM.name()));
}
}
resultFuture.complete(driverChannel);
} else {
Throwable error = connectFuture.cause();
if (error instanceof UnsupportedProtocolVersionException && isNegotiating) {
attemptedVersions.add(currentVersion);
Optional<ProtocolVersion> downgraded = context.getProtocolVersionRegistry().downgrade(currentVersion);
if (downgraded.isPresent()) {
LOG.debug("[{}] Failed to connect with protocol {}, retrying with {}", logPrefix, currentVersion, downgraded.get());
connect(endPoint, options, nodeMetricUpdater, downgraded.get(), true, attemptedVersions, resultFuture);
} else {
resultFuture.completeExceptionally(UnsupportedProtocolVersionException.forNegotiation(endPoint, attemptedVersions));
}
} else {
// Note: might be completed already if the failure happened in initializer(), this is
// fine
resultFuture.completeExceptionally(error);
}
}
});
}
use of com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException in project java-driver by datastax.
the class ProtocolVersionInitialNegotiationIT method should_fail_if_provided_v5_is_not_supported_oss.
@CassandraRequirement(min = "2.1", max = "4.0-rc1", description = "Only C* in [2.1,4.0-rc1[ has V5 unsupported or supported as beta")
@Test
public void should_fail_if_provided_v5_is_not_supported_oss() {
Assume.assumeFalse("This test is only for OSS C*", ccm.getDseVersion().isPresent());
DriverConfigLoader loader = SessionUtils.configLoaderBuilder().withString(DefaultDriverOption.PROTOCOL_VERSION, "V5").build();
try (CqlSession ignored = SessionUtils.newSession(ccm, loader)) {
fail("Expected an AllNodesFailedException");
} catch (AllNodesFailedException anfe) {
Throwable cause = anfe.getAllErrors().values().iterator().next().get(0);
assertThat(cause).isInstanceOf(UnsupportedProtocolVersionException.class);
UnsupportedProtocolVersionException unsupportedException = (UnsupportedProtocolVersionException) cause;
assertThat(unsupportedException.getAttemptedVersions()).containsOnly(DefaultProtocolVersion.V5);
}
}
use of com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException in project java-driver by datastax.
the class DefaultProtocolVersionRegistry method highestCommon.
@Override
public ProtocolVersion highestCommon(Collection<Node> nodes) {
if (nodes == null || nodes.isEmpty()) {
throw new IllegalArgumentException("Expected at least one node");
}
// Start with all non-beta versions (beta versions are always forced, and we don't call this
// method if the version was forced).
Set<ProtocolVersion> candidates = new LinkedHashSet<>();
for (ProtocolVersion version : allVersions) {
if (!version.isBeta()) {
candidates.add(version);
}
}
// Keep an unfiltered copy in case we need to throw an exception below
ImmutableList<ProtocolVersion> initialCandidates = ImmutableList.copyOf(candidates);
// For each node, remove the versions it doesn't support
for (Node node : nodes) {
// We can't trust the Cassandra version reported by DSE to infer the maximum OSS protocol
// supported. For example DSE 6 reports release_version 4.0-SNAPSHOT, but only supports OSS
// protocol v4 (while Cassandra 4 will support v5). So we treat DSE separately.
Version dseVersion = (Version) node.getExtras().get(DseNodeProperties.DSE_VERSION);
if (dseVersion != null) {
LOG.debug("[{}] Node {} reports DSE version {}", logPrefix, node.getEndPoint(), dseVersion);
dseVersion = dseVersion.nextStable();
if (dseVersion.compareTo(DSE_4_7_0) < 0) {
throw new UnsupportedProtocolVersionException(node.getEndPoint(), String.format("Node %s reports DSE version %s, " + "but the driver only supports 4.7.0 and above", node.getEndPoint(), dseVersion), initialCandidates);
} else if (dseVersion.compareTo(DSE_5_0_0) < 0) {
// DSE 4.7.x, 4.8.x
removeHigherThan(DefaultProtocolVersion.V3, null, candidates);
} else if (dseVersion.compareTo(DSE_5_1_0) < 0) {
// DSE 5.0
removeHigherThan(DefaultProtocolVersion.V4, null, candidates);
} else if (dseVersion.compareTo(DSE_6_0_0) < 0) {
// DSE 5.1
removeHigherThan(DefaultProtocolVersion.V4, DseProtocolVersion.DSE_V1, candidates);
} else if (dseVersion.compareTo(DSE_7_0_0) < 0) {
// DSE 6
removeHigherThan(DefaultProtocolVersion.V4, DseProtocolVersion.DSE_V2, candidates);
} else {
// DSE 7.0
removeHigherThan(DefaultProtocolVersion.V5, DseProtocolVersion.DSE_V2, candidates);
}
} else {
// not DSE
Version cassandraVersion = node.getCassandraVersion();
if (cassandraVersion == null) {
LOG.warn("[{}] Node {} reports neither DSE version nor Cassandra version, " + "ignoring it from optimal protocol version computation", logPrefix, node.getEndPoint());
continue;
}
cassandraVersion = cassandraVersion.nextStable();
LOG.debug("[{}] Node {} reports Cassandra version {}", logPrefix, node.getEndPoint(), cassandraVersion);
if (cassandraVersion.compareTo(Version.V2_1_0) < 0) {
throw new UnsupportedProtocolVersionException(node.getEndPoint(), String.format("Node %s reports Cassandra version %s, " + "but the driver only supports 2.1.0 and above", node.getEndPoint(), cassandraVersion), ImmutableList.of(DefaultProtocolVersion.V3, DefaultProtocolVersion.V4));
} else if (cassandraVersion.compareTo(Version.V2_2_0) < 0) {
// 2.1.0
removeHigherThan(DefaultProtocolVersion.V3, null, candidates);
} else if (cassandraVersion.compareTo(Version.V4_0_0) < 0) {
// 2.2, 3.x
removeHigherThan(DefaultProtocolVersion.V4, null, candidates);
} else {
// 4.0
removeHigherThan(DefaultProtocolVersion.V5, null, candidates);
}
}
}
// If we have versions left, return the highest one
ProtocolVersion max = null;
for (ProtocolVersion candidate : candidates) {
if (max == null || max.getCode() < candidate.getCode()) {
max = candidate;
}
}
if (max == null) {
// Note: with the current algorithm, this never happens
throw new UnsupportedProtocolVersionException(null, String.format("Could not determine a common protocol version, " + "enable DEBUG logs for '%s' for more details", LOG.getName()), initialCandidates);
} else {
return max;
}
}
Aggregations