diff --git a/clirr-ignores.xml b/clirr-ignores.xml index ebb546569d7..d7ff2a7c2ad 100644 --- a/clirr-ignores.xml +++ b/clirr-ignores.xml @@ -37,6 +37,44 @@ 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. + + + + 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/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/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. * 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); - } -}