Изменение конфигурации Spring Data Cassandra на лету

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

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

@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 с этим классом Configuration, приложение не запускается. Это то, что отображается в консоли:

***************************
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? Если кто-то делал это раньше, можете ли вы поделиться тем же?


person kaizen    schedule 25.10.2018    source источник


Ответы (1)


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

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

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

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

  1. Создайте bean-компонент @ConfigurationProperties, который инкапсулирует ваши свойства, или, лучше, повторно используйте CassandraProperties.
  2. Повторно включите CassandraAutoConfiguration и удалите собственные компоненты MappingContext и CassandraConverter, оставив только определения Cluster и Session bean
  3. Объявите компоненты Cluster и Session по мере необходимости и заставьте их использовать @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());
    }
}
person mp911de    schedule 30.10.2018