Search in sources :

Example 1 with UnsupportedProtocolVersionException

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);
    }
}
Also used : AllNodesFailedException(com.datastax.oss.driver.api.core.AllNodesFailedException) DriverConfigLoader(com.datastax.oss.driver.api.core.config.DriverConfigLoader) UnsupportedProtocolVersionException(com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException) CqlSession(com.datastax.oss.driver.api.core.CqlSession) Test(org.junit.Test) CassandraRequirement(com.datastax.oss.driver.api.testinfra.CassandraRequirement)

Example 2 with UnsupportedProtocolVersionException

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);
    });
}
Also used : Frame(com.datastax.oss.protocol.internal.Frame) Error(com.datastax.oss.protocol.internal.response.Error) UnsupportedProtocolVersionException(com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException) Test(org.junit.Test) UseDataProvider(com.tngtech.java.junit.dataprovider.UseDataProvider)

Example 3 with UnsupportedProtocolVersionException

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);
            }
        }
    });
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) UnsupportedProtocolVersionException(com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException) ProtocolVersion(com.datastax.oss.driver.api.core.ProtocolVersion) NettyOptions(com.datastax.oss.driver.internal.core.context.NettyOptions) TypesafeDriverConfig(com.datastax.oss.driver.internal.core.config.typesafe.TypesafeDriverConfig) Bootstrap(io.netty.bootstrap.Bootstrap) DriverConfig(com.datastax.oss.driver.api.core.config.DriverConfig) TypesafeDriverConfig(com.datastax.oss.driver.internal.core.config.typesafe.TypesafeDriverConfig) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList)

Example 4 with UnsupportedProtocolVersionException

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);
    }
}
Also used : AllNodesFailedException(com.datastax.oss.driver.api.core.AllNodesFailedException) DriverConfigLoader(com.datastax.oss.driver.api.core.config.DriverConfigLoader) UnsupportedProtocolVersionException(com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException) CqlSession(com.datastax.oss.driver.api.core.CqlSession) Test(org.junit.Test) CassandraRequirement(com.datastax.oss.driver.api.testinfra.CassandraRequirement)

Example 5 with UnsupportedProtocolVersionException

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;
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) DseProtocolVersion(com.datastax.dse.driver.api.core.DseProtocolVersion) DefaultProtocolVersion(com.datastax.oss.driver.api.core.DefaultProtocolVersion) Version(com.datastax.oss.driver.api.core.Version) ProtocolVersion(com.datastax.oss.driver.api.core.ProtocolVersion) Node(com.datastax.oss.driver.api.core.metadata.Node) DseProtocolVersion(com.datastax.dse.driver.api.core.DseProtocolVersion) DefaultProtocolVersion(com.datastax.oss.driver.api.core.DefaultProtocolVersion) ProtocolVersion(com.datastax.oss.driver.api.core.ProtocolVersion) UnsupportedProtocolVersionException(com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException)

Aggregations

UnsupportedProtocolVersionException (com.datastax.oss.driver.api.core.UnsupportedProtocolVersionException)7 Test (org.junit.Test)5 Frame (com.datastax.oss.protocol.internal.Frame)3 Error (com.datastax.oss.protocol.internal.response.Error)3 AllNodesFailedException (com.datastax.oss.driver.api.core.AllNodesFailedException)2 CqlSession (com.datastax.oss.driver.api.core.CqlSession)2 ProtocolVersion (com.datastax.oss.driver.api.core.ProtocolVersion)2 DriverConfigLoader (com.datastax.oss.driver.api.core.config.DriverConfigLoader)2 CassandraRequirement (com.datastax.oss.driver.api.testinfra.CassandraRequirement)2 UseDataProvider (com.tngtech.java.junit.dataprovider.UseDataProvider)2 DseProtocolVersion (com.datastax.dse.driver.api.core.DseProtocolVersion)1 DefaultProtocolVersion (com.datastax.oss.driver.api.core.DefaultProtocolVersion)1 Version (com.datastax.oss.driver.api.core.Version)1 DriverConfig (com.datastax.oss.driver.api.core.config.DriverConfig)1 Node (com.datastax.oss.driver.api.core.metadata.Node)1 TypesafeDriverConfig (com.datastax.oss.driver.internal.core.config.typesafe.TypesafeDriverConfig)1 NettyOptions (com.datastax.oss.driver.internal.core.context.NettyOptions)1 Bootstrap (io.netty.bootstrap.Bootstrap)1 Channel (io.netty.channel.Channel)1 ChannelFuture (io.netty.channel.ChannelFuture)1