cassandradatastax-java-driverspring-data-cassandraspring-boot-starter-parent

Spring Boot app can't connect to Cassandra cluster, driver returning "AllNodesFailedException: Could not reach any contact point"


i've updated my spring-boot to v3.0.0 and spring-data-cassandra to v4.0.0 which resulted in unable to connect to cassandra cluster which is deployed in stg env and runs on IPv6 address having different datacenter rather DC1

i've added a config file which accepts localDC programatically

   `@Bean(destroyMethod = "close")
    public CqlSession session() {
        CqlSession session = CqlSession.builder() 
            .addContactPoint(InetSocketAddress.createUnresolved("[240b:c0e0:1xx:xxx8:xxxx:x:x:x]", port))
                .withConfigLoader(
                        DriverConfigLoader.programmaticBuilder()
                                .withString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter)                              
                                .withString(DefaultDriverOption.AUTH_PROVIDER_PASSWORD,password)
                                .withString(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT,"10s")
                                .withString(DefaultDriverOption.CONNECTION_CONNECT_TIMEOUT, "20s")
                                .withString(DefaultDriverOption.REQUEST_TIMEOUT, "20s")
                                .withString(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, "20s")
                                .withString(DefaultDriverOption.SESSION_KEYSPACE,keyspace)
                                .build())
                //.addContactPoint(InetSocketAddress.createUnresolved(InetAddress.getByName(contactPoints).getHostName(), port))
                .build();
        }
        return session;`

and this is my application.yml file

spring:
  data:
    cassandra:
      keyspace-name: xxx
      contact-points: [xxxx:xxxx:xxxx:xxx:xxx:xxx]
      port: xxx
      local-datacenter: xxxx
      use-dc-aware: true
      username: xxxxx
      password: xxxxx
      ssl: true
      SchemaAction: CREATE_IF_NOT_EXISTS

So locally I was able to connect to cassandra (by default it is pointing to localhost) , but in stg env my appplication is not able to connect to that cluster

logs in my stg env

caused by: com.datastax.oss.driver.api.core.AllNodesFailedException: Could not reach any contact point, make sure you've provided valid addresses (showing first 1 nodes, use getAllErrors() for more): Node (endPoint=/[240b:cOe0:102:xxxx:xxxx:x:x:x]:3xxx,hostId-null,hashCode=4e9ba6a8):[com.datastax.oss.driver.api.core.connection.ConnectionInitException:[s0|controllid:0x984419ed,L:/[240b:cOe0:102:5dd7: xxxx:x:x:xxx]:4xxx - R:/[240b:c0e0:102:xxxx:xxxx:x:x:x]:3xxx] Protocol initialization request, step 1 (OPTIONS: unexpected tarlure com.datastax.oss.driver.apt.core.connection.closedconnectiontxception: Lost connection to remote peer)]


Solution

  • added the certificate in my spring application

        public CqlSession session() throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
             Resource resource = new ClassPathResource("root.crt");
                    InputStream inputStream = resource.getInputStream();
                    CertificateFactory cf = CertificateFactory.getInstance("X.509");
                    Certificate cert = cf.generateCertificate(inputStream);
                    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
                    keyStore.load(null);
                    keyStore.setCertificateEntry("ca", cert);
                    trustManagerFactory.init(keyStore);
                    SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
                    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
                    return CqlSession.builder()
                            .withSslContext(sslContext)
                            .addContactPoint(new InetSocketAddress(contactPoints,port))
                            .withAuthCredentials(username, password)
                            .withLocalDatacenter(localDatacenter)
                            .withKeyspace(keyspace)
                            .build();
    }
    

    so added the cert file in the configuration file of the cqlsession builder and this helped me in connecting to the remote cassandra cluster