Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Values in a spring.data.cassandra.config file can't override some defaults defined in CassandraProperties #31238

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import javax.net.ssl.SSLContext;

Expand Down Expand Up @@ -126,7 +125,10 @@ private Config cassandraConfiguration(CassandraProperties properties) {

private Config applyDefaultFallback(Config config) {
ConfigFactory.invalidateCaches();
return ConfigFactory.defaultOverrides().withFallback(config).withFallback(ConfigFactory.defaultReference())
return ConfigFactory.defaultOverrides()
.withFallback(config)
.withFallback(mapConfig(CassandraProperties.defaults()))
.withFallback(ConfigFactory.defaultReference())
.resolve();
}

Expand All @@ -153,10 +155,10 @@ private Config mapConfig(CassandraProperties properties) {
mapPoolingOptions(properties, options);
mapRequestOptions(properties, options);
mapControlConnectionOptions(properties, options);
map.from(mapContactPoints(properties))
map.from(mapContactPoints(properties)).whenNonNull()
.to((contactPoints) -> options.add(DefaultDriverOption.CONTACT_POINTS, contactPoints));
map.from(properties.getLocalDatacenter()).to(
(localDatacenter) -> options.add(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter));
map.from(properties.getLocalDatacenter()).whenHasText()
.to((localDatacenter) -> options.add(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter));
return options.build();
}

Expand Down Expand Up @@ -210,8 +212,9 @@ private void mapControlConnectionOptions(CassandraProperties properties, Cassand
}

private List<String> mapContactPoints(CassandraProperties properties) {
return properties.getContactPoints().stream()
.map((candidate) -> formatContactPoint(candidate, properties.getPort())).collect(Collectors.toList());
List<String> contactPoints = properties.getContactPoints();
return (contactPoints == null) ? null : contactPoints.stream()
.map((candidate) -> formatContactPoint(candidate, properties.getPort())).toList();
}

private String formatContactPoint(String candidate, int port) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@
@ConfigurationProperties(prefix = "spring.data.cassandra")
public class CassandraProperties {

static CassandraProperties defaults() {
var properties = new CassandraProperties();

properties.setContactPoints(new ArrayList<>(Collections.singleton("127.0.0.1:9042")));
properties.setCompression(Compression.NONE);
properties.getControlconnection().setTimeout(Duration.ofSeconds(5));

return properties;
}

/**
* Location of the configuration file to use.
*/
Expand All @@ -57,7 +67,7 @@ public class CassandraProperties {
* Cluster node addresses in the form 'host:port', or a simple 'host' to use the
* configured port.
*/
private final List<String> contactPoints = new ArrayList<>(Collections.singleton("127.0.0.1:9042"));
private List<String> contactPoints;

/**
* Port to use if a contact point does not specify one.
Expand All @@ -83,7 +93,7 @@ public class CassandraProperties {
/**
* Compression supported by the Cassandra binary protocol.
*/
private Compression compression = Compression.NONE;
private Compression compression;

/**
* Schema action to take at startup.
Expand Down Expand Up @@ -143,6 +153,10 @@ public List<String> getContactPoints() {
return this.contactPoints;
}

public void setContactPoints(List<String> contactPoints) {
this.contactPoints = contactPoints;
}

public int getPort() {
return this.port;
}
Expand Down Expand Up @@ -266,7 +280,7 @@ public static class Request {
/**
* How many rows will be retrieved simultaneously in a single network round-trip.
*/
private int pageSize;
private Integer pageSize;

private final Throttler throttler = new Throttler();

Expand Down Expand Up @@ -294,7 +308,7 @@ public void setSerialConsistency(DefaultConsistencyLevel serialConsistency) {
this.serialConsistency = serialConsistency;
}

public int getPageSize() {
public Integer getPageSize() {
return this.pageSize;
}

Expand Down Expand Up @@ -347,7 +361,7 @@ public static class Controlconnection {
/**
* Timeout to use for control queries.
*/
private Duration timeout = Duration.ofSeconds(5);
private Duration timeout;

public Duration getTimeout() {
return this.timeout;
Expand All @@ -370,17 +384,17 @@ public static class Throttler {
* Maximum number of requests that can be enqueued when the throttling threshold
* is exceeded.
*/
private int maxQueueSize;
private Integer maxQueueSize;

/**
* Maximum number of requests that are allowed to execute in parallel.
*/
private int maxConcurrentRequests;
private Integer maxConcurrentRequests;

/**
* Maximum allowed request rate.
*/
private int maxRequestsPerSecond;
private Integer maxRequestsPerSecond;

/**
* How often the throttler attempts to dequeue requests. Set this high enough that
Expand All @@ -397,23 +411,23 @@ public void setType(ThrottlerType type) {
this.type = type;
}

public int getMaxQueueSize() {
public Integer getMaxQueueSize() {
return this.maxQueueSize;
}

public void setMaxQueueSize(int maxQueueSize) {
this.maxQueueSize = maxQueueSize;
}

public int getMaxConcurrentRequests() {
public Integer getMaxConcurrentRequests() {
return this.maxConcurrentRequests;
}

public void setMaxConcurrentRequests(int maxConcurrentRequests) {
this.maxConcurrentRequests = maxConcurrentRequests;
}

public int getMaxRequestsPerSecond() {
public Integer getMaxRequestsPerSecond() {
return this.maxRequestsPerSecond;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.cassandra;

import java.time.Duration;
import java.util.List;

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.CqlSession;
Expand All @@ -28,6 +29,7 @@
import com.datastax.oss.driver.internal.core.session.throttling.ConcurrencyLimitingRequestThrottler;
import com.datastax.oss.driver.internal.core.session.throttling.PassThroughRequestThrottler;
import com.datastax.oss.driver.internal.core.session.throttling.RateLimitingRequestThrottler;
import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;

import org.springframework.boot.autoconfigure.AutoConfigurations;
Expand Down Expand Up @@ -244,6 +246,44 @@ void driverConfigLoaderWithConfigComplementSettings() {
});
}

@Test // gh-31025
void driverConfigLoaderWithConfigOverridesDefaults() {
String configLocation = "org/springframework/boot/autoconfigure/cassandra/override-defaults.conf";
this.contextRunner.withPropertyValues("spring.data.cassandra.config=" + configLocation).run((context) -> {
assertThat(context).hasSingleBean(DriverConfigLoader.class);

SoftAssertions softly = new SoftAssertions();

softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getString(DefaultDriverOption.SESSION_NAME)).isEqualTo("advanced session");

softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getDuration(DefaultDriverOption.REQUEST_TIMEOUT)).isEqualTo(Duration.ofSeconds(2)); // default

softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getStringList(DefaultDriverOption.CONTACT_POINTS)).isEqualTo(List.of("1.2.3.4:5678"));
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getBoolean(DefaultDriverOption.RESOLVE_CONTACT_POINTS)).isFalse();
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getInt(DefaultDriverOption.REQUEST_PAGE_SIZE)).isEqualTo(11);
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getString(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER)).isEqualTo("datacenter1");

softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_CONCURRENT_REQUESTS)).isEqualTo(22);
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_REQUESTS_PER_SECOND)).isEqualTo(33);
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getInt(DefaultDriverOption.REQUEST_THROTTLER_MAX_QUEUE_SIZE)).isEqualTo(44);
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT)).isEqualTo(Duration.ofMillis(5555));
softly.assertThat(context.getBean(DriverConfigLoader.class).getInitialConfig().getDefaultProfile()
.getString(DefaultDriverOption.PROTOCOL_COMPRESSION)).isEqualTo("SNAPPY");

softly.assertAll();
});
}

@Test
void driverConfigLoaderWithConfigCreateProfiles() {
String configLocation = "org/springframework/boot/autoconfigure/cassandra/profiles.conf";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
datastax-java-driver {
basic {
session-name = advanced session
load-balancing-policy {
local-datacenter = datacenter1
}
request.page-size = 11
contact-points = [ "1.2.3.4:5678" ]
}
advanced {
throttler {
max-concurrent-requests = 22
max-requests-per-second = 33
max-queue-size = 44
}
control-connection.timeout = 5555
protocol.compression = SNAPPY
resolve-contact-points = false
}
}