无法使用 Spring 引导版本 2.3 连接到 Datastax Cassandra。0.Release

Not able a connect to Datastax Cassandra with Spring boot version 2.3.0.Release

我无法与 spring 引导版本 2.3.0.RELEASE 的 datastax cassandra 实例建立连接。 相同的代码在 spring boot 2.6 版本中运行良好。

运行 spring 启动应用程序时出错

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration': \
  Unsatisfied dependency expressed through constructor parameter 0; \
  nested exception is org.springframework.beans.factory.BeanCreationException: \
  Error creating bean with name 'cassandraSession' defined in class path resource [org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfiguration.class]: \
  Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: \
  Failed to instantiate [com.datastax.oss.driver.api.core.CqlSession]: \
  Factory method 'cassandraSession' threw exception; \
  nested exception is java.lang.IllegalStateException: \
    Can't use withCloudSecureConnectBundle and explicitly specify ssl configuration. They are mutually exclusive.
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:797) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:227) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE]
        ...
@Configuration
public class CassandraConfig {

    @Value("${spring.data.cassandra.contact-points}")
    private String contactPoints;

    @Value("${astra.secure-connect-bundle:none}")
    private String astraSecureConnectBundle;

    @Value("${spring.data.cassandra.username}")
    private String cassandraUsername;

    @Value("${spring.data.cassandra.password}")
    private String cassandraPassword;

    @Value("${spring.data.cassandra.port}")
    private int port;

    @Value("${spring.data.cassandra.keyspace-name}")
    private String keySpace;

    @Value("${spring.data.cassandra.local-datacenter}")
    private String dataCenter;

    @Bean
    public CqlSessionBuilderCustomizer sessionBuilderCustomizer() {
        /*
         * When using DataStax Astra, we must pass the secure connect bundle to the
         * CqlSession
         * See documentation:
         * https://docs.datastax.com/en/astra/aws/doc/dscloud/astra/dscloudUsingDrivers.
         * html
         */
        if (!astraSecureConnectBundle.equals("none")) {
            return builder -> builder
                    .withCloudSecureConnectBundle(Paths
                            .get("C:/projects/****/****/**/secure-connect-###.zip"))//zip file provided by datastax
                    .withAuthCredentials(this.cassandraUsername, this.cassandraPassword);
        } else {
            return builder -> builder
                    .addContactPoint(new InetSocketAddress(this.contactPoints, this.port))
                    .withLocalDatacenter(this.dataCenter)
                    .withAuthCredentials(this.cassandraUsername, this.cassandraUsername);
        }
    }

    @Bean
    public DriverConfigLoaderBuilderCustomizer driverConfigLoaderBuilderCustomizer() {
        /*
         * When using DataStax Astra, we do not have to pass contact points like we
         * normally would because
         * this metadata is contained in the secure connect bundle.
         */
        if (!astraSecureConnectBundle.equals("none")) {
            return builder -> builder.without(DefaultDriverOption.CONTACT_POINTS);
        }
        return builder -> builder
                .withString(DefaultDriverOption.SESSION_NAME, "spring-boot-service");
    }

}

application.properties

spring.data.cassandra.keyspace-name="KeySpaceSpace"
spring.data.cassandra.contact-points=#########.db.astra.datastax.com
spring.data.cassandra.port=32392
spring.data.cassandra.local-datacenter=dc-1
spring.data.cassandra.username=###########
spring.data.cassandra.password=###########
spring.data.cassandra.ssl=true
astra.secure-connect-bundle=${ASTRA_SECURE_CONNECT_BUNDLE:/app/astra/creds}
spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS
spring.main.allow-circular-references=true

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!-- <version>2.6.0</version> -->
        <version>2.3.1.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sample</groupId>
    <artifactId>sample-one-poc-svc</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sample-one-poc-svc</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-cassandra</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.17.1 </version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.1 </version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.datastax.oss</groupId>
            <artifactId>java-driver-query-builder</artifactId>
        </dependency>
        <dependency>
            <groupId>com.datastax.oss</groupId>
            <artifactId>java-driver-mapper-processor</artifactId>
        </dependency>
        <dependency>
            <groupId>com.datastax.oss</groupId>
            <artifactId>java-driver-mapper-runtime</artifactId>
        </dependency>
        <dependency>
            <groupId>com.datastax.oss</groupId>
            <artifactId>java-driver-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.datastax.cassandra</groupId>
            <artifactId>cassandra-driver-mapping</artifactId>
            <version>3.11.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-to-slf4j</artifactId>
            <version>2.17.1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

不知道是不是和这个问题一样 https://github.com/spring-projects/spring-boot/issues/21487 问题说它固定在 2.3.1 版本的 spring 引导中,但是如果我使用 2.3.1 版本我会得到同样的异常。

Andrew 的评论是正确的。问题是安全连接包包含连接元数据和 SSL (TLS) 凭据,因此驱动程序已经期望启用加密,这就是解析器抛出此异常的原因:

  nested exception is java.lang.IllegalStateException: \
    Can't use withCloudSecureConnectBundle and explicitly specify ssl configuration. \
    They are mutually exclusive.

您可以通过从 application.properties 中删除此行来解决冲突:

spring.data.cassandra.ssl=true

我不熟悉 Spring 代码库,所以我无法验证为什么它在 2.6 中有效,但在 2.3 中无效。

感谢 Cédric Lunven 对这个问题的指点。干杯!