com.datastax.driver.dse.graph.GraphOptions Maven / Gradle / Ivy
/*
* Copyright DataStax, Inc.
*
* This software can be used solely with DataStax Enterprise. Please consult the license at
* http://www.datastax.com/terms/datastax-dse-driver-license-terms
*/
package com.datastax.driver.dse.graph;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.datastax.driver.core.ConsistencyLevel;
import com.google.common.collect.ImmutableMap;
import java.nio.ByteBuffer;
import java.util.Map;
/**
* The default graph options to use for a DSE cluster.
*
* These options will be used for all graph statements sent to the cluster, unless they have been
* explicitly overridden at the statement level (by using methods such as {@link
* GraphStatement#setGraphName(String)}).
*
*
Graph options are specified at cluster initialization with {@link
* com.datastax.driver.dse.DseCluster.Builder#withGraphOptions(GraphOptions)}, and can be retrieved
* at runtime with {@code dseCluster.getConfiguration().getGraphOptions()}.
*/
public class GraphOptions {
// Static keys for the custom payload maps
static final String GRAPH_SOURCE_KEY = "graph-source";
static final String GRAPH_NAME_KEY = "graph-name";
static final String GRAPH_LANGUAGE_KEY = "graph-language";
static final String GRAPH_READ_CONSISTENCY_KEY = "graph-read-consistency";
static final String GRAPH_WRITE_CONSISTENCY_KEY = "graph-write-consistency";
static final String REQUEST_TIMEOUT_KEY = "request-timeout";
static final String GRAPH_RESULTS_KEY = "graph-results";
/** The default value for {@link #getGraphLanguage()} ({@value}). */
public static final String DEFAULT_GRAPH_LANGUAGE = "gremlin-groovy";
/** The default value for {@link #getGraphSource()} ({@value}). */
public static final String DEFAULT_GRAPH_SOURCE = "g";
private volatile String graphLanguage = DEFAULT_GRAPH_LANGUAGE;
private volatile String graphSource = DEFAULT_GRAPH_SOURCE;
private volatile String graphName;
private volatile ConsistencyLevel graphReadConsistency;
private volatile ConsistencyLevel graphWriteConsistency;
private volatile Map defaultPayload;
private volatile int readTimeoutMillis = 0;
// unset by default
private volatile GraphProtocol graphSubProtocol;
public GraphOptions() {
rebuildDefaultPayload();
}
/**
* Returns the graph language to use in graph queries.
*
* @return the graph language to use in graph queries.
* @see #setGraphLanguage(String)
*/
public String getGraphLanguage() {
return graphLanguage;
}
/**
* Sets the graph language to use in graph queries.
*
* This property is required. If you don't call this method, it defaults to {@value
* #DEFAULT_GRAPH_LANGUAGE}.
*
* @param graphLanguage the graph language to use in graph queries.
* @return this {@code GraphOptions} instance (for method chaining).
*/
public GraphOptions setGraphLanguage(String graphLanguage) {
checkNotNull(graphLanguage, "graphLanguage cannot be null");
this.graphLanguage = graphLanguage;
rebuildDefaultPayload();
return this;
}
/**
* Returns the graph traversal source name to use in graph queries.
*
* @return The graph traversal source name to use in graph queries.
* @see #setGraphSource(String)
*/
public String getGraphSource() {
return graphSource;
}
/**
* Sets the graph traversal source name to use in graph queries.
*
*
This property is required. If you don't call this method, it defaults to {@value
* #DEFAULT_GRAPH_SOURCE}.
*
* @param graphSource the graph traversal source name to use in graph queries.
* @return this {@code GraphOptions} instance (for method chaining).
*/
public GraphOptions setGraphSource(String graphSource) {
checkNotNull(graphSource, "graphSource cannot be null");
this.graphSource = graphSource;
rebuildDefaultPayload();
return this;
}
/**
* Returns the graph name to use in graph queries.
*
* @return The graph name to use in graph queries.
* @see #setGraphName(String)
*/
public String getGraphName() {
return graphName;
}
/**
* Sets the graph name to use in graph queries.
*
*
This property is optional. If you don't call this method, it is left unset.
*
* @param graphName The Graph name to use in graph queries.
* @return this {@code GraphOptions} instance (for method chaining).
*/
public GraphOptions setGraphName(String graphName) {
this.graphName = graphName;
rebuildDefaultPayload();
return this;
}
/**
* Returns the read consistency level to use in graph queries.
*
* @return the read consistency level configured with graph queries.
*/
public ConsistencyLevel getGraphReadConsistencyLevel() {
return this.graphReadConsistency;
}
/**
* Sets the read consistency level to use for graph queries.
*
*
This setting will override the consistency level set with {@link
* GraphStatement#setConsistencyLevel(ConsistencyLevel)} only for the READ part of the graph
* query.
*
*
Please see {@link GraphStatement#setConsistencyLevel(ConsistencyLevel)} for more
* information.
*
* @param cl the consistency level to set.
* @return this {@link GraphOptions} instance (for method chaining).
*/
public GraphOptions setGraphReadConsistencyLevel(ConsistencyLevel cl) {
this.graphReadConsistency = cl;
rebuildDefaultPayload();
return this;
}
/**
* Returns the write consistency level to use in graph queries.
*
* @return the write consistency level configured with graph queries.
*/
public ConsistencyLevel getGraphWriteConsistencyLevel() {
return this.graphWriteConsistency;
}
/**
* Sets the write consistency level to use for graph queries.
*
*
This setting will override the consistency level set with {@link
* GraphStatement#setConsistencyLevel(ConsistencyLevel)} only for the write part of the graph
* query.
*
*
Please see {@link GraphStatement#setConsistencyLevel(ConsistencyLevel)} for more
* information.
*
* @param cl the consistency level to set.
* @return this {@link GraphStatement} instance (for method chaining).
*/
public GraphOptions setGraphWriteConsistencyLevel(ConsistencyLevel cl) {
this.graphWriteConsistency = cl;
rebuildDefaultPayload();
return this;
}
/**
* Return the per-host socket read timeout that is set for all graph queries.
*
* @return the timeout.
*/
public int getReadTimeoutMillis() {
return this.readTimeoutMillis;
}
/**
* Sets the per-host read timeout in milliseconds for graph queries. The default is 0, which means
* the driver will wait until the coordinator responds with the result or an error, or times out.
*
*
Only call this method if you want to wait less than the server's default timeout (defined in
* {@code dse.yaml}). Note that the server will abort a query once the client has stopped waiting
* for it, so there's no risk of leaving long-running queries on the server.
*
* @param readTimeoutMillis the timeout to set.
* @return this {@link GraphOptions} instance (for method chaining).
*/
public GraphOptions setReadTimeoutMillis(int readTimeoutMillis) {
checkArgument(readTimeoutMillis >= 0, "readTimeoutMillis can not be negative");
this.readTimeoutMillis = readTimeoutMillis;
return this;
}
/**
* Set the sub protocol to use with DSE Graph. See {@link GraphProtocol} for more information.
*
* @param graphSubProtocol the sub protocol to choose
* @return this {@link GraphOptions} instance (for method chaining).
*/
public GraphOptions setGraphSubProtocol(GraphProtocol graphSubProtocol) {
this.graphSubProtocol = graphSubProtocol;
return this;
}
/**
* Return the graph sub protocol set for all queries.
*
* @return the sub protocol currently used.
*/
public GraphProtocol getGraphSubProtocol() {
return this.graphSubProtocol;
}
/**
* Builds the custom payload for the given statement, providing defaults from these graph options
* if necessary.
*
*
This method is intended for internal use only.
*
* @param statement the statement.
* @return the payload.
*/
public Map buildPayloadWithDefaults(GraphStatement statement) {
if (statement.getGraphLanguage() == null
&& statement.getGraphSource() == null
&& statement.getGraphReadConsistencyLevel() == null
&& statement.getGraphWriteConsistencyLevel() == null
&& statement.getGraphName() == null
&& statement.getGraphInternalOptions().size() == 0
&& !statement.isSystemQuery()
&& graphSubProtocol == null) {
return defaultPayload;
} else {
ImmutableMap.Builder builder = ImmutableMap.builder();
setOrDefaultText(builder, GRAPH_LANGUAGE_KEY, statement.getGraphLanguage());
setOrDefaultText(builder, GRAPH_SOURCE_KEY, statement.getGraphSource());
// ----- Optional DSEGraph settings -----
setOrDefaultCl(builder, GRAPH_READ_CONSISTENCY_KEY, statement.getGraphReadConsistencyLevel());
setOrDefaultCl(
builder, GRAPH_WRITE_CONSISTENCY_KEY, statement.getGraphWriteConsistencyLevel());
if (!statement.isSystemQuery()) {
setOrDefaultText(builder, GRAPH_NAME_KEY, statement.getGraphName());
}
if (statement.getReadTimeoutMillis() > 0) {
// If > 0 it means it's not the default and has to be in the payload.
setOrDefaultBigInt(builder, REQUEST_TIMEOUT_KEY, (long) statement.getReadTimeoutMillis());
}
// the default is null (means unset). If set, use it in the statement's payload.
// If unset, the server determines the default result according to the graph-language.
// Additionally, do not tamper with this key if the statement is a different implementation
// unknown to the driver (right now only RegularGraphStatement is concerned)
if (graphSubProtocol != null && statement instanceof RegularGraphStatement) {
setOrDefaultText(builder, GRAPH_RESULTS_KEY, graphSubProtocol.getProtocolReference());
}
for (Map.Entry optionEntry : statement.getGraphInternalOptions().entrySet()) {
setOrDefaultText(builder, optionEntry.getKey(), optionEntry.getValue());
}
return builder.build();
}
}
void setOrDefaultText(
ImmutableMap.Builder builder, String key, String value) {
ByteBuffer bytes = (value == null) ? defaultPayload.get(key) : PayloadHelper.asBytes(value);
if (bytes != null) builder.put(key, bytes);
}
private void setOrDefaultCl(
ImmutableMap.Builder builder, String key, ConsistencyLevel value) {
ByteBuffer bytes =
(value == null) ? defaultPayload.get(key) : PayloadHelper.asBytes(value.name());
if (bytes != null) builder.put(key, bytes);
}
private void setOrDefaultBigInt(
ImmutableMap.Builder builder, String key, Long value) {
ByteBuffer bytes = (value == null) ? defaultPayload.get(key) : PayloadHelper.asBytes(value);
if (bytes != null) builder.put(key, bytes);
}
void rebuildDefaultPayload() {
ImmutableMap.Builder builder = ImmutableMap.builder();
builder.put(GRAPH_LANGUAGE_KEY, PayloadHelper.asBytes(this.graphLanguage));
builder.put(GRAPH_SOURCE_KEY, PayloadHelper.asBytes(this.graphSource));
if (this.graphName != null) {
builder.put(GRAPH_NAME_KEY, PayloadHelper.asBytes(this.graphName));
}
if (this.graphReadConsistency != null) {
builder.put(
GRAPH_READ_CONSISTENCY_KEY, PayloadHelper.asBytes(this.graphReadConsistency.name()));
}
if (this.graphWriteConsistency != null) {
builder.put(
GRAPH_WRITE_CONSISTENCY_KEY, PayloadHelper.asBytes(this.graphWriteConsistency.name()));
}
this.defaultPayload = builder.build();
}
}