Search code examples
javaspring-bootspring-dataspring-cloud-configspring-data-cassandra

How to set Spring Data Cassandra keyspace dynamically?


We're using Spring Boot 1.5.10 with Spring Data for Apache Cassandra and that's all working well.

We've had a new requirement coming along where we need to connect to a different keyspace while the service is up and running.

Through the use of Spring Cloud Config Server, we can easily set the value of spring.data.cassandra.keyspace-name, however, we're not certain if there's a way that we can dynamically switch (force) the service to use this new keyspace without having to restart if first?

Any ideas or suggestions?


Solution

  • Using @RefreshScope with properties/repositories doesn't work as the keyspace is bound to the Cassandra Session bean.

    Using Spring Data Cassandra 1.5 with Spring Boot 1.5 you have at least two options:

    1. Declare a @RefreshScope CassandraSessionFactoryBean, see also CassandraDataAutoConfiguration. This will interrupt all Cassandra operations upon refresh and re-create all dependant beans.
    2. Listen to RefreshScopeRefreshedEvent and change the keyspace via USE my-new-keyspace;. This approach is less invasive and doesn't interrupt running queries. You'd basically use an event listener.

      @Component
      class MySessionRefresh {
      
        private final Session session;
        private final Environment environment;
      
        // omitted constructors for brevity
      
        @EventListener
        @Order(Ordered.LOWEST_PRECEDENCE)
        public void handle(RefreshScopeRefreshedEvent event) {
      
          String keyspace = environment.getProperty("spring.data.cassandra.keyspace-name");
          session.execute("USE " + keyspace + ";");
        }
      }
      

    With Spring Data Cassandra 2, we introduced the SessionFactory abstraction providing AbstractRoutingSessionFactory for code-controlled routing of CQL/session calls.