'Multiple Keyspaces in Cassandra Springboot Spring Data while setting credentials for each keyspace
I am trying to configure cassandra for multiple keyspaces , I need to set userName and Password for cassandra, overriding session function which gives me an authentication error, even though I can find the credentials getting printed in code.
I tried with different approaches mentioned on SO, I haven't been able to figure things out while adding credentials.
I get this Authentication error
Caused by: com.datastax.oss.driver.api.core.AllNodesFailedException: Could not reach any contact point, make sure you've provided valid addresses (showing first 3 nodes, use getAllErrors() for more): Node(endPoint=10.0.213.69:9042, hostId=null, hashCode=6453355e): [com.datastax.oss.driver.api.core.auth.AuthenticationException: Authentication error on node 10.0.213.69:9042: Node 10.0.213.69:9042 requires authentication (org.apache.cassandra.auth.PasswordAuthenticator), but no authenticator configured], Node(endPoint=10.0.211.74:9042, hostId=null, hashCode=6a94c67c): [com.datastax.oss.driver.api.core.auth.AuthenticationException: Authentication error on node 10.0.211.74:9042: Node 10.0.211.74:9042 requires authentication (org.apache.cassandra.auth.PasswordAuthenticator), but no authenticator configured], Node(endPoint=10.0.208.57:9042, hostId=null, hashCode=606cad0c): [com.datastax.oss.driver.api.core.auth.AuthenticationException: Authentication error on node 10.0.208.57:9042: Node 10.0.208.57:9042 requires authentication (org.apache.cassandra.auth.PasswordAuthenticator), but no authenticator configured]
I have a base config like this
abstract class CassandraBaseConfig :
AbstractCassandraConfiguration() {
override fun getSchemaAction(): SchemaAction {
return SchemaAction.CREATE_IF_NOT_EXISTS
}
override fun getSessionBuilderConfigurer(): SessionBuilderConfigurer? {
return SessionBuilderConfigurer { sessionBuilder: CqlSessionBuilder ->
val builder: ProgrammaticDriverConfigLoaderBuilder = DefaultProgrammaticDriverConfigLoaderBuilder(
{
ConfigFactory.invalidateCaches()
ConfigFactory.defaultOverrides()
.withFallback(buildConfig())
.withFallback(ConfigFactory.defaultReference())
.resolve()
},
DefaultDriverConfigLoader.DEFAULT_ROOT_PATH
).withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(60))
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(180))
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, Duration.ofSeconds(60))
sessionBuilder.withConfigLoader(builder.build())
return@SessionBuilderConfigurer sessionBuilder
}
}
private companion object CassandraDriverOptions {
private val options: MutableMap<String, Any> = LinkedHashMap()
fun addOption(option: DriverOption, value: Any): CassandraDriverOptions {
val key = createKeyFor(option)
options[key] = value
return this
}
fun buildConfig() = ConfigFactory.parseMap(options, "Environment")
private fun createKeyFor(option: DriverOption) = "${DefaultDriverConfigLoader.DEFAULT_ROOT_PATH}.${option.path}"
}
}
And two keyspaces which I configure like this
@Configuration
@EnableCassandraRepositories(
basePackages = ["com.expediagroup.dataquality.api.repository.cassandra.egdq"],
cassandraTemplateRef = "cassandraEgdqPropertiesTemplate"
)
open class CassandraEgdqAppUser(
private val cassandraEgdqProperties: CassandraEgdqProperties
) :
CassandraBaseConfig() {
override fun getKeyspaceName() = cassandraEgdqProperties.keySpace
override fun getContactPoints() = cassandraEgdqProperties.contactPoints
override fun getPort() = cassandraEgdqProperties.portNumber
override fun getLocalDataCenter() = cassandraEgdqProperties.dataCenterName
@Bean("cassandraEgdqPropertiesSession")
open fun session(): CqlSessionFactoryBean {
val cassandraSession = super.cassandraSession()
cassandraSession.setUsername(cassandraEgdqProperties.username)
cassandraSession.setPassword(cassandraEgdqProperties.password)
return cassandraSession
}
@Bean("cassandraEgdqPropertiesTemplate")
@Throws(Exception::class)
open fun cassandraTemplate(
@Qualifier("cassandraEgdqPropertiesSession") session: CqlSessionFactoryBean
): CassandraAdminOperations {
return CassandraAdminTemplate(session.getObject(), cassandraConverter())
}
}
Second keyspace
@Configuration
@EnableCassandraRepositories(
basePackages = ["com.expediagroup.dataquality.api.repository.cassandra.egdqprofiles"],
cassandraTemplateRef = "cassandraPropertiesTemplate"
)
open class CassandraEgdqProfilesAppUser(
private val cassandraProperties: CassandraProperties
) : CassandraBaseConfig() {
override fun getKeyspaceName() = cassandraProperties.keySpace
override fun getContactPoints() = cassandraProperties.contactPoints
override fun getPort() = cassandraProperties.portNumber
override fun getLocalDataCenter() = cassandraProperties.dataCenterName
@Bean("cassandraPropertiesSession")
// @Primary
open fun session(): CqlSessionFactoryBean {
val cassandraSession = super.cassandraSession()
cassandraSession.setUsername(cassandraProperties.username)
cassandraSession.setPassword(cassandraProperties.password)
return cassandraSession
}
@Bean("cassandraPropertiesTemplate")
@Throws(Exception::class)
open fun cassandraTemplate(
@Qualifier("cassandraPropertiesSession") session: CqlSessionFactoryBean
): CassandraAdminOperations {
return CassandraAdminTemplate(session.getObject(), cassandraConverter())
}
}
Any help is appreciated.
Solution 1:[1]
To get rid of the first issue I figured I had overlapping prefixes I was using during configuration.
Next I modified session earlier using super.cassandraSession() to instead use
val session = CqlSessionFactoryBean()
session.setKeyspaceName(cassandraProperties.keySpace)
session.setContactPoints(contactPoints)
session.setPort(cassandraProperties.portNumber)
session.setUsername(cassandraProperties.username)
session.setPassword(cassandraProperties.password)
session.setLocalDatacenter(cassandraProperties.dataCenterName)
session.setSessionBuilderConfigurer { cqlSessionBuilder ->
cqlSessionBuilder.withConfigLoader(getDriverConfigs())
}
fun getDriverConfigs(cassandraProperties: CassandraProperties): DriverConfigLoader {
val driverConfigs = OptionsMap.driverDefaults()
driverConfigs.put(TypedDriverOption.REQUEST_TIMEOUT, Duration.ofMillis(cassandraProperties.requestTimeoutMs))
return DriverConfigLoader.fromMap(driverConfigs)
}
Then I needed to exclude CassandraDataAutoConfiguration in my yaml file
spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration, org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
