From 72ac567d0ed177ccac6c7168ca6cf8119acd2061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20B=C4=85czkowski?= Date: Thu, 25 Sep 2025 18:34:55 +0200 Subject: [PATCH 1/2] Remove serverless related code and dependencies BouncyCastle dependencies were removed since they are no longer needed. Removes ConfigurationBundle, Parameters, ScyllaCloudAuthInfo, ScyllaCloudConnectionConfig, ScyllaCloudContext, ScyllaCloudDatacenter, ScyllaCloudSniEndPointFactory, CloudConfigYamlParsingTest, ScyllaSniProxyTest Removes adjustments from CCMAccess, CCMBridge, CCMCache, CCMConfig, CCMTestsSupport. Removes usages in Cluster.java. Adds new ignores to clirr that cover removed public APIs. --- clirr-ignores.xml | 28 +++ driver-core/pom.xml | 18 -- .../com/datastax/driver/core/Cluster.java | 91 ------- .../driver/core/ConfigurationBundle.java | 122 --------- .../com/datastax/driver/core/Parameters.java | 32 --- .../driver/core/ScyllaCloudAuthInfo.java | 95 ------- .../core/ScyllaCloudConnectionConfig.java | 232 ------------------ .../driver/core/ScyllaCloudContext.java | 26 -- .../driver/core/ScyllaCloudDatacenter.java | 171 ------------- .../core/ScyllaCloudSniEndPointFactory.java | 45 ---- .../com/datastax/driver/core/CCMAccess.java | 3 - .../com/datastax/driver/core/CCMBridge.java | 29 --- .../com/datastax/driver/core/CCMCache.java | 5 - .../com/datastax/driver/core/CCMConfig.java | 2 - .../datastax/driver/core/CCMTestsSupport.java | 38 --- .../core/CloudConfigYamlParsingTest.java | 36 --- .../driver/core/ScyllaSniProxyTest.java | 125 ---------- 17 files changed, 28 insertions(+), 1070 deletions(-) delete mode 100644 driver-core/src/main/java/com/datastax/driver/core/ConfigurationBundle.java delete mode 100644 driver-core/src/main/java/com/datastax/driver/core/Parameters.java delete mode 100644 driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudAuthInfo.java delete mode 100644 driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudConnectionConfig.java delete mode 100644 driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudContext.java delete mode 100644 driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudDatacenter.java delete mode 100644 driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudSniEndPointFactory.java delete mode 100644 driver-core/src/test/java/com/datastax/driver/core/CloudConfigYamlParsingTest.java delete mode 100644 driver-core/src/test/java/com/datastax/driver/core/ScyllaSniProxyTest.java diff --git a/clirr-ignores.xml b/clirr-ignores.xml index ebb546569d7..f129c478423 100644 --- a/clirr-ignores.xml +++ b/clirr-ignores.xml @@ -37,6 +37,34 @@ Replacing Datastax Cloud with Scylla Cloud. Removing confusing code that won't be maintained. + + 7002 + com/datastax/driver/core/Cluster$Builder + com.datastax.driver.core.Cluster$Builder withScyllaCloudConnectionConfig(java.io.File) + Serverless was dropped. This code has no use anymore. + + + + 7002 + com/datastax/driver/core/Cluster$Builder + com.datastax.driver.core.Cluster$Builder withScyllaCloudConnectionConfig(java.net.URL) + Serverless was dropped. This code has no use anymore. + + + + 7002 + com/datastax/driver/core/Cluster$Builder + com.datastax.driver.core.Cluster$Builder withScyllaCloudConnectionConfig(java.io.InputStream) + Serverless was dropped. This code has no use anymore. + + + + 7002 + com/datastax/driver/core/Cluster$Builder + com.datastax.driver.core.Cluster$Builder withScyllaCloudConnectionConfig(com.datastax.driver.core.ScyllaCloudConnectionConfig) + Serverless was dropped. This code has no use anymore. + + 7004 com/datastax/driver/core/Metadata diff --git a/driver-core/pom.xml b/driver-core/pom.xml index b7479d8a98a..0c6d669a0ff 100644 --- a/driver-core/pom.xml +++ b/driver-core/pom.xml @@ -176,24 +176,6 @@ com.fasterxml.jackson.dataformat jackson-dataformat-yaml - - - org.bouncycastle - bcprov-jdk18on - 1.82 - - - - org.bouncycastle - bcpkix-jdk18on - 1.82 - - - - org.bouncycastle - bcutil-jdk18on - 1.82 - diff --git a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java index e607acbcda8..c323cdedf88 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Cluster.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Cluster.java @@ -60,14 +60,9 @@ import com.google.common.util.concurrent.SettableFuture; import com.google.common.util.concurrent.Uninterruptibles; import java.io.Closeable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.URL; import java.net.UnknownHostException; -import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -1384,92 +1379,6 @@ public Builder withNoCompact() { return this; } - /** - * Configure for Scylla Cloud Serverless cluster using configuration bundle. - * - * @param configurationFile configuration bundle file. - * @return this builder. - * @throws IOException - * @see Builder#withScyllaCloudConnectionConfig(ScyllaCloudConnectionConfig) - */ - public Builder withScyllaCloudConnectionConfig(File configurationFile) throws IOException { - return withScyllaCloudConnectionConfig(configurationFile.toURI().toURL()); - } - - /** - * Configure for Scylla Cloud Serverless cluster using URL to configuration bundle. - * - * @param configurationUrl URL from which configuration bundle can be read. - * @return this builder. - * @throws IOException - * @see Builder#withScyllaCloudConnectionConfig(ScyllaCloudConnectionConfig) - */ - public Builder withScyllaCloudConnectionConfig(URL configurationUrl) throws IOException { - return withScyllaCloudConnectionConfig(configurationUrl.openStream()); - } - - /** - * Configure for Scylla Cloud Serverless cluster using InputStream of configuration bundle. - * - * @param inputStream input stream containing configuration bundle format data. - * @return this builder. - * @throws IOException - * @see Builder#withScyllaCloudConnectionConfig(ScyllaCloudConnectionConfig) - */ - public Builder withScyllaCloudConnectionConfig(InputStream inputStream) throws IOException { - return withScyllaCloudConnectionConfig( - ScyllaCloudConnectionConfig.fromInputStream(inputStream)); - } - - /** - * Sets a collection of options for connecting to Scylla Cloud Serverless cluster. - * - *

