DATACASS-798 - Introduce CassandraDriverOptionsConfigurer and allow specifying a configuration file.
We now allow configuring a DriverConfigLoaderBuilderConfigurer and specifying a driver configuration file through AbstractSessionConfiguration to improve configuration possibilities. The DriverConfigLoaderBuilderConfigurer gets applied after applying the configuration to DriverConfigLoaderBuilder. The driver config file acts as a fallback config if the configuration property cannot be looked up from system properties or from the configuration in DriverConfigLoaderBuilder.
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -26,6 +28,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.data.cassandra.SessionFactory;
|
||||
import org.springframework.data.cassandra.core.cql.CqlTemplate;
|
||||
import org.springframework.data.cassandra.core.cql.keyspace.CreateKeyspaceSpecification;
|
||||
@@ -224,6 +227,33 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link DriverConfigLoaderBuilderConfigurer}. The configuration gets applied after applying
|
||||
* {@link System#getProperties() System Properties} config overrides and before
|
||||
* {@link #getDriverConfigurationResource() the driver config file}.
|
||||
*
|
||||
* @return the {@link DriverConfigLoaderBuilderConfigurer}; may be {@literal null}.
|
||||
* @since 3.1.2
|
||||
*/
|
||||
@Nullable
|
||||
protected DriverConfigLoaderBuilderConfigurer getDriverConfigLoaderBuilderConfigurer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Resource} pointing to a driver configuration file. The configuration file is applied after
|
||||
* applying {@link System#getProperties() System Properties} and the configuration built by this configuration class.
|
||||
*
|
||||
* @return the {@link Resource}; may be {@literal null} if none provided.
|
||||
* @since 3.1.2
|
||||
* @see <a href="https://docs.datastax.com/en/developer/java-driver/4.9/manual/core/configuration/">Driver
|
||||
* Configuration</a>
|
||||
*/
|
||||
@Nullable
|
||||
protected Resource getDriverConfigurationResource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of CQL scripts to be run on startup after {@link #getKeyspaceCreations() Keyspace creations}
|
||||
* and after initialization of the {@literal System} Keyspace.
|
||||
@@ -280,7 +310,9 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware {
|
||||
|
||||
private SessionBuilderConfigurer getSessionBuilderConfigurerWrapper() {
|
||||
|
||||
SessionBuilderConfigurer configurer = getSessionBuilderConfigurer();
|
||||
SessionBuilderConfigurer sessionConfigurer = getSessionBuilderConfigurer();
|
||||
DriverConfigLoaderBuilderConfigurer driverConfigLoaderConfigurer = getDriverConfigLoaderBuilderConfigurer();
|
||||
Resource driverConfigFile = getDriverConfigurationResource();
|
||||
|
||||
return sessionBuilder -> {
|
||||
|
||||
@@ -302,16 +334,30 @@ public abstract class AbstractSessionConfiguration implements BeanFactoryAware {
|
||||
|
||||
ConfigFactory.invalidateCaches();
|
||||
|
||||
return ConfigFactory.defaultOverrides() //
|
||||
.withFallback(options.build()) //
|
||||
.withFallback(ConfigFactory.defaultReference());
|
||||
Config config = ConfigFactory.defaultOverrides() //
|
||||
.withFallback(options.build());
|
||||
|
||||
if (driverConfigFile != null) {
|
||||
try {
|
||||
config = config
|
||||
.withFallback(ConfigFactory.parseReader(new InputStreamReader(driverConfigFile.getInputStream())));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(String.format("Cannot parse driver config file %s", driverConfigFile), e);
|
||||
}
|
||||
}
|
||||
|
||||
return config.withFallback(ConfigFactory.defaultReference());
|
||||
|
||||
}, DefaultDriverConfigLoader.DEFAULT_ROOT_PATH);
|
||||
|
||||
if (driverConfigLoaderConfigurer != null) {
|
||||
driverConfigLoaderConfigurer.configure(builder);
|
||||
}
|
||||
|
||||
sessionBuilder.withConfigLoader(builder.build());
|
||||
|
||||
if (configurer != null) {
|
||||
return configurer.configure(sessionBuilder);
|
||||
if (sessionConfigurer != null) {
|
||||
return sessionConfigurer.configure(sessionBuilder);
|
||||
}
|
||||
|
||||
return sessionBuilder;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import com.datastax.oss.driver.api.core.config.ProgrammaticDriverConfigLoaderBuilder;
|
||||
|
||||
/**
|
||||
* Callback interface that can be implemented by beans wishing to customize the
|
||||
* {@link ProgrammaticDriverConfigLoaderBuilder} via a {@link DriverConfigLoaderBuilderConfigurer} whilst retaining
|
||||
* default configuration.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 3.1.2
|
||||
*/
|
||||
public interface DriverConfigLoaderBuilderConfigurer {
|
||||
|
||||
/**
|
||||
* Customize the {@linkplain ProgrammaticDriverConfigLoaderBuilder DriverConfigLoader builder}.
|
||||
*
|
||||
* @param builder the builder to customize
|
||||
*/
|
||||
void configure(ProgrammaticDriverConfigLoaderBuilder builder);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.config;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.data.cassandra.support.CassandraConnectionProperties;
|
||||
import org.springframework.data.cassandra.test.util.CassandraExtension;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.datastax.oss.driver.api.core.CqlSession;
|
||||
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractSessionConfiguration}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@ExtendWith(CassandraExtension.class)
|
||||
class AbstractSessionConfigurationIntegrationTests {
|
||||
|
||||
@Test
|
||||
void shouldApplyDriverConfigLoaderBuilderConfigurer() {
|
||||
|
||||
MySessionConfiguration configuration = new MySessionConfiguration();
|
||||
CqlSessionFactoryBean bean = configuration.cassandraSession();
|
||||
bean.afterPropertiesSet();
|
||||
CqlSession session = bean.getObject();
|
||||
|
||||
assertThat(session.getContext().getConfig().getProfile("foo")).isNotNull();
|
||||
assertThat(session.getContext().getConfig().getProfiles()).doesNotContainKeys("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldApplyConfigurationFile() {
|
||||
|
||||
MySessionConfiguration configuration = new MySessionConfiguration();
|
||||
CqlSessionFactoryBean bean = configuration.cassandraSession();
|
||||
bean.afterPropertiesSet();
|
||||
CqlSession session = bean.getObject();
|
||||
|
||||
assertThat(session.getContext().getConfig().getProfile("oltp")).isNotNull();
|
||||
assertThat(session.getContext().getConfig().getProfiles()).doesNotContainKeys("bar");
|
||||
}
|
||||
|
||||
static class MySessionConfiguration extends AbstractSessionConfiguration {
|
||||
|
||||
@Override
|
||||
protected String getKeyspaceName() {
|
||||
return "system";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected String getLocalDataCenter() {
|
||||
return "datacenter1";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPort() {
|
||||
return new CassandraConnectionProperties().getCassandraPort();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected DriverConfigLoaderBuilderConfigurer getDriverConfigLoaderBuilderConfigurer() {
|
||||
return it -> {
|
||||
it.startProfile("foo").withString(DefaultDriverOption.SESSION_NAME, "hello-world").endProfile();
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Resource getDriverConfigurationResource() {
|
||||
return new ClassPathResource("application.conf");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,13 @@
|
||||
# This file is in HOCON format, see https://github.com/typesafehub/config/blob/master/HOCON.md.
|
||||
datastax-java-driver {
|
||||
|
||||
profiles {
|
||||
oltp {
|
||||
basic.request.timeout = 100 milliseconds
|
||||
basic.request.consistency = ONE
|
||||
}
|
||||
}
|
||||
|
||||
basic.load-balancing-policy {
|
||||
class = DcInferringLoadBalancingPolicy
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user