Skip to content

Commit

Permalink
Allow config options with relative paths
Browse files Browse the repository at this point in the history
This will be useful to nest policies.
  • Loading branch information
olim7t committed Jun 28, 2017
1 parent 4f69c82 commit a6112af
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 123 deletions.
Expand Up @@ -15,13 +15,16 @@
*/
package com.datastax.oss.driver.api.core.addresstranslation;

import com.datastax.oss.driver.api.core.config.DriverOption;
import com.datastax.oss.driver.api.core.context.DriverContext;
import java.net.InetSocketAddress;

/** An address translator that always returns the same address unchanged. */
public class PassThroughAddressTranslator implements AddressTranslator {

public PassThroughAddressTranslator(@SuppressWarnings("unused") DriverContext context) {
public PassThroughAddressTranslator(
@SuppressWarnings("unused") DriverContext context,
@SuppressWarnings("unused") DriverOption configRoot) {
// nothing to do
}

Expand Down
Expand Up @@ -17,6 +17,7 @@

import com.datastax.oss.driver.api.core.config.CoreDriverOption;
import com.datastax.oss.driver.api.core.config.DriverConfigProfile;
import com.datastax.oss.driver.api.core.config.DriverOption;
import com.datastax.oss.driver.api.core.context.DriverContext;
import com.google.common.base.Charsets;
import java.net.SocketAddress;
Expand All @@ -26,17 +27,15 @@
* A simple authentication provider that supports SASL authentication using the PLAIN mechanism for
* version 3 (or above) of the CQL native protocol.
*
* <p>To activate this provider, an {@code authentication} section must be included in the driver
* <p>To activate this provider, an {@code auth-provider} section must be included in the driver
* configuration, for example:
*
* <pre>
* datastax-java-driver {
* authentication {
* provider-class = com.datastax.driver.api.core.auth.PlainTextAuthProvider
* config {
* username = cassandra
* password = cassandra
* }
* auth-provider {
* class = com.datastax.driver.api.core.auth.PlainTextAuthProvider
* username = cassandra
* password = cassandra
* }
* }
* </pre>
Expand All @@ -46,16 +45,20 @@
public class PlainTextAuthProvider implements AuthProvider {

private final DriverConfigProfile config;
private final DriverOption configRoot;

/** Builds a new instance. */
public PlainTextAuthProvider(DriverContext context) {
public PlainTextAuthProvider(DriverContext context, DriverOption configRoot) {
this.config = context.config().defaultProfile();
this.configRoot = configRoot;
}

@Override
public Authenticator newAuthenticator(SocketAddress host, String serverAuthenticator) {
String username = config.getString(CoreDriverOption.AUTHENTICATION_CONFIG_USERNAME);
String password = config.getString(CoreDriverOption.AUTHENTICATION_CONFIG_PASSWORD);
String username =
config.getString(configRoot.concat(CoreDriverOption.RELATIVE_PLAIN_TEXT_AUTH_USERNAME));
String password =
config.getString(configRoot.concat(CoreDriverOption.RELATIVE_PLAIN_TEXT_AUTH_PASSWORD));
return new PlainTextAuthenticator(username, password);
}

Expand Down
Expand Up @@ -43,15 +43,18 @@ public enum CoreDriverOption implements DriverOption {
CONTROL_CONNECTION_TIMEOUT("connection.control-connection.timeout", true),
CONTROL_CONNECTION_PAGE_SIZE("connection.control-connection.page-size", true),

RETRY_POLICY_CLASS("retry.policy-class", true),
// "Sub-option" for all the policies, etc.
RELATIVE_POLICY_CLASS("class", false),

LOAD_BALANCING_POLICY_CLASS("load-balancing.policy-class", true),
RETRY_POLICY_ROOT("retry-policy", true),

SPECULATIVE_EXECUTION_POLICY_CLASS("speculative-execution.policy-class", true),
LOAD_BALANCING_POLICY_ROOT("load-balancing-policy", true),

RECONNECTION_POLICY_CLASS("connection.reconnection.policy-class", true),
RECONNECTION_CONFIG_BASE_DELAY("connection.reconnection.config.base-delay", true),
RECONNECTION_CONFIG_MAX_DELAY("connection.reconnection.config.max-delay", true),
SPECULATIVE_EXECUTION_POLICY_ROOT("speculative-execution-policy", true),

RECONNECTION_POLICY_ROOT("connection.reconnection-policy", true),
RELATIVE_EXPONENTIAL_RECONNECTION_BASE_DELAY("connection.reconnection.config.base-delay", false),
RELATIVE_EXPONENTIAL_RECONNECTION_MAX_DELAY("connection.reconnection.config.max-delay", false),

PREPARE_ON_ALL_NODES("prepared-statements.prepare-on-all-nodes", true),
REPREPARE_ENABLED("prepared-statements.reprepare-on-up.enabled", true),
Expand All @@ -63,14 +66,14 @@ public enum CoreDriverOption implements DriverOption {
POOLING_LOCAL_CONNECTIONS("pooling.local.connections", true),
POOLING_REMOTE_CONNECTIONS("pooling.remote.connections", true),

ADDRESS_TRANSLATOR_CLASS("address-translation.translator-class", true),
ADDRESS_TRANSLATOR_ROOT("address-translator", true),

AUTHENTICATION_PROVIDER_CLASS("authentication.provider-class", false),
AUTHENTICATION_CONFIG_USERNAME("authentication.config.username", false),
AUTHENTICATION_CONFIG_PASSWORD("authentication.config.password", false),
AUTH_PROVIDER_ROOT("auth-provider", false),
RELATIVE_PLAIN_TEXT_AUTH_USERNAME("username", false),
RELATIVE_PLAIN_TEXT_AUTH_PASSWORD("password", false),

SSL_FACTORY_CLASS("ssl.factory-class", false),
SSL_CONFIG_CIPHER_SUITES("ssl.config.cipher-suites", false),
SSL_ENGINE_FACTORY_ROOT("ssl-engine-factory", false),
RELATIVE_DEFAULT_SSL_CIPHER_SUITES("ssl.config.cipher-suites", false),

METADATA_TOPOLOGY_WINDOW("metadata.topology-event-debouncer.window", true),
METADATA_TOPOLOGY_MAX_EVENTS("metadata.topology-event-debouncer.max-events", true),
Expand Down
Expand Up @@ -20,4 +20,29 @@ public interface DriverOption {
String getPath();

boolean required();

/**
* Concatenates two options to build a longer path.
*
* <p>This is intended for options that can appear at different levels, for example arguments of
* policies that can be nested.
*/
default DriverOption concat(DriverOption child) {
DriverOption parent = this;
// Not particularly efficient, but this will mainly be used for policies, which initialize at
// startup, so it should be good enough.
return new DriverOption() {
@Override
public String getPath() {
return parent.getPath() + "." + child.getPath();
}

@Override
public boolean required() {
// This property is only for initial validation of the configuration, and we can't validate
// nested fields because they are by definition not known in advance.
return false;
}
};
}
}
Expand Up @@ -17,6 +17,7 @@

import com.datastax.oss.driver.api.core.config.CoreDriverOption;
import com.datastax.oss.driver.api.core.config.DriverConfigProfile;
import com.datastax.oss.driver.api.core.config.DriverOption;
import com.datastax.oss.driver.api.core.context.DriverContext;
import com.google.common.base.Preconditions;
import java.time.Duration;
Expand All @@ -32,27 +33,28 @@ public class ExponentialReconnectionPolicy implements ReconnectionPolicy {
private final long maxAttempts;

/** Builds a new instance. */
public ExponentialReconnectionPolicy(DriverContext context) {
public ExponentialReconnectionPolicy(DriverContext context, DriverOption configRoot) {
DriverConfigProfile config = context.config().defaultProfile();
this.baseDelayMs =
config.getDuration(CoreDriverOption.RECONNECTION_CONFIG_BASE_DELAY).toMillis();
this.maxDelayMs = config.getDuration(CoreDriverOption.RECONNECTION_CONFIG_MAX_DELAY).toMillis();
DriverOption baseDelayOption =
configRoot.concat(CoreDriverOption.RELATIVE_EXPONENTIAL_RECONNECTION_BASE_DELAY);
DriverOption maxDelayOption =
configRoot.concat(CoreDriverOption.RELATIVE_EXPONENTIAL_RECONNECTION_MAX_DELAY);

this.baseDelayMs = config.getDuration(baseDelayOption).toMillis();
this.maxDelayMs = config.getDuration(maxDelayOption).toMillis();

Preconditions.checkArgument(
baseDelayMs > 0,
"%s must be strictly positive (got %s)",
CoreDriverOption.RECONNECTION_CONFIG_BASE_DELAY.getPath(),
baseDelayOption.getPath(),
baseDelayMs);
Preconditions.checkArgument(
maxDelayMs >= 0,
"%s must be positive (got %s)",
CoreDriverOption.RECONNECTION_CONFIG_MAX_DELAY.getPath(),
maxDelayMs);
maxDelayMs >= 0, "%s must be positive (got %s)", maxDelayOption.getPath(), maxDelayMs);
Preconditions.checkArgument(
maxDelayMs >= baseDelayMs,
"%s must be bigger than %s (got %s, %s)",
CoreDriverOption.RECONNECTION_CONFIG_MAX_DELAY.getPath(),
CoreDriverOption.RECONNECTION_CONFIG_BASE_DELAY.getPath(),
maxDelayOption.getPath(),
baseDelayOption.getPath(),
maxDelayMs,
baseDelayMs);

Expand Down
Expand Up @@ -15,6 +15,7 @@
*/
package com.datastax.oss.driver.api.core.loadbalancing;

import com.datastax.oss.driver.api.core.config.DriverOption;
import com.datastax.oss.driver.api.core.context.DriverContext;
import com.datastax.oss.driver.api.core.metadata.Node;
import com.datastax.oss.driver.api.core.metadata.NodeState;
Expand Down Expand Up @@ -43,7 +44,9 @@ public class RoundRobinLoadBalancingPolicy implements LoadBalancingPolicy {
private final CopyOnWriteArraySet<Node> liveNodes = new CopyOnWriteArraySet<>();
private volatile DistanceReporter distanceReporter;

public RoundRobinLoadBalancingPolicy(@SuppressWarnings("unused") DriverContext context) {
public RoundRobinLoadBalancingPolicy(
@SuppressWarnings("unused") DriverContext context,
@SuppressWarnings("unused") DriverOption configRoot) {
this.logPrefix = context.clusterName();
}

Expand Down
Expand Up @@ -16,6 +16,7 @@
package com.datastax.oss.driver.api.core.retry;

import com.datastax.oss.driver.api.core.ConsistencyLevel;
import com.datastax.oss.driver.api.core.config.DriverOption;
import com.datastax.oss.driver.api.core.context.DriverContext;
import com.datastax.oss.driver.api.core.session.Request;

Expand All @@ -26,7 +27,9 @@
*/
public class DefaultRetryPolicy implements RetryPolicy {

public DefaultRetryPolicy(@SuppressWarnings("unused") DriverContext context) {
public DefaultRetryPolicy(
@SuppressWarnings("unused") DriverContext context,
@SuppressWarnings("unused") DriverOption configRoot) {
// nothing to do
}

Expand Down
Expand Up @@ -16,13 +16,16 @@
package com.datastax.oss.driver.api.core.specex;

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.config.DriverOption;
import com.datastax.oss.driver.api.core.context.DriverContext;
import com.datastax.oss.driver.api.core.session.Request;

/** A policy that never triggers speculative executions. */
public class NoSpeculativeExecutionPolicy implements SpeculativeExecutionPolicy {

public NoSpeculativeExecutionPolicy(@SuppressWarnings("unused") DriverContext context) {
public NoSpeculativeExecutionPolicy(
@SuppressWarnings("unused") DriverContext context,
@SuppressWarnings("unused") DriverOption configRoot) {
// nothing to do
}

Expand Down
Expand Up @@ -17,6 +17,7 @@

import com.datastax.oss.driver.api.core.config.CoreDriverOption;
import com.datastax.oss.driver.api.core.config.DriverConfigProfile;
import com.datastax.oss.driver.api.core.config.DriverOption;
import com.datastax.oss.driver.api.core.context.DriverContext;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
Expand All @@ -28,16 +29,14 @@
/**
* Default SSL implementation.
*
* <p>To activate this class, an {@code ssl} section must be included in the driver configuration,
* for example:
* <p>To activate this class, an {@code ssl-engine-factory} section must be included in the driver
* configuration, for example:
*
* <pre>
* datastax-java-driver {
* ssl {
* factory-class = com.datastax.driver.api.core.ssl.DefaultSslEngineFactory
* config {
* cipher-suites = [ "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA" ]
* }
* ssl-engine-factory {
* class = com.datastax.driver.api.core.ssl.DefaultSslEngineFactory
* cipher-suites = [ "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA" ]
* }
* }
* </pre>
Expand All @@ -50,15 +49,17 @@ public class DefaultSslEngineFactory implements SslEngineFactory {
private final String[] cipherSuites;

/** Builds a new instance from the driver configuration. */
public DefaultSslEngineFactory(DriverContext driverContext) {
public DefaultSslEngineFactory(DriverContext driverContext, DriverOption configRoot) {
try {
this.sslContext = SSLContext.getDefault();
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Cannot initialize SSL Context", e);
}
DriverConfigProfile config = driverContext.config().defaultProfile();
if (config.isDefined(CoreDriverOption.SSL_CONFIG_CIPHER_SUITES)) {
List<String> list = config.getStringList(CoreDriverOption.SSL_CONFIG_CIPHER_SUITES);
DriverOption cipherSuiteOption =
configRoot.concat(CoreDriverOption.RELATIVE_DEFAULT_SSL_CIPHER_SUITES);
if (config.isDefined(cipherSuiteOption)) {
List<String> list = config.getStringList(cipherSuiteOption);
String tmp[] = new String[list.size()];
this.cipherSuites = list.toArray(tmp);
} else {
Expand Down
Expand Up @@ -22,6 +22,7 @@
import com.datastax.oss.driver.api.core.config.DriverConfig;
import com.datastax.oss.driver.api.core.config.DriverConfigLoader;
import com.datastax.oss.driver.api.core.config.DriverConfigProfile;
import com.datastax.oss.driver.api.core.config.DriverOption;
import com.datastax.oss.driver.api.core.connection.ReconnectionPolicy;
import com.datastax.oss.driver.api.core.loadbalancing.LoadBalancingPolicy;
import com.datastax.oss.driver.api.core.retry.RetryPolicy;
Expand Down Expand Up @@ -140,66 +141,65 @@ public DefaultDriverContext(DriverConfigLoader configLoader, List<TypeCodec<?>>
}

protected LoadBalancingPolicy buildLoadBalancingPolicy() {
CoreDriverOption classOption = CoreDriverOption.LOAD_BALANCING_POLICY_CLASS;
return Reflection.buildFromConfig(this, classOption, LoadBalancingPolicy.class)
DriverOption rootOption = CoreDriverOption.LOAD_BALANCING_POLICY_ROOT;
return Reflection.buildFromConfig(this, rootOption, LoadBalancingPolicy.class)
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"Missing load balancing policy, check your configuration (%s)",
classOption)));
rootOption)));
}

protected ReconnectionPolicy buildReconnectionPolicy() {
CoreDriverOption classOption = CoreDriverOption.RECONNECTION_POLICY_CLASS;
return Reflection.buildFromConfig(this, classOption, ReconnectionPolicy.class)
CoreDriverOption rootOption = CoreDriverOption.RECONNECTION_POLICY_ROOT;
return Reflection.buildFromConfig(this, rootOption, ReconnectionPolicy.class)
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"Missing reconnection policy, check your configuration (%s)",
classOption)));
"Missing reconnection policy, check your configuration (%s)", rootOption)));
}

protected RetryPolicy buildRetryPolicy() {
CoreDriverOption classOption = CoreDriverOption.RETRY_POLICY_CLASS;
return Reflection.buildFromConfig(this, classOption, RetryPolicy.class)
CoreDriverOption rootOption = CoreDriverOption.RETRY_POLICY_ROOT;
return Reflection.buildFromConfig(this, rootOption, RetryPolicy.class)
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"Missing retry policy, check your configuration (%s)", classOption)));
"Missing retry policy, check your configuration (%s)", rootOption)));
}

protected SpeculativeExecutionPolicy buildSpeculativeExecutionPolicy() {
CoreDriverOption classOption = CoreDriverOption.SPECULATIVE_EXECUTION_POLICY_CLASS;
return Reflection.buildFromConfig(this, classOption, SpeculativeExecutionPolicy.class)
CoreDriverOption rootOption = CoreDriverOption.SPECULATIVE_EXECUTION_POLICY_ROOT;
return Reflection.buildFromConfig(this, rootOption, SpeculativeExecutionPolicy.class)
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"Missing speculative execution policy, check your configuration (%s)",
classOption)));
rootOption)));
}

