Конфигурация Spring Data Cassandra меняется на лету - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь сделать то же самое с моим приложением.Я использую следующие версии Spring boot и Cassandra:

spring-data-cassandra - 2.0.8.RELEASE spring-boot-starter-parent - 2.0.4.RELEASE Мне нужно изменить некоторые свойства (в основном это имена хостов)) Кассандры на лету и хотят, чтобы она установила новое соединение с приложением.Для изменения конфигурации у нас есть внутреннее Cloud Config Change Management, и оно отлично работает на изменения и слушает его.Это мой класс:

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@RefreshScope
@EnableCassandraRepositories(basePackages = {"com.*.*.*.dao.repo"})
public class AppConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(AppConfig.class);

    @Value("${application['cassandraPort']}")
    private String cassandraPort;

    @Value("${application['cassandraEndpoint']}")
    private String cassandraEndpoint;

    @Value("${application['keyspaceName']}")
    private String keyspaceName;

    @Value("${application['cassandraConsistency']}")
    private String cassandraConsistency;

    @Value("${application['cassandraUserName']}")
    private String cassandraUserName;




    @Autowired
    private AppConfig appConfig;


    public AppConfig() {

        System.out.println("AppConfig Constructor");

    }




    public String getCassandraPort() {
        return cassandraPort;
    }

    public void setCassandraPort(String cassandraPort) {
        this.cassandraPort = cassandraPort;
    }

    public String getCassandraEndpoint() {
        return cassandraEndpoint;
    }

    public void setCassandraEndpoint(String cassandraEndpoint) {
        this.cassandraEndpoint = cassandraEndpoint;
    }

    public String getKeyspaceName() {
        return keyspaceName;
    }

    public void setKeyspaceName(String keyspaceName) {
        this.keyspaceName = keyspaceName;
    }

    public String getCassandraConsistency() {
        return cassandraConsistency;
    }

    public void setCassandraConsistency(String cassandraConsistency) {
        this.cassandraConsistency = cassandraConsistency;
    }

    public String getCassandraUserName() {
        return cassandraUserName;
    }

    public void setCassandraUserName(String cassandraUserName) {
        this.cassandraUserName = cassandraUserName;
    }




    @Bean
    // @RefreshScope
    public CassandraConverter converter() {
        return new MappingCassandraConverter(this.mappingContext());
    }


    @Bean
    // @RefreshScope
    public CassandraMappingContext mappingContext() {
        return new CassandraMappingContext();
    }


    @Bean
    //@RefreshScope
    public CassandraSessionFactoryBean session() {


        CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();

        session.setCluster(this.cluster().getObject());
        session.setKeyspaceName(appConfig.getKeyspaceName());
        session.setConverter(this.converter());
        session.setSchemaAction(SchemaAction.NONE);
        return session;
    }

    @Bean
    //@RefreshScope
    public CassandraClusterFactoryBean cluster() {
        CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();

        cluster.setContactPoints(appConfig.getCassandraEndpoint());
        cluster.setPort(Integer.valueOf(appConfig.getCassandraPort()));
        cluster.setUsername(appConfig.getCassandraUserName());
        cluster.setPassword("password");
        cluster.setQueryOptions(new QueryOptions().setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM));

        return cluster;
    }

}

Однако, когда я пытаюсь использовать @RefreshScope с этим классом конфигурации, приложение не запускается.Вот что он показывает в консоли:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 2 of constructor in org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration required a bean of type 'com.datastax.driver.core.Cluster' that could not be found.
    - Bean method 'cassandraCluster' not loaded because auto-configuration 'CassandraAutoConfiguration' was excluded


Action:

Consider revisiting the entries above or defining a bean of type 'com.datastax.driver.core.Cluster' in your configuration.

Есть ли некоторые рекомендации по использованию @RefreshScope с Cassandra Bean?Если кто-то сделал это раньше, вы можете поделиться тем же?

1 Ответ

0 голосов
/ 30 октября 2018

Вы смешиваете пару вещей здесь.

  1. Конфигурация содержит свойства и определения компонентов.
  2. @RefreshScope на AppConfig вызывает некоторое вмешательство в автоконфигурацию Spring Boot, и объявленные bean-компоненты не используются (поэтому вы видите Parameter 2 of constructor…).

Toочистите, мы будем максимально использовать то, что предоставляет Spring Boot, и только объявляет то, что действительно необходимо.

Для решения проблемы выполните следующие действия (на основе приведенного выше кода):

  1. Создайте bean-компонент @ConfigurationProperties, который инкапсулирует ваши свойства, или лучше, повторно используйте CassandraProperties.
  2. Повторно включите CassandraAutoConfiguration и удалите свои собственные MappingContext и CassandraConverterbean-компоненты, сохраняйте только определения Cluster и Session bean-компонентов
  3. Объявляйте Cluster и Session bean-компоненты при необходимости и заставляйте их использовать @RefreshScope.Ваш класс @Configuration должен выглядеть следующим образом:

Пример конфигурации:

@Configuration
public class MyConfig {

    @Bean(destroyMethod = "close")
    @RefreshScope
    public Cluster cassandraCluster(CassandraProperties properties) {
        Cluster.Builder builder = Cluster.builder().addContactPoints(properties.getContactPoints().toArray(new String[0]))
                .withoutJMXReporting();

        return builder.build();
    }

    @Bean(destroyMethod = "close")
    @RefreshScope
    public Session cassandraSession(CassandraProperties properties, Cluster cluster) {
        return cluster.connect(properties.getKeyspaceName());
    }
}
...