Search code examples
javaspring-bootcassandradatastax-java-driveramazon-keyspaces

How can we create two separate cassandra clusters from the same Spring Boot application?


I'm having a hard time connecting to two different clusters from a Spring Boot application. The task is to get the data from Cassandra on ec2 and insert in batches to an AWS keyspace. I am able to get the data from Cassandra on ec2.

Here I am overriding the customize method of

org.springframework.boot.autoconfigure.cassandra.ClusterBuilderCustomizer

When trying to connect to the Cassandra cluster running on ec2, things are working fine, but the requirement is to also have one more cluster to select data from Cassandra ec2 and insert into the other Cassandra cluster.

The problem is when I am overriding the customize method for creating a cluster in the AWS Keyspace, instead of a new cluster being created, the contact point gets added to a previously created cluster.

After that, I tried creating two different configurations for instantiating two different clusters. See the configuration below for cluster 1. Cluster 2 is the same; the only difference is its for 3rd party Cassandra on cloud.

@Configuration
@EnableCassandraRepositories(cassandraTemplateRef = "cassandraKeyspaceServiceTemplate")
public class CassandraClusterOneServiceConfiguration {

  @Autowired
  private CassandraOneProperties cassandraProperties;

  @Bean(name = "cluster1")
  @Primary
  public CassandraClusterFactoryBean cluster() {
    CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
    cluster.setContactPoints(cassandraProperties.getContactPoints());
    cluster.setPort(cassandraProperties.getPort());
    cluster.setSslEnabled(cassandraProperties.isSsl());
    cluster.setUsername(cassandraProperties.getUsername());
    cluster.setPassword(cassandraProperties.getPassword());
   
     final SSLContext sslContext = SSLContext.getInstance("SSL");
    

    cluster.setSslOptions(
        RemoteEndpointAwareJdkSSLOptions.builder().withSSLContext(sslContext).build());
    cluster.setJmxReportingEnabled(false);
    return cluster;
  }

  @Bean(name = "clusterContext1")
  @Primary
  public CassandraMappingContext mappingContext() {
    return new CassandraMappingContext();
  }

  @Bean(name = "clusterConverter1")
  @Primary
  public CassandraConverter converter() {
    return new MappingCassandraConverter(mappingContext());
  }

  @Bean("cassandraKeyspaceServiceSession")
  @Primary
  public CassandraSessionFactoryBean session() {

    CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
    session.setCluster(cluster().getObject());
    session.setKeyspaceName(cassandraProperties.getKeyspaceName());
    session.setConverter(converter());
    session.setSchemaAction(SchemaAction.NONE);

    return session;
  }

  @Bean("cassandraKeyspaceServiceTemplate")
  @Primary
  public CassandraOperations cassandraTemplate() {
    return new CassandraTemplate(session().getObject());
  }
}

With this code the first cluster is also setting up correctly, but the second one is giving me a NoHostAvailable exception. This seems to be a connection timeout.

How can I create two different clusters in a Spring Boot application?


Solution

  • You will want to create two classes as show in the example Managing Multiple Cassandra Sessions.

    Additionally, you can find some best practices with Amazon Keyspaces and spring boot here. https://github.com/aws-samples/amazon-keyspaces-examples/tree/main/java/datastax-v4/spring