protected AddressTranslator buildAddressTranslator() {
CoreDriverOption classOption = CoreDriverOption.ADDRESS_TRANSLATOR_CLASS;
return Reflection.buildFromConfig(this, classOption, AddressTranslator.class)
CoreDriverOption rootOption = CoreDriverOption.ADDRESS_TRANSLATOR_ROOT;
return Reflection.buildFromConfig(this, rootOption, AddressTranslator.class)
.orElseThrow(
() ->
new IllegalArgumentException(
String.format(
"Missing address translator, check your configuration (%s)", classOption)));
"Missing address translator, check your configuration (%s)", rootOption)));
}

protected Optional<AuthProvider> buildAuthProvider() {
return Reflection.buildFromConfig(
this, CoreDriverOption.AUTHENTICATION_PROVIDER_CLASS, AuthProvider.class);
this, CoreDriverOption.AUTH_PROVIDER_ROOT, AuthProvider.class);
}

protected Optional<SslEngineFactory> buildSslEngineFactory() {
return Reflection.buildFromConfig(
this, CoreDriverOption.SSL_FACTORY_CLASS, SslEngineFactory.class);
this, CoreDriverOption.SSL_ENGINE_FACTORY_ROOT, SslEngineFactory.class);
}

protected EventBus buildEventBus() {
Expand Down

0 comments on commit a6112af

Please sign in to comment.