Sets several options according to provided {@link ScyllaCloudConnectionConfig}. This - * includes calling {@link Builder#withEndPointFactory(EndPointFactory)}, {@link - * Builder#withSSL(SSLOptions)}, {@link Builder#withAuthProvider(AuthProvider)}, {@link - * Builder#withoutAdvancedShardAwareness()} with parameters derived from the config. - * - *

Cannot be combined with {@link Builder#addContactPoint}. All contact points should already - * be provided in {@link ScyllaCloudConnectionConfig}. - * - * @param config instantiated ScyllaCloudConnectionConfig. - * @return this builder. - */ - protected Builder withScyllaCloudConnectionConfig(ScyllaCloudConnectionConfig config) { - try { - ScyllaCloudDatacenter currentDatacenter = config.getCurrentDatacenter(); - InetSocketAddress proxyAddress = currentDatacenter.getServer(); - - Builder builder = - withEndPointFactory( - new ScyllaCloudSniEndPointFactory( - proxyAddress, currentDatacenter.getNodeDomain())) - .withSSL( - (config.getCurrentDatacenter().isInsecureSkipTlsVerify() - ? config.createBundle().getInsecureSSLOptions() - : config.createBundle().getSSLOptions())) - .withAuthProvider( - new PlainTextAuthProvider( - config.getCurrentAuthInfo().getUsername(), - config.getCurrentAuthInfo().getPassword())) - .withoutAdvancedShardAwareness(); - - if (builder.rawHostContactPoints.size() > 0 - || builder.rawHostAndPortContactPoints.size() > 0 - || builder.contactPoints.size() > 0) { - throw new IllegalStateException( - "Can't use withCloudSecureConnectBundle if you've already called addContactPoint(s)"); - } - builder.addContactPoint(new SniEndPoint(proxyAddress, currentDatacenter.getNodeDomain())); - - return builder; - } catch (IOException e) { - throw new IllegalStateException("Cannot construct cloud config", e); - } catch (GeneralSecurityException e) { - throw new IllegalStateException("Cannot construct cloud config", e); - } - } - /** * Disables advanced shard awareness. By default, this driver chooses local port while making a * connection to node, to signal which shard it wants to connect to. This allows driver to diff --git a/driver-core/src/main/java/com/datastax/driver/core/ConfigurationBundle.java b/driver-core/src/main/java/com/datastax/driver/core/ConfigurationBundle.java deleted file mode 100644 index 3c8b3f74fb1..00000000000 --- a/driver-core/src/main/java/com/datastax/driver/core/ConfigurationBundle.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2022 ScyllaDB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.datastax.driver.core; - -import java.io.*; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -class ConfigurationBundle { - private final KeyStore identity; - private final KeyStore trustStore; - - public ConfigurationBundle(KeyStore identity, KeyStore trustStore) { - this.identity = identity; - this.trustStore = trustStore; - } - - public KeyStore getIdentity() { - return identity; - } - - public KeyStore getTrustStore() { - return trustStore; - } - - private void writeKeystore(String path, KeyStore ks, char[] password) - throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { - File file = new File(path); - OutputStream os = new FileOutputStream(file); - ks.store(os, password); - os.close(); - } - - public void writeIdentity(String path, char[] password) - throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException { - writeKeystore(path, identity, password); - } - - public void writeTrustStore(String path, char[] password) - throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException { - writeKeystore(path, trustStore, password); - } - - protected SSLContext getSSLContext() throws IOException, GeneralSecurityException { - KeyManagerFactory kmf = createKeyManagerFactory(identity); - TrustManagerFactory tmf = createTrustManagerFactory(trustStore); - SSLContext sslContext = SSLContext.getInstance("SSL"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); - return sslContext; - } - - protected SSLContext getInsecureSSLContext() throws IOException, GeneralSecurityException { - KeyManagerFactory kmf = createKeyManagerFactory(identity); - SSLContext sslContext = SSLContext.getInstance("SSL"); - TrustManager[] trustManager = - new TrustManager[] { - new X509TrustManager() { - @Override - public void checkClientTrusted(X509Certificate[] x509Certificates, String s) - throws CertificateException {} - - @Override - public void checkServerTrusted(X509Certificate[] x509Certificates, String s) - throws CertificateException {} - - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - } - }; - sslContext.init(kmf.getKeyManagers(), trustManager, new SecureRandom()); - return sslContext; - } - - protected KeyManagerFactory createKeyManagerFactory(KeyStore ks) - throws IOException, GeneralSecurityException { - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, "cassandra".toCharArray()); - return kmf; - } - - protected TrustManagerFactory createTrustManagerFactory(KeyStore ts) - throws IOException, GeneralSecurityException { - TrustManagerFactory tmf = - TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(ts); - return tmf; - } - - protected SSLOptions getSSLOptions() throws GeneralSecurityException, IOException { - return SniSSLOptions.builder().withSSLContext(getSSLContext()).build(); - } - - protected SSLOptions getInsecureSSLOptions() throws GeneralSecurityException, IOException { - return SniSSLOptions.builder().withSSLContext(getInsecureSSLContext()).build(); - } -} diff --git a/driver-core/src/main/java/com/datastax/driver/core/Parameters.java b/driver-core/src/main/java/com/datastax/driver/core/Parameters.java deleted file mode 100644 index 9e462756713..00000000000 --- a/driver-core/src/main/java/com/datastax/driver/core/Parameters.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2022 ScyllaDB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.driver.core; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -class Parameters { - private final ConsistencyLevel defaultConsistency; - private final ConsistencyLevel defaultSerialConsistency; - - @JsonCreator - public Parameters( - @JsonProperty(value = "defaultConsistency") ConsistencyLevel defaultConsistency, - @JsonProperty(value = "defaultSerialConsistency") ConsistencyLevel defaultSerialConsistency) { - this.defaultConsistency = defaultConsistency; - this.defaultSerialConsistency = defaultSerialConsistency; - } -} diff --git a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudAuthInfo.java b/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudAuthInfo.java deleted file mode 100644 index ddb3d794f9d..00000000000 --- a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudAuthInfo.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2022 ScyllaDB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.driver.core; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.File; - -class ScyllaCloudAuthInfo { - private final byte[] clientCertificateData; - private final String clientCertificatePath; - private final byte[] clientKeyData; - private final String clientKeyPath; - private final String username; - private final String password; - - @JsonCreator - public ScyllaCloudAuthInfo( - @JsonProperty(value = "clientCertificateData") byte[] clientCertificateData, - @JsonProperty(value = "clientCertificatePath") String clientCertificatePath, - @JsonProperty(value = "clientKeyData") byte[] clientKeyData, - @JsonProperty(value = "clientKeyPath") String clientKeyPath, - @JsonProperty(value = "username") String username, - @JsonProperty(value = "password") String password) { - this.clientCertificateData = clientCertificateData; - this.clientCertificatePath = clientCertificatePath; - this.clientKeyData = clientKeyData; - this.clientKeyPath = clientKeyPath; - this.username = username; - this.password = password; - } - - public void validate() { - if (clientCertificateData == null) { - if (clientCertificatePath == null) { - throw new IllegalArgumentException( - "Either clientCertificateData or clientCertificatePath has to be provided for authInfo."); - } - File file = new File(clientCertificatePath); - if (!file.canRead()) { - throw new IllegalArgumentException( - "Cannot read file at given clientCertificatePath (" + clientCertificatePath + ")."); - } - } - - if (clientKeyData == null) { - if (clientKeyPath == null) { - throw new IllegalArgumentException( - "Either clientKeyData or clientKeyPath has to be provided for authInfo."); - } - File file = new File(clientKeyPath); - if (!file.canRead()) { - throw new IllegalArgumentException( - "Cannot read file at given clientKeyPath (" + clientKeyPath + ")."); - } - } - } - - public byte[] getClientCertificateData() { - return clientCertificateData; - } - - public String getClientCertificatePath() { - return clientCertificatePath; - } - - public byte[] getClientKeyData() { - return clientKeyData; - } - - public String getClientKeyPath() { - return clientKeyPath; - } - - public String getUsername() { - return username; - } - - public String getPassword() { - return password; - } -} diff --git a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudConnectionConfig.java b/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudConnectionConfig.java deleted file mode 100644 index 78be455414a..00000000000 --- a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudConnectionConfig.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2022 ScyllaDB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.datastax.driver.core; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import java.io.*; -import java.security.*; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.spec.InvalidKeySpecException; -import java.util.Map; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; - -class ScyllaCloudConnectionConfig { - private final String kind; - private final String apiVersion; - private final Map datacenters; - private final Map authInfos; - private final Map contexts; - private final String currentContext; - private final Parameters parameters; - - @JsonCreator - public ScyllaCloudConnectionConfig( - @JsonProperty(value = "kind") String kind, - @JsonProperty(value = "apiVersion") String apiVersion, - @JsonProperty(value = "datacenters", required = true) - Map datacenters, - @JsonProperty(value = "authInfos", required = true) - Map authInfos, - @JsonProperty(value = "contexts", required = true) Map contexts, - @JsonProperty(value = "currentContext", required = true) String currentContext, - @JsonProperty(value = "parameters") Parameters parameters) { - this.kind = kind; - this.apiVersion = apiVersion; - this.datacenters = datacenters; - this.authInfos = authInfos; - this.contexts = contexts; - this.currentContext = currentContext; - this.parameters = parameters; - } - - public static ScyllaCloudConnectionConfig fromInputStream(InputStream inputStream) - throws IOException { - ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - ScyllaCloudConnectionConfig scyllaCloudConnectionConfig = - mapper.readValue(inputStream, ScyllaCloudConnectionConfig.class); - scyllaCloudConnectionConfig.validate(); - return scyllaCloudConnectionConfig; - } - - public void validate() { - if (this.datacenters == null) { - throw new IllegalArgumentException( - "Please provide datacenters (datacenters:) in the configuration yaml."); - } - for (ScyllaCloudDatacenter datacenter : datacenters.values()) { - datacenter.validate(); - } - - if (this.authInfos == null) { - throw new IllegalArgumentException( - "Please provide any authentication config (authInfos:) in the configuration yaml."); - } - for (ScyllaCloudAuthInfo authInfo : authInfos.values()) { - authInfo.validate(); - } - - if (this.contexts == null) { - throw new IllegalArgumentException( - "Please provide any configuration (contexts:) context in the configuration yaml."); - } - - if (this.currentContext == null) { - throw new IllegalArgumentException( - "Please set default context (currentContext:) in the configuration yaml."); - } - } - - public ConfigurationBundle createBundle() - throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, - InvalidKeySpecException { - this.validate(); - KeyStore identity = KeyStore.getInstance(KeyStore.getDefaultType()); - KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); - identity.load(null, null); - trustStore.load(null, null); - for (Map.Entry datacenterEntry : datacenters.entrySet()) { - ScyllaCloudDatacenter datacenter = datacenterEntry.getValue(); - InputStream certificateDataStream; - if (datacenter.getCertificateAuthorityData() != null) { - certificateDataStream = new ByteArrayInputStream(datacenter.getCertificateAuthorityData()); - } else if (datacenter.getCertificateAuthorityPath() != null) { - certificateDataStream = new FileInputStream(datacenter.getCertificateAuthorityPath()); - } else { - // impossible - throw new IllegalStateException( - "Neither CertificateAuthorityPath nor CertificateAuthorityData are set in this Datacenter object. " - + "Validation should have prevented this."); - } - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - Certificate cert = cf.generateCertificate(certificateDataStream); - trustStore.setCertificateEntry(datacenterEntry.getKey(), cert); - } - - for (Map.Entry authInfoEntry : authInfos.entrySet()) { - ScyllaCloudAuthInfo authInfo = authInfoEntry.getValue(); - InputStream certificateDataStream; - String keyString; - - if (authInfo.getClientCertificateData() != null) { - certificateDataStream = new ByteArrayInputStream(authInfo.getClientCertificateData()); - } else if (authInfo.getClientCertificatePath() != null) { - certificateDataStream = new FileInputStream(authInfo.getClientCertificatePath()); - } else { - // impossible - throw new RuntimeException( - "Neither CertificateAuthorityPath nor CertificateAuthorityData are set in this AuthInfo object. " - + "Validation should have prevented this."); - } - - if (authInfo.getClientKeyData() != null) { - keyString = new String(authInfo.getClientKeyData()); - } else if (authInfo.getClientKeyPath() != null) { - BufferedReader br = new BufferedReader(new FileReader(authInfo.getClientKeyPath())); - StringBuilder sb = new StringBuilder(); - String line = br.readLine(); - while (line != null) { - sb.append(line); - line = br.readLine(); - } - keyString = sb.toString(); - } else { - // impossible - throw new RuntimeException( - "Neither ClientKeyData nor ClientKeyPath are set in this AuthInfo object. " - + "Validation should have prevented this."); - } - - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - Certificate cert = cf.generateCertificate(certificateDataStream); - - Certificate[] certArr = new Certificate[1]; - certArr[0] = cert; - - Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); - PEMParser pemParser = new PEMParser(new StringReader(keyString)); - JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); - Object object = pemParser.readObject(); - PrivateKey privateKey; - if (object instanceof PrivateKeyInfo) { - privateKey = converter.getPrivateKey((PrivateKeyInfo) object); - } else if (object instanceof PEMKeyPair) { - KeyPair kp = converter.getKeyPair((PEMKeyPair) object); - privateKey = kp.getPrivate(); - } else if (object == null) { - // Should not ever happen - throw new IllegalStateException( - "Error parsing authInfo " - + authInfoEntry.getKey() - + ". " - + "Somehow no objects are left in the stream. Is passed Client Key empty?"); - } else { - throw new InvalidKeySpecException( - "Error parsing authInfo " - + authInfoEntry.getKey() - + ". " - + "Make sure provided key signature is either 'RSA PRIVATE KEY' or 'PRIVATE KEY'"); - } - - identity.setKeyEntry(authInfoEntry.getKey(), privateKey, "cassandra".toCharArray(), certArr); - } - - return new ConfigurationBundle(identity, trustStore); - } - - public ScyllaCloudDatacenter getCurrentDatacenter() { - return datacenters.get(getCurrentContext().getDatacenterName()); - } - - public ScyllaCloudAuthInfo getCurrentAuthInfo() { - return authInfos.get(getCurrentContext().getAuthInfoName()); - } - - public String getKind() { - return kind; - } - - public String getApiVersion() { - return apiVersion; - } - - public Map getDatacenters() { - return datacenters; - } - - public Map getAuthInfos() { - return authInfos; - } - - public Map getContexts() { - return contexts; - } - - public ScyllaCloudContext getCurrentContext() { - return contexts.get(currentContext); - } - - public Parameters getParameters() { - return parameters; - } -} diff --git a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudContext.java b/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudContext.java deleted file mode 100644 index 5fe96b8659c..00000000000 --- a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudContext.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2022 ScyllaDB - */ -package com.datastax.driver.core; - -import com.fasterxml.jackson.annotation.JsonProperty; - -class ScyllaCloudContext { - private final String datacenterName; - private final String authInfoName; - - public ScyllaCloudContext( - @JsonProperty(value = "datacenterName", required = true) String datacenterName, - @JsonProperty(value = "authInfoName", required = true) String authInfoName) { - this.datacenterName = datacenterName; - this.authInfoName = authInfoName; - } - - public String getDatacenterName() { - return datacenterName; - } - - public String getAuthInfoName() { - return authInfoName; - } -} diff --git a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudDatacenter.java b/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudDatacenter.java deleted file mode 100644 index 7cb1e0841c6..00000000000 --- a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudDatacenter.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2022 ScyllaDB - */ -package com.datastax.driver.core; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.collect.ImmutableList; -import com.google.common.net.HostAndPort; -import java.io.File; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; - -class ScyllaCloudDatacenter { - private final String certificateAuthorityPath; - private final byte[] certificateAuthorityData; - private final String server; - private final String tlsServerName; - private final String nodeDomain; - private final String proxyURL; - private final boolean insecureSkipTlsVerify; - - // Full hostname has limit of 255 chars. - // Host UUID takes 32 chars for hex digits and 4 dashes. Additional 1 is for separator dot before - // nodeDomain - private static final int NODE_DOMAIN_MAX_LENGTH = 255 - 32 - 4 - 1; - - @JsonCreator - public ScyllaCloudDatacenter( - @JsonProperty(value = "certificateAuthorityPath") String certificateAuthorityPath, - @JsonProperty(value = "certificateAuthorityData") byte[] certificateAuthorityData, - @JsonProperty(value = "server") String server, - @JsonProperty(value = "tlsServerName") String tlsServerName, - @JsonProperty(value = "nodeDomain") String nodeDomain, - @JsonProperty(value = "proxyURL") String proxyURL, - @JsonProperty(value = "insecureSkipTlsVerify", defaultValue = "false") - boolean insecureSkipTlsVerify) { - this.certificateAuthorityPath = certificateAuthorityPath; - this.certificateAuthorityData = certificateAuthorityData; - this.server = server; - this.tlsServerName = tlsServerName; - this.nodeDomain = nodeDomain; - this.proxyURL = proxyURL; - this.insecureSkipTlsVerify = insecureSkipTlsVerify; - } - - public void validate() { - if (certificateAuthorityData == null) { - if (certificateAuthorityPath == null) { - throw new IllegalArgumentException( - "Either certificateAuthorityData or certificateAuthorityPath must be provided for datacenter description."); - } - File file = new File(certificateAuthorityPath); - if (!file.canRead()) { - throw new IllegalArgumentException( - "Cannot read file at given certificateAuthorityPath (" - + certificateAuthorityPath - + ")."); - } - } - validateServer(); - validateNodeDomain(); - } - - public String getCertificateAuthorityPath() { - return certificateAuthorityPath; - } - - public byte[] getCertificateAuthorityData() { - return certificateAuthorityData; - } - - public InetSocketAddress getServer() { - HostAndPort parsedServer = HostAndPort.fromString(server); - return InetSocketAddress.createUnresolved( - GuavaCompatibility.INSTANCE.getHost(parsedServer), parsedServer.getPort()); - } - - public String getNodeDomain() { - return nodeDomain; - } - - public String getTlsServerName() { - return tlsServerName; - } - - public String getProxyURL() { - return proxyURL; - } - - public boolean isInsecureSkipTlsVerify() { - return insecureSkipTlsVerify; - } - - // Using parts relevant to hostnames as we're dealing with a part of hostname - // RFC-1123 Section 2.1 and RFC-952 1. - private void validateNodeDomain() { - if (nodeDomain == null || nodeDomain.length() == 0) { - throw new IllegalArgumentException( - "nodeDomain property is required in datacenter description."); - } else { - // M - if (nodeDomain.length() > NODE_DOMAIN_MAX_LENGTH) { - // Should be shorter because it is not the whole hostname - throw new IllegalArgumentException( - "Subdomain name too long (max " + NODE_DOMAIN_MAX_LENGTH + "): " + nodeDomain); - } - if (nodeDomain.contains(" ")) { - throw new IllegalArgumentException( - "nodeDomain '" + nodeDomain + "' cannot contain spaces."); - } - if (nodeDomain.startsWith(".") || nodeDomain.endsWith(".")) { - throw new IllegalArgumentException( - "nodeDomain '" + nodeDomain + "' cannot start or end with a dot."); - } - if (nodeDomain.endsWith("-")) { - throw new IllegalArgumentException( - "nodeDomain '" + nodeDomain + "' cannot end with a minus sign."); - } - } - - List components = ImmutableList.copyOf(nodeDomain.split("\\.")); - for (String component : components) { - if (component.length() == 0) { - throw new IllegalArgumentException( - "nodeDomain '" + nodeDomain + "' cannot have empty components between dots."); - } - - for (int index = 0; index < component.length(); index++) { - if (!Character.isLetterOrDigit(component.charAt(index))) { - if (component.charAt(index) == '-') { - if (index == 0 || index == component.length() - 1) { - throw new IllegalArgumentException( - "nodeDomain '" - + nodeDomain - + "' components can have minus sign only as interior character: " - + component.charAt(index)); - } - } else { - throw new IllegalArgumentException( - "nodeDomain '" - + nodeDomain - + "' contains illegal character: " - + component.charAt(index)); - } - } - } - } - } - - private void validateServer() { - if (server == null) { - throw new IllegalArgumentException("server property is required in datacenter description."); - } else { - try { - // Property 'server' is not a true URL because it does not contain protocol prefix - // We're adding prefix just to satisfy that part of validation - URL url = new URL("http://" + server); - if (url.getPort() == -1) { - throw new IllegalArgumentException( - "server property '" + server + "' does not contain a port."); - } - } catch (MalformedURLException e) { - throw new IllegalArgumentException( - "server property '" + server + "' is not a valid URL", e); - } - } - } -} diff --git a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudSniEndPointFactory.java b/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudSniEndPointFactory.java deleted file mode 100644 index 81a009b4a05..00000000000 --- a/driver-core/src/main/java/com/datastax/driver/core/ScyllaCloudSniEndPointFactory.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright DataStax, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Copyright (C) 2022 ScyllaDB - * - * Modified by ScyllaDB - */ -package com.datastax.driver.core; - -import java.net.InetSocketAddress; -import java.util.UUID; - -class ScyllaCloudSniEndPointFactory implements EndPointFactory { - private final String nodeDomain; - - private final InetSocketAddress proxy; - - public ScyllaCloudSniEndPointFactory(InetSocketAddress proxy, String nodeDomain) { - this.proxy = proxy; - this.nodeDomain = nodeDomain; - } - - @Override - public void init(Cluster cluster) {} - - @Override - public EndPoint create(Row row) { - UUID host_id = row.getUUID("host_id"); - String sni = host_id.toString() + "." + nodeDomain; - return new SniEndPoint(proxy, sni); - } -} diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java b/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java index 8a91c6fb1c1..ebc199ec4e0 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMAccess.java @@ -88,9 +88,6 @@ enum Workload { /** @return The binary port for this CCM cluster. */ int getBinaryPort(); - /** @return The SNI proxy port for this CCM cluster. */ - int getSniPort(); - /** Signals that logs for this CCM cluster should be kept after the cluster is stopped. */ void setKeepLogs(boolean keepLogs); diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java b/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java index de1867dea6c..344678c8149 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMBridge.java @@ -388,8 +388,6 @@ private static VersionNumber parseScyllaInputVersion(String versionString) { private final int binaryPort; - private final int sniPort; - private final String ipPrefix; private final File ccmDir; @@ -400,8 +398,6 @@ private static VersionNumber parseScyllaInputVersion(String versionString) { private final String jvmArgs; - private final boolean startSniProxy; - private boolean keepLogs = false; private boolean started = false; @@ -421,10 +417,8 @@ protected CCMBridge( int storagePort, int thriftPort, int binaryPort, - int sniPort, int[] jmxPorts, String jvmArgs, - boolean startSniProxy, int[] nodes) { this.clusterName = clusterName; @@ -435,11 +429,9 @@ protected CCMBridge( this.storagePort = storagePort; this.thriftPort = thriftPort; this.binaryPort = binaryPort; - this.sniPort = sniPort; this.isDSE = dseVersion != null; this.isScylla = (getGlobalScyllaVersion() != null); this.jvmArgs = jvmArgs; - this.startSniProxy = startSniProxy; this.nodes = nodes; this.ccmDir = Files.createTempDir(); this.jmxPorts = jmxPorts; @@ -545,11 +537,6 @@ public int getBinaryPort() { return binaryPort; } - @Override - public int getSniPort() { - return sniPort; - } - @Override public void setKeepLogs(boolean keepLogs) { this.keepLogs = keepLogs; @@ -615,10 +602,6 @@ public synchronized void start() { if (isWindows() && this.cassandraVersion.compareTo(VersionNumber.parse("2.2.4")) >= 0) { cmd += " --quiet-windows"; } - if (startSniProxy) { - cmd += " --sni-proxy"; - cmd += " --sni-port " + sniPort; - } execute(cmd); // Wait for binary interface on each node. @@ -1022,7 +1005,6 @@ public static class Builder { private boolean start = true; private boolean dse = isDse(); private boolean scylla = GLOBAL_SCYLLA_VERSION_NUMBER != null; - private boolean startSniProxy = false; private VersionNumber version = null; private final Set createOptions = new LinkedHashSet(); private final Set jvmArgs = new LinkedHashSet(); @@ -1055,11 +1037,6 @@ public Builder withoutNodes() { return withNodes(); } - public Builder withSniProxy() { - this.startSniProxy = true; - return this; - } - /** * Builder takes care of naming and numbering clusters on its own. Use if you really need a * specific name @@ -1233,8 +1210,6 @@ public CCMBridge build() { int binaryPort = Integer.parseInt(cassandraConfiguration.get("native_transport_port").toString()); - int sniPort = TestUtils.findAvailablePort(); - // Copy any supplied jmx ports over, and find available ports for the rest int numNodes = 0; for (int i : nodes) { @@ -1282,10 +1257,8 @@ public CCMBridge build() { storagePort, thriftPort, binaryPort, - sniPort, generatedJmxPorts, joinJvmArgs(), - startSniProxy, nodes); Runtime.getRuntime() @@ -1496,7 +1469,6 @@ public boolean equals(Object o) { return false; if (!createOptions.equals(builder.createOptions)) return false; if (!jvmArgs.equals(builder.jvmArgs)) return false; - if (startSniProxy != builder.startSniProxy) return false; if (!cassandraConfiguration.equals(builder.cassandraConfiguration)) return false; if (!dseConfiguration.equals(builder.dseConfiguration)) return false; return workloads.equals(builder.workloads); @@ -1511,7 +1483,6 @@ public int hashCode() { result = 31 * result + (version != null ? version.hashCode() : 0); result = 31 * result + createOptions.hashCode(); result = 31 * result + jvmArgs.hashCode(); - result = 31 * result + (startSniProxy ? 1 : 0); result = 31 * result + cassandraConfiguration.hashCode(); result = 31 * result + dseConfiguration.hashCode(); result = 31 * result + workloads.hashCode(); diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java b/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java index 254e2cae12c..d7c1a5368f2 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMCache.java @@ -104,11 +104,6 @@ public int getBinaryPort() { return ccm.getBinaryPort(); } - @Override - public int getSniPort() { - return ccm.getSniPort(); - } - @Override public void setKeepLogs(boolean keepLogs) { ccm.setKeepLogs(keepLogs); diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMConfig.java b/driver-core/src/test/java/com/datastax/driver/core/CCMConfig.java index ef1e076e1a3..d43b39db95b 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMConfig.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMConfig.java @@ -215,8 +215,6 @@ final class Undefined {} */ boolean[] createKeyspace() default {}; - boolean[] startSniProxy() default {}; - /** * Returns {@code true} if the test class or the test method alters the CCM cluster, e.g. by * adding or removing nodes, in which case, it should not be reused after the test is finished. diff --git a/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java b/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java index 496b3533692..d679e98bb4f 100644 --- a/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java +++ b/driver-core/src/test/java/com/datastax/driver/core/CCMTestsSupport.java @@ -160,11 +160,6 @@ public int getBinaryPort() { return delegate.getBinaryPort(); } - @Override - public int getSniPort() { - return delegate.getSniPort(); - } - @Override public void setKeepLogs(boolean keepLogs) { delegate.setKeepLogs(keepLogs); @@ -495,14 +490,6 @@ private boolean dirtiesContext() { return false; } - @SuppressWarnings("SimplifiableIfStatement") - private boolean startSniProxy() { - for (CCMConfig ann : annotations) { - if (ann != null && ann.startSniProxy().length > 0) return ann.startSniProxy()[0]; - } - return false; - } - private CCMBridge.Builder ccmBuilder(Object testInstance) throws Exception { if (ccmBuilder == null) { ccmBuilder = ccmProvider(testInstance); @@ -520,7 +507,6 @@ private CCMBridge.Builder ccmBuilder(Object testInstance) throws Exception { if (dse != null) ccmBuilder.withDSE(dse); if (ssl()) ccmBuilder.withSSL(); if (auth()) ccmBuilder.withAuth(); - if (startSniProxy()) ccmBuilder.withSniProxy(); for (Map.Entry entry : config().entrySet()) { ccmBuilder.withCassandraConfiguration(entry.getKey(), entry.getValue()); } @@ -762,30 +748,6 @@ public Cluster.Builder createClusterBuilderNoDebouncing() { return createClusterBuilder().withQueryOptions(TestUtils.nonDebouncingQueryOptions()); } - /** - * Returns the cluster builder to test against Scylla Cloud (sniProxy enabled). - * - *

This implementation returns a vanilla builder with contact points and port that match - * datacenter description in CCM generated yaml configuration file. This configuration may contain - * domain names that cannot be resolved on local machine, therefore we overwrite EndPointFactory - * afterwards and add sniProxy contact point using raw ip addresses (with ports from configuration - * file). It's not required to call {@link Cluster.Builder#addContactPointsWithPorts}, it will be - * done automatically. - * - * @return The cluster builder to use for the tests. - */ - public Cluster.Builder createClusterBuilderScyllaCloud() throws IOException { - assert ccmTestConfig.startSniProxy(); - Cluster.Builder builder = Cluster.builder(); - - File ccmdir = ccm.getCcmDir(); - File clusterFile = new File(ccmdir, ccm.getClusterName()); - File yamlFile = new File(clusterFile, "config_data.yaml"); - - builder.withScyllaCloudConnectionConfig(yamlFile); - return builder; - } - /** * Configures the builder with contact points and port that match the running CCM cluster. * Therefore it's not required to call {@link Cluster.Builder#addContactPointsWithPorts}, it will diff --git a/driver-core/src/test/java/com/datastax/driver/core/CloudConfigYamlParsingTest.java b/driver-core/src/test/java/com/datastax/driver/core/CloudConfigYamlParsingTest.java deleted file mode 100644 index 69e5123ca9f..00000000000 --- a/driver-core/src/test/java/com/datastax/driver/core/CloudConfigYamlParsingTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2022 ScyllaDB - */ -package com.datastax.driver.core; - -import java.io.IOException; -import java.net.URL; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.spec.InvalidKeySpecException; -import org.testng.annotations.Test; - -public class CloudConfigYamlParsingTest { - @Test(groups = "short") - public void read_simple_config_and_create_bundle() - throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, - InvalidKeySpecException { - final String CONFIG_PATH = "/scylla_cloud/testConf.yaml"; - URL url = getClass().getResource(CONFIG_PATH); - ScyllaCloudConnectionConfig scyllaCloudConnectionConfig = - ScyllaCloudConnectionConfig.fromInputStream(url.openStream()); - ConfigurationBundle bundle = scyllaCloudConnectionConfig.createBundle(); - } - - @Test( - groups = {"short"}, - expectedExceptions = IllegalArgumentException.class) - public void read_incomplete_config() throws IOException { - // This config does not contain certificates which are required - final String CONFIG_PATH = "/scylla_cloud/config_w_missing_data.yaml"; - URL url = getClass().getResource(CONFIG_PATH); - ScyllaCloudConnectionConfig scyllaCloudConnectionConfig = - ScyllaCloudConnectionConfig.fromInputStream(url.openStream()); - } -} diff --git a/driver-core/src/test/java/com/datastax/driver/core/ScyllaSniProxyTest.java b/driver-core/src/test/java/com/datastax/driver/core/ScyllaSniProxyTest.java deleted file mode 100644 index 32c56c0d819..00000000000 --- a/driver-core/src/test/java/com/datastax/driver/core/ScyllaSniProxyTest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2022 ScyllaDB - */ -package com.datastax.driver.core; - -import static com.datastax.driver.core.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.atMost; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import com.datastax.driver.core.utils.ScyllaOnly; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Set; -import java.util.TreeSet; -import java.util.UUID; -import org.testng.annotations.Test; - -@CreateCCM(CreateCCM.TestMode.PER_METHOD) -@ScyllaOnly -public class ScyllaSniProxyTest extends CCMTestsSupport { - - private void test_ccm_cluster(int testNodes) { - ccm().setKeepLogs(true); - Cluster c = cluster().init(); - Session s = c.connect(); - TestUtils.waitForUp(TestUtils.ipOfNode(1), c); - - Collection hosts = s.getState().getConnectedHosts(); - assertThat(hosts.size()).isEqualTo(testNodes); - Set uuidSet = new TreeSet(); - for (Host host : hosts) { - uuidSet.add(host.getHostId()); - assertThat(host.getEndPoint().resolve().getAddress()).isEqualTo(TestUtils.addressOfNode(1)); - assertThat(host.getEndPoint().resolve().getPort()).isEqualTo(ccm().getSniPort()); - assertThat(host.getEndPoint().toString()).doesNotContain("any."); - } - assertThat(uuidSet.size()).isEqualTo(testNodes); - ((SessionManager) s).cluster.manager.controlConnection.triggerReconnect(); - - SchemaChangeListener listener = mock(SchemaChangeListenerBase.class); - final ArrayList keyspaceMismatches = new ArrayList(); - final ArrayList tableMismatches = new ArrayList(); - - SchemaChangeListener assertingListener = - new SchemaChangeListenerBase() { - @Override - public void onKeyspaceAdded(KeyspaceMetadata keyspace) { - if (!keyspace.getName().equals("testks")) { - keyspaceMismatches.add(keyspace.getName()); - } - } - - @Override - public void onTableAdded(TableMetadata table) { - if (!table.getName().equals("testtab")) { - tableMismatches.add(table.getName()); - } - } - }; - - c.register(listener); - c.register(assertingListener); - - s.execute(String.format(TestUtils.CREATE_KEYSPACE_SIMPLE_FORMAT, "testks", testNodes)); - s.execute("CREATE TABLE testks.testtab (a int PRIMARY KEY, b int);"); - - // Sometimes (probably due to reconnection) both events can be read twice - // assertingListener ensures we deal with the same keyspace and table - try { - Thread.sleep(1000); - } catch (InterruptedException ignored) { - } - verify(listener, atLeast(1)).onTableAdded(any(TableMetadata.class)); - verify(listener, atMost(2)).onTableAdded(any(TableMetadata.class)); - verify(listener, atLeast(1)).onKeyspaceAdded(any(KeyspaceMetadata.class)); - verify(listener, atMost(2)).onKeyspaceAdded(any(KeyspaceMetadata.class)); - - if (!keyspaceMismatches.isEmpty()) { - StringBuilder ksNames = new StringBuilder(); - for (String str : keyspaceMismatches) { - ksNames.append(", " + ksNames + str); - } - throw new RuntimeException( - "assertingListener registered keyspace added event with keyspaces named: [" - + ksNames.substring(2) - + "] which is not \"testks\""); - } - if (!tableMismatches.isEmpty()) { - StringBuilder tabNames = new StringBuilder(); - for (String str : tableMismatches) { - tabNames.append(", " + tabNames + str); - } - throw new RuntimeException( - "assertingListener registered table added event with tables named: [" - + tabNames.substring(2) - + "] which is not \"testtab\""); - } - - s.close(); - c.close(); - } - - @Test(groups = "short") - @CCMConfig( - startSniProxy = true, - numberOfNodes = 3, - clusterProvider = "createClusterBuilderScyllaCloud", - dirtiesContext = true) - public void test_ccm_cluster_3node() throws InterruptedException { - test_ccm_cluster(3); - } - - @Test(groups = "short") - @CCMConfig( - startSniProxy = true, - numberOfNodes = 1, - clusterProvider = "createClusterBuilderScyllaCloud", - dirtiesContext = true) - public void test_ccm_cluster_1node() throws InterruptedException { - test_ccm_cluster(1); - } -} From eb1c3154456fb1c54c351a9d1323c39c75ccc06b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20B=C4=85czkowski?= Date: Fri, 26 Sep 2025 23:48:28 +0200 Subject: [PATCH 2/2] Revert some core adjustments that were made for serverless EndPoint fields are final again in Connection and Host classes. --- clirr-ignores.xml | 10 ++++++++++ .../main/java/com/datastax/driver/core/Connection.java | 2 +- .../com/datastax/driver/core/ControlConnection.java | 7 ------- .../src/main/java/com/datastax/driver/core/Host.java | 6 +----- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/clirr-ignores.xml b/clirr-ignores.xml index f129c478423..d7ff2a7c2ad 100644 --- a/clirr-ignores.xml +++ b/clirr-ignores.xml @@ -65,6 +65,16 @@ Serverless was dropped. This code has no use anymore. + + 7002 + com/datastax/driver/core/Host + void setEndPoint(com.datastax.driver.core.EndPoint) + Originally endPoint field was made non-final to work around serverless limitations. + We're making it final again for clarity. Driver always used to treat the EndPoint as something that + does not change for given Host outside that specific case. + + + 7004 com/datastax/driver/core/Metadata diff --git a/driver-core/src/main/java/com/datastax/driver/core/Connection.java b/driver-core/src/main/java/com/datastax/driver/core/Connection.java index 67c61a47ec3..e3a886972ce 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Connection.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Connection.java @@ -127,7 +127,7 @@ enum State { volatile long maxIdleTime; - EndPoint endPoint; + final EndPoint endPoint; private final String name; private volatile Integer shardId = null; diff --git a/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java b/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java index e3d0cb51466..5988708ff09 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java +++ b/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java @@ -680,11 +680,6 @@ private static void updateInfo( } host.setHostId(row.getUUID("host_id")); host.setSchemaVersion(row.getUUID("schema_version")); - - EndPoint endPoint = cluster.configuration.getPolicies().getEndPointFactory().create(row); - if (endPoint != null) { - host.setEndPoint(endPoint); - } } private static void updateLocationInfo( @@ -816,8 +811,6 @@ private void refreshNodeListAndTokenMap( connection.endPoint); } else { updateInfo(controlHost, localRow, cluster, isInitialConnection); - connection.endPoint = controlHost.getEndPoint(); - if (metadataEnabled && factory != null) { Set tokensStr = localRow.getSet("tokens", String.class); if (!tokensStr.isEmpty()) { diff --git a/driver-core/src/main/java/com/datastax/driver/core/Host.java b/driver-core/src/main/java/com/datastax/driver/core/Host.java index 603a5dc1010..844b4db6005 100644 --- a/driver-core/src/main/java/com/datastax/driver/core/Host.java +++ b/driver-core/src/main/java/com/datastax/driver/core/Host.java @@ -43,7 +43,7 @@ public class Host { static final Logger statesLogger = LoggerFactory.getLogger(Host.class.getName() + ".STATES"); // The address we'll use to connect to the node - private EndPoint endPoint; + private final EndPoint endPoint; // The broadcast RPC address, as reported in system tables. // Note that, unlike previous versions of the driver, this address is NOT TRANSLATED. @@ -183,10 +183,6 @@ public EndPoint getEndPoint() { return endPoint; } - public void setEndPoint(EndPoint endPoint) { - this.endPoint = endPoint; - } - /** * Returns the address that the driver will use to connect to the node. *