Cassandra 中的多个密钥空间 Springboot Spring 为每个密钥空间设置凭据时的数据

Multiple Keyspaces in Cassandra Springboot Spring Data while setting credentials for each keyspace

我正在尝试为多个密钥空间配置 cassandra,我需要为 cassandra 设置用户名和密码,覆盖会话函数,这给我一个身份验证错误,即使我可以找到在代码中打印的凭据。

我尝试了 SO 中提到的不同方法,但在添加凭据时我无法解决问题。

我收到此身份验证错误

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]

我有这样的基本配置

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}"
  }
}

还有我这样配置的两个键空间

@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())
  }
}

第二个键空间

@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())
  }
}

感谢任何帮助。

为了解决第一个问题,我认为我在配置期间使用了重叠的前缀。

接下来,我之前使用 super.cassandraSession() 修改了会话,改为使用

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)
}

然后我需要在我的 yaml 文件中排除 CassandraDataAutoConfiguration

spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration, org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration