Skip to content

Commit 904feb2

Browse files
committed
Polish 'Allow spring.data.cassandra.config file to override default values'
See gh-31238
1 parent 1c7d998 commit 904feb2

File tree

5 files changed

+73
-86
lines changed

5 files changed

+73
-86
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfiguration.java

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
1919
import java.io.IOException;
2020
import java.security.NoSuchAlgorithmException;
2121
import java.time.Duration;
22+
import java.util.Collections;
2223
import java.util.LinkedHashMap;
2324
import java.util.List;
2425
import java.util.Map;
@@ -63,13 +64,23 @@
6364
* @author Eddú Meléndez
6465
* @author Stephane Nicoll
6566
* @author Steffen F. Qvistgaard
67+
* @author Ittay Stern
6668
* @since 1.3.0
6769
*/
6870
@Configuration(proxyBeanMethods = false)
6971
@ConditionalOnClass({ CqlSession.class })
7072
@EnableConfigurationProperties(CassandraProperties.class)
7173
public class CassandraAutoConfiguration {
7274

75+
private static final Config SPRING_BOOT_DEFAULTS;
76+
static {
77+
CassandraDriverOptions options = new CassandraDriverOptions();
78+
options.add(DefaultDriverOption.CONTACT_POINTS, Collections.singletonList("127.0.0.1:9042"));
79+
options.add(DefaultDriverOption.PROTOCOL_COMPRESSION, "none");
80+
options.add(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, (int) Duration.ofSeconds(5).toMillis());
81+
SPRING_BOOT_DEFAULTS = options.build();
82+
}
83+
7384
@Bean
7485
@ConditionalOnMissingBean
7586
@Lazy
@@ -118,43 +129,41 @@ public DriverConfigLoader cassandraDriverConfigLoader(CassandraProperties proper
118129
}
119130

120131
private Config cassandraConfiguration(CassandraProperties properties) {
121-
Config config = mapConfig(properties);
122-
Resource configFile = properties.getConfig();
123-
return (configFile != null) ? applyDefaultFallback(config.withFallback(loadConfig(configFile)))
124-
: applyDefaultFallback(config);
125-
}
126-
127-
private Config applyDefaultFallback(Config config) {
128132
ConfigFactory.invalidateCaches();
129-
return ConfigFactory.defaultOverrides().withFallback(config)
130-
.withFallback(mapConfig(CassandraProperties.defaults())).withFallback(ConfigFactory.defaultReference())
131-
.resolve();
133+
Config config = ConfigFactory.defaultOverrides();
134+
config = config.withFallback(mapConfig(properties));
135+
if (properties.getConfig() != null) {
136+
config = config.withFallback(loadConfig(properties.getConfig()));
137+
}
138+
config = config.withFallback(SPRING_BOOT_DEFAULTS);
139+
config = config.withFallback(ConfigFactory.defaultReference());
140+
return config.resolve();
132141
}
133142

134-
private Config loadConfig(Resource config) {
143+
private Config loadConfig(Resource resource) {
135144
try {
136-
return ConfigFactory.parseURL(config.getURL());
145+
return ConfigFactory.parseURL(resource.getURL());
137146
}
138147
catch (IOException ex) {
139-
throw new IllegalStateException("Failed to load cassandra configuration from " + config, ex);
148+
throw new IllegalStateException("Failed to load cassandra configuration from " + resource, ex);
140149
}
141150
}
142151

143152
private Config mapConfig(CassandraProperties properties) {
144153
CassandraDriverOptions options = new CassandraDriverOptions();
145-
PropertyMapper map = PropertyMapper.get();
154+
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
146155
map.from(properties.getSessionName()).whenHasText()
147156
.to((sessionName) -> options.add(DefaultDriverOption.SESSION_NAME, sessionName));
148-
map.from(properties::getUsername).whenNonNull()
157+
map.from(properties::getUsername)
149158
.to((username) -> options.add(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, username)
150159
.add(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, properties.getPassword()));
151-
map.from(properties::getCompression).whenNonNull()
160+
map.from(properties::getCompression)
152161
.to((compression) -> options.add(DefaultDriverOption.PROTOCOL_COMPRESSION, compression));
153162
mapConnectionOptions(properties, options);
154163
mapPoolingOptions(properties, options);
155164
mapRequestOptions(properties, options);
156165
mapControlConnectionOptions(properties, options);
157-
map.from(mapContactPoints(properties)).whenNonNull()
166+
map.from(mapContactPoints(properties))
158167
.to((contactPoints) -> options.add(DefaultDriverOption.CONTACT_POINTS, contactPoints));
159168
map.from(properties.getLocalDatacenter()).whenHasText().to(
160169
(localDatacenter) -> options.add(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter));
@@ -211,9 +220,12 @@ private void mapControlConnectionOptions(CassandraProperties properties, Cassand
211220
}
212221

213222
private List<String> mapContactPoints(CassandraProperties properties) {
214-
List<String> contactPoints = properties.getContactPoints();
215-
return (contactPoints == null) ? null : contactPoints.stream()
216-
.map((candidate) -> formatContactPoint(candidate, properties.getPort())).collect(Collectors.toList());
223+
if (properties.getContactPoints() != null) {
224+
return properties.getContactPoints().stream()
225+
.map((candidate) -> formatContactPoint(candidate, properties.getPort()))
226+
.collect(Collectors.toList());
227+
}
228+
return null;
217229
}
218230

219231
private String formatContactPoint(String candidate, int port) {

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cassandra/CassandraProperties.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
package org.springframework.boot.autoconfigure.cassandra;
1818

1919
import java.time.Duration;
20-
import java.util.ArrayList;
21-
import java.util.Collections;
2220
import java.util.List;
2321

2422
import com.datastax.oss.driver.api.core.DefaultConsistencyLevel;
@@ -38,16 +36,6 @@
3836
@ConfigurationProperties(prefix = "spring.data.cassandra")
3937
public class CassandraProperties {
4038

41-
static CassandraProperties defaults() {
42-
CassandraProperties properties = new CassandraProperties();
43-
44-
properties.setContactPoints(new ArrayList<>(Collections.singleton("127.0.0.1:9042")));
45-
properties.setCompression(Compression.NONE);
46-
properties.getControlconnection().setTimeout(Duration.ofSeconds(5));
47-
48-
return properties;
49-
}
50-
5139
/**
5240
* Location of the configuration file to use.
5341
*/

spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,10 @@
492492
"name": "spring.data.cassandra.connection.init-query-timeout",
493493
"defaultValue": "5s"
494494
},
495+
{
496+
"name": "spring.data.cassandra.controlconnection.timeout",
497+
"defaultValue": "5s"
498+
},
495499
{
496500
"name": "spring.data.cassandra.contact-points",
497501
"defaultValue": [

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cassandra/CassandraAutoConfigurationTests.java

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
1818

1919
import java.time.Duration;
2020
import java.util.Collections;
21-
import java.util.List;
2221

2322
import com.datastax.oss.driver.api.core.CqlIdentifier;
2423
import com.datastax.oss.driver.api.core.CqlSession;
@@ -30,7 +29,6 @@
3029
import com.datastax.oss.driver.internal.core.session.throttling.ConcurrencyLimitingRequestThrottler;
3130
import com.datastax.oss.driver.internal.core.session.throttling.PassThroughRequestThrottler;
3231
import com.datastax.oss.driver.internal.core.session.throttling.RateLimitingRequestThrottler;
33-
import org.assertj.core.api.SoftAssertions;
3432
import org.junit.jupiter.api.Test;
3533

3634
import org.springframework.boot.autoconfigure.AutoConfigurations;
@@ -46,6 +44,7 @@
4644
*
4745
* @author Eddú Meléndez
4846
* @author Stephane Nicoll
47+
* @author Ittay Stern
4948
*/
5049
class CassandraAutoConfigurationTests {
5150

@@ -247,41 +246,25 @@ void driverConfigLoaderWithConfigComplementSettings() {
247246
});
248247
}
249248

250-
@Test // gh-31025
249+
@Test // gh-31238
251250
void driverConfigLoaderWithConfigOverridesDefaults() {
252251
String configLocation = "org/springframework/boot/autoconfigure/cassandra/override-defaults.conf";
253252
this.contextRunner.withPropertyValues("spring.data.cassandra.config=" + configLocation).run((context) -> {
254-
assertThat(context).hasSingleBean(DriverConfigLoader.class);
255-
256-
SoftAssertions softly = new SoftAssertions();
257-
258-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
259-
.getString(DefaultDriverOption.SESSION_NAME)).isEqualTo("advanced session");
260-
261-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
262-
.getDuration(DefaultDriverOption.REQUEST_TIMEOUT)).isEqualTo(Duration.ofSeconds(2)); // default
263-
264-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
265-
.getStringList(DefaultDriverOption.CONTACT_POINTS)).isEqualTo(Collections.singletonList("1.2.3.4:5678"));
266-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
267-
.getBoolean(DefaultDriverOption.RESOLVE_CONTACT_POINTS)).isFalse();
268-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
269-
.getInt(DefaultDriverOption.REQUEST_PAGE_SIZE)).isEqualTo(11);
270-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
271-
.getString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER)).isEqualTo("datacenter1");
272-
273-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
274-
.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_CONCURRENT_REQUESTS)).isEqualTo(22);
275-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
276-
.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_REQUESTS_PER_SECOND)).isEqualTo(33);
277-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
278-
.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_QUEUE_SIZE)).isEqualTo(44);
279-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
280-
.getDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT)).isEqualTo(Duration.ofMillis(5555));
281-
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
282-
.getString(DefaultDriverOption.PROTOCOL_COMPRESSION)).isEqualTo("SNAPPY");
283-
284-
softly.assertAll();
253+
DriverExecutionProfile actual = context.getBean(DriverConfigLoader.class).getInitialConfig()
254+
.getDefaultProfile();
255+
assertThat(actual.getString(DefaultDriverOption.SESSION_NAME)).isEqualTo("advanced session");
256+
assertThat(actual.getDuration(DefaultDriverOption.REQUEST_TIMEOUT)).isEqualTo(Duration.ofSeconds(2));
257+
assertThat(actual.getStringList(DefaultDriverOption.CONTACT_POINTS))
258+
.isEqualTo(Collections.singletonList("1.2.3.4:5678"));
259+
assertThat(actual.getBoolean(DefaultDriverOption.RESOLVE_CONTACT_POINTS)).isFalse();
260+
assertThat(actual.getInt(DefaultDriverOption.REQUEST_PAGE_SIZE)).isEqualTo(11);
261+
assertThat(actual.getString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER)).isEqualTo("datacenter1");
262+
assertThat(actual.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_CONCURRENT_REQUESTS)).isEqualTo(22);
263+
assertThat(actual.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_REQUESTS_PER_SECOND)).isEqualTo(33);
264+
assertThat(actual.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_QUEUE_SIZE)).isEqualTo(44);
265+
assertThat(actual.getDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT))
266+
.isEqualTo(Duration.ofMillis(5555));
267+
assertThat(actual.getString(DefaultDriverOption.PROTOCOL_COMPRESSION)).isEqualTo("SNAPPY");
285268
});
286269
}
287270

Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
datastax-java-driver {
2-
basic {
3-
session-name = advanced session
4-
load-balancing-policy {
5-
local-datacenter = datacenter1
6-
}
7-
request.page-size = 11
8-
contact-points = [ "1.2.3.4:5678" ]
9-
}
10-
advanced {
11-
throttler {
12-
max-concurrent-requests = 22
13-
max-requests-per-second = 33
14-
max-queue-size = 44
15-
}
16-
control-connection.timeout = 5555
17-
protocol.compression = SNAPPY
18-
resolve-contact-points = false
19-
}
2+
basic {
3+
session-name = advanced session
4+
load-balancing-policy {
5+
local-datacenter = datacenter1
6+
}
7+
request.page-size = 11
8+
contact-points = [ "1.2.3.4:5678" ]
9+
}
10+
advanced {
11+
throttler {
12+
max-concurrent-requests = 22
13+
max-requests-per-second = 33
14+
max-queue-size = 44
15+
}
16+
control-connection.timeout = 5555
17+
protocol.compression = SNAPPY
18+
resolve-contact-points = false
19+
}
2020
}

0 commit comments

Comments
 (0)