I am trying to connect to Cassandra from my Spring boot application using spring-boot-data-cassandra:3.1.3 and spring-boot-autoconfigure:2.4.2.
My Cassandra cluster is enabled with ssl at Cassandra side. So when I am auto configuring Cassandra connections with ssl enabled (by setting spring.data.cassandra.ssl=true) then Default SSL context is created for me, but i need to provide my truststore path and truststore password to initialize SSLContext. There is no properties provided at data-cassandra like the one provided for kafka(spring.kafka.ssl.truststore-location= # Location of the trust store file. spring.kafka.ssl.truststore-password= # Store password for the trust store file.), so is there any way to provide truststore file location and password to AutoConfigure my Cassandra configuration or to override default SSLContext created for the specified versions.
Comment From: wilkinsona
You can use a CqlSessionBuilderCustomizer to configure the CqlSessionBuilder's SSLContext to meet your needs. I think it makes sense to add some properties for configuring a trust store and password. That could be done as part of #17589 or here with a specific focus on Cassandra. Let's see what the rest of the team thinks.
Comment From: suvanakar
Thanks for the response @wilkinsona. But I strongly feel that the properties for such configurations should be provided to have a unified solution like we have for kafka for instance. Let's wait for the team to share their views.
Comment From: mbhave
17589 might mean that we unify ssl properties that we've got across the board to provide more cohesive support. It looks like it might be Spring Boot 3.0 work. We probably wouldn't want to add properties right now knowing they could go away in an upcoming release. Given that there is a customizer available, I think we should wait until we decide what to do with #17589.
Comment From: suvanakar
@mbhave @wilkinsona I tried updating the SSLContext using CqlSessionBuilderCustomizer by creating a @Bean for the same like below. But this one is not working.
@Bean
public CqlSessionBuilderCustomizer cqlSessionBuilderCustomizer() {
return cqlSessionBuilder -> cqlSessionBuilder
.withSslContext(getCustomSslContext());
}
It is still taking the default SSLContext only. Any idea why is that?
Comment From: wilkinsona
I can't explain why that would happen. CqlSessionBuilderCustomizer beans should be applied after the auto-configured has configured SSL, allowing them to override whatever the auto-configuration has done. If you provide a small sample that illustrates what you're trying to do, we can take a closer look.
Comment From: mkumar87
@mbhave @wilkinsona I tried updating the SSLContext using CqlSessionBuilderCustomizer by creating a
@Beanfor the same like below. But this one is not working.
@Bean public CqlSessionBuilderCustomizer cqlSessionBuilderCustomizer() { return cqlSessionBuilder -> cqlSessionBuilder .withSslContext(getCustomSslContext()); }It is still taking the default SSLContext only. Any idea why is that?
I'm also facing similar issue and stuck here.. While debugging, I dont see the bean is initialized and getCustomSSLContext() is called at all
Comment From: mkumar87
I see the CqlSessionBuilderCustomizer.customize is invoked only by CassandraAutoConfiguration.. Do we need to extend that class from my config? Our project uses reactor framework, where I have extended my config file with AbstractReactiveCassandraConfiguration..
Comment From: snicoll
If you are extending from AbstractReactiveCassandraConfiguration, this effectively creates the CqlSession and the Spring Boot auto-configuration backs off so the customizer will not be applied. You can figure this out by yourself running Spring Boot in debug mode (add debug=true in application.properties) and look at the auto-configuration report.
This hierarchy has SessionBuilderConfigurer for the same purpose. You can override getSessionBuilderConfigurer in your sub-class and move that code there.
Paging @mp911de for extra visibility. Wondering what we could do to make that more obvious considering there are two ways to configure Cassandra when Spring Boot is used.
Comment From: mp911de
Multiple approaches to configure a data integration apply to JDBC, MongoDB, R2DBC, Cassandra, Couchbase, Neo4j, and Elasticsearch. Let's discuss that on an independent ticket to not dilute the discussion of this one.
Comment From: wilkinsona
I'm not sure that it's even specific to Spring Data. The same applies to WebMvc, for example, where you could sub-class WebMvcConfigurationSupport or use @EnableWebMvc and switch off Boot's auto-configuration. We've seen people do that unintentionally as well. Perhaps we need to consider https://github.com/spring-projects/spring-boot/issues/6647 again, but with a broader scope? Or maybe we need some better documentation to caution against using AbstractReactiveCassandraConfiguration as we already do for @EnableWebMvc and @EnableWebFlux.
Comment From: mkumar87
If you are extending from
AbstractReactiveCassandraConfiguration, this effectively creates theCqlSessionand the Spring Boot auto-configuration backs off so the customizer will not be applied. You can figure this out by yourself running Spring Boot in debug mode (adddebug=trueinapplication.properties) and look at the auto-configuration report.This hierarchy has
SessionBuilderConfigurerfor the same purpose. You can overridegetSessionBuilderConfigurerin your sub-class and move that code there.Paging @mp911de for extra visibility. Wondering what we could do to make that more obvious considering there are two ways to configure Cassandra when Spring Boot is used.
Awesome.. Thanks for the insight @snicoll .. I was banging my head with the same issue and now I know whats happening.. Yes you are right.. I have see SessionBuilder is the only option which can overriden. Would you mind let me know how i can achieve that.. I did have an option to override the getter, but I couldn't create the SessionBuilderConfigurer correctly.
Comment From: wilkinsona
@mkumar87 If you want to continue using AbstractReactiveCassandraConfiguration, you can configure the SSL context with something like this:
@Configuration(proxyBeanMethods = false)
class CustomReactiveCassandraConfiguration extends AbstractReactiveCassandraConfiguration {
@Override
protected String getKeyspaceName() {
return "example";
}
@Override
protected SessionBuilderConfigurer getSessionBuilderConfigurer() {
return (cqlSessionBuilder) -> {
SSLContext sslContext = createSslContext();
return cqlSessionBuilder.withSslContext(sslContext);
};
}
}
You'd then implement a createSslContext() method that creates an SSLContext that meets your needs.
Comment From: mkumar87
Perfect. I just made this working :-) .. I'm testing this right now! 🤞 .. Thank you for the help!
Comment From: ajith428
Are SSL trust-store props for Cassandra or unifying SSL configuration is completed in spring-boot 3.0.0-M3?
Comment From: snicoll
@ajith428 this issue is still open, so I am afraid not.