Skip to content

Commit b874071

Browse files
committed
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.
1 parent 2ecc51c commit b874071

File tree

4 files changed

+193
-6
lines changed

4 files changed

+193
-6
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/config/AbstractSessionConfiguration.java

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.cassandra.config;
1717

18+
import java.io.IOException;
19+
import java.io.InputStreamReader;
1820
import java.util.Collections;
1921
import java.util.LinkedHashMap;
2022
import java.util.List;
@@ -26,6 +28,7 @@
2628
import org.springframework.beans.factory.ObjectProvider;
2729
import org.springframework.context.annotation.Bean;
2830
import org.springframework.context.annotation.Configuration;
31+
import org.springframework.core.io.Resource;
2932
import org.springframework.data.cassandra.SessionFactory;
3033
import org.springframework.data.cassandra.core.cql.CqlTemplate;
3134
import org.springframework.data.cassandra.core.cql.keyspace.CreateKeyspaceSpecification;
@@ -224,6 +227,33 @@ protected SessionBuilderConfigurer getSessionBuilderConfigurer() {
224227
return null;
225228
}
226229

230+
/**
231+
* Returns the {@link DriverConfigLoaderBuilderConfigurer}. The configuration gets applied after applying
232+
* {@link System#getProperties() System Properties} config overrides and before
233+
* {@link #getDriverConfigurationResource() the driver config file}.
234+
*
235+
* @return the {@link DriverConfigLoaderBuilderConfigurer}; may be {@literal null}.
236+
* @since 3.1.2
237+
*/
238+
@Nullable
239+
protected DriverConfigLoaderBuilderConfigurer getDriverConfigLoaderBuilderConfigurer() {
240+
return null;
241+
}
242+
243+
/**
244+
* Returns the {@link Resource} pointing to a driver configuration file. The configuration file is applied after
245+
* applying {@link System#getProperties() System Properties} and the configuration built by this configuration class.
246+
*
247+
* @return the {@link Resource}; may be {@literal null} if none provided.
248+
* @since 3.1.2
249+
* @see <a href="https://docs.datastax.com/en/developer/java-driver/4.9/manual/core/configuration/">Driver
250+
* Configuration</a>
251+
*/
252+
@Nullable
253+
protected Resource getDriverConfigurationResource() {
254+
return null;
255+
}
256+
227257
/**
228258
* Returns the list of CQL scripts to be run on startup after {@link #getKeyspaceCreations() Keyspace creations}
229259
* and after initialization of the {@literal System} Keyspace.
@@ -280,7 +310,9 @@ public CqlSessionFactoryBean cassandraSession() {
280310

281311
private SessionBuilderConfigurer getSessionBuilderConfigurerWrapper() {
282312

283-
SessionBuilderConfigurer configurer = getSessionBuilderConfigurer();
313+
SessionBuilderConfigurer sessionConfigurer = getSessionBuilderConfigurer();
314+
DriverConfigLoaderBuilderConfigurer driverConfigLoaderConfigurer = getDriverConfigLoaderBuilderConfigurer();
315+
Resource driverConfigFile = getDriverConfigurationResource();
284316

285317
return sessionBuilder -> {
286318

@@ -302,16 +334,30 @@ private SessionBuilderConfigurer getSessionBuilderConfigurerWrapper() {
302334

303335
ConfigFactory.invalidateCaches();
304336

305-
return ConfigFactory.defaultOverrides() //
306-
.withFallback(options.build()) //
307-
.withFallback(ConfigFactory.defaultReference());
337+
Config config = ConfigFactory.defaultOverrides() //
338+
.withFallback(options.build());
339+
340+
if (driverConfigFile != null) {
341+
try {
342+
config = config
343+
.withFallback(ConfigFactory.parseReader(new InputStreamReader(driverConfigFile.getInputStream())));
344+
} catch (IOException e) {
345+
throw new IllegalStateException(String.format("Cannot parse driver config file %s", driverConfigFile), e);
346+
}
347+
}
348+
349+
return config.withFallback(ConfigFactory.defaultReference());
308350

309351
}, DefaultDriverConfigLoader.DEFAULT_ROOT_PATH);
310352

353+
if (driverConfigLoaderConfigurer != null) {
354+
driverConfigLoaderConfigurer.configure(builder);
355+
}
356+
311357
sessionBuilder.withConfigLoader(builder.build());
312358

313-
if (configurer != null) {
314-
return configurer.configure(sessionBuilder);
359+
if (sessionConfigurer != null) {
360+
return sessionConfigurer.configure(sessionBuilder);
315361
}
316362

317363
return sessionBuilder;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.cassandra.config;
17+
18+
import com.datastax.oss.driver.api.core.config.ProgrammaticDriverConfigLoaderBuilder;
19+
20+
/**
21+
* Callback interface that can be implemented by beans wishing to customize the
22+
* {@link ProgrammaticDriverConfigLoaderBuilder} via a {@link DriverConfigLoaderBuilderConfigurer} whilst retaining
23+
* default configuration.
24+
*
25+
* @author Mark Paluch
26+
* @since 3.1.2
27+
*/
28+
public interface DriverConfigLoaderBuilderConfigurer {
29+
30+
/**
31+
* Customize the {@linkplain ProgrammaticDriverConfigLoaderBuilder DriverConfigLoader builder}.
32+
*
33+
* @param builder the builder to customize
34+
*/
35+
void configure(ProgrammaticDriverConfigLoaderBuilder builder);
36+
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.cassandra.config;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
20+
import org.junit.jupiter.api.Test;
21+
import org.junit.jupiter.api.extension.ExtendWith;
22+
23+
import org.springframework.core.io.ClassPathResource;
24+
import org.springframework.core.io.Resource;
25+
import org.springframework.data.cassandra.support.CassandraConnectionProperties;
26+
import org.springframework.data.cassandra.test.util.CassandraExtension;
27+
import org.springframework.lang.Nullable;
28+
29+
import com.datastax.oss.driver.api.core.CqlSession;
30+
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
31+
32+
/**
33+
* Unit tests for {@link AbstractSessionConfiguration}.
34+
*
35+
* @author Mark Paluch
36+
*/
37+
@ExtendWith(CassandraExtension.class)
38+
class AbstractSessionConfigurationIntegrationTests {
39+
40+
@Test
41+
void shouldApplyDriverConfigLoaderBuilderConfigurer() {
42+
43+
MySessionConfiguration configuration = new MySessionConfiguration();
44+
CqlSessionFactoryBean bean = configuration.cassandraSession();
45+
bean.afterPropertiesSet();
46+
CqlSession session = bean.getObject();
47+
48+
assertThat(session.getContext().getConfig().getProfile("foo")).isNotNull();
49+
assertThat(session.getContext().getConfig().getProfiles()).doesNotContainKeys("bar");
50+
}
51+
52+
@Test
53+
void shouldApplyConfigurationFile() {
54+
55+
MySessionConfiguration configuration = new MySessionConfiguration();
56+
CqlSessionFactoryBean bean = configuration.cassandraSession();
57+
bean.afterPropertiesSet();
58+
CqlSession session = bean.getObject();
59+
60+
assertThat(session.getContext().getConfig().getProfile("oltp")).isNotNull();
61+
assertThat(session.getContext().getConfig().getProfiles()).doesNotContainKeys("bar");
62+
}
63+
64+
static class MySessionConfiguration extends AbstractSessionConfiguration {
65+
66+
@Override
67+
protected String getKeyspaceName() {
68+
return "system";
69+
}
70+
71+
@Nullable
72+
@Override
73+
protected String getLocalDataCenter() {
74+
return "datacenter1";
75+
}
76+
77+
@Override
78+
protected int getPort() {
79+
return new CassandraConnectionProperties().getCassandraPort();
80+
}
81+
82+
@Nullable
83+
@Override
84+
protected DriverConfigLoaderBuilderConfigurer getDriverConfigLoaderBuilderConfigurer() {
85+
return it -> {
86+
it.startProfile("foo").withString(DefaultDriverOption.SESSION_NAME, "hello-world").endProfile();
87+
};
88+
}
89+
90+
@Nullable
91+
@Override
92+
protected Resource getDriverConfigurationResource() {
93+
return new ClassPathResource("application.conf");
94+
}
95+
}
96+
97+
}

spring-data-cassandra/src/test/resources/application.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111
# This file is in HOCON format, see https://github.com/typesafehub/config/blob/master/HOCON.md.
1212
datastax-java-driver {
1313

14+
profiles {
15+
oltp {
16+
basic.request.timeout = 100 milliseconds
17+
basic.request.consistency = ONE
18+
}
19+
}
20+
1421
basic.load-balancing-policy {
1522
class = DcInferringLoadBalancingPolicy
1623
}

0 commit comments

Comments
 (0)