DATACASS-708 - Allow configuration of execution profile and serial consistency per statement.
We now allow configuration of the execution profile and serial consistency through QueryOptions and CassandraAccessor/ReactiveCqlTemplate. Settings are applied on a per-Statement basis. The newly ExecutionProfileResolver can resolve the profile either from a profile name or a DriverExecutionProfile object for more flexibility. With this change, we removed the support for setting a RetryPolicy directly as the new driver 4 does not support a direct configuration of the RetryPolicy. Instead, the RetryPolicy is configured through an execution profile.
This commit is contained in:
@@ -21,6 +21,7 @@ import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.data.cassandra.core.cql.ExecutionProfileResolver;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.cassandra.core.query.Filter;
|
||||
@@ -28,7 +29,6 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.oss.driver.api.core.ConsistencyLevel;
|
||||
import com.datastax.oss.driver.api.core.retry.RetryPolicy;
|
||||
|
||||
/**
|
||||
* Extension to {@link WriteOptions} for use with {@code DELETE} operations.
|
||||
@@ -45,11 +45,12 @@ public class DeleteOptions extends WriteOptions {
|
||||
|
||||
private final @Nullable Filter ifCondition;
|
||||
|
||||
private DeleteOptions(@Nullable ConsistencyLevel consistencyLevel, @Nullable RetryPolicy retryPolicy,
|
||||
@Nullable Boolean tracing, @Nullable Integer fetchSize, Duration readTimeout, Duration ttl,
|
||||
@Nullable Long timestamp, boolean ifExists, @Nullable Filter ifCondition) {
|
||||
private DeleteOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver,
|
||||
@Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, Duration ttl,
|
||||
@Nullable Long timestamp, @Nullable Boolean tracing, boolean ifExists, @Nullable Filter ifCondition) {
|
||||
|
||||
super(consistencyLevel, retryPolicy, tracing, fetchSize, readTimeout, ttl, timestamp);
|
||||
super(consistencyLevel, executionProfileResolver, pageSize, serialConsistencyLevel, timeout, ttl, timestamp,
|
||||
tracing);
|
||||
|
||||
this.ifExists = ifExists;
|
||||
this.ifCondition = ifCondition;
|
||||
@@ -129,13 +130,20 @@ public class DeleteOptions extends WriteOptions {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#retryPolicy(com.datastax.driver.core.policies.RetryPolicy)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#executionProfile(String)
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public DeleteOptionsBuilder retryPolicy(RetryPolicy driverRetryPolicy) {
|
||||
public DeleteOptionsBuilder executionProfile(String profileName) {
|
||||
super.executionProfile(profileName);
|
||||
return this;
|
||||
}
|
||||
|
||||
super.retryPolicy(driverRetryPolicy);
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#executionProfile(org.springframework.data.cassandra.core.cql.ExecutionProfileResolver)
|
||||
*/
|
||||
@Override
|
||||
public DeleteOptionsBuilder executionProfile(ExecutionProfileResolver executionProfileResolver) {
|
||||
super.executionProfile(executionProfileResolver);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -182,6 +190,15 @@ public class DeleteOptions extends WriteOptions {
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#serialConsistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel)
|
||||
*/
|
||||
@Override
|
||||
public DeleteOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) {
|
||||
super.serialConsistencyLevel(consistencyLevel);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#readTimeout(java.time.Duration)
|
||||
*/
|
||||
@@ -312,8 +329,9 @@ public class DeleteOptions extends WriteOptions {
|
||||
*/
|
||||
public DeleteOptions build() {
|
||||
|
||||
return new DeleteOptions(this.consistencyLevel, this.retryPolicy, this.tracing, this.pageSize, this.timeout,
|
||||
this.ttl, this.timestamp, this.ifExists, this.ifCondition);
|
||||
return new DeleteOptions(this.consistencyLevel, this.executionProfileResolver, this.pageSize,
|
||||
this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing, this.ifExists,
|
||||
this.ifCondition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.data.cassandra.core.cql.ExecutionProfileResolver;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.datastax.oss.driver.api.core.ConsistencyLevel;
|
||||
import com.datastax.oss.driver.api.core.retry.RetryPolicy;
|
||||
|
||||
/**
|
||||
* Extension to {@link WriteOptions} for use with {@code INSERT} operations.
|
||||
@@ -43,11 +43,12 @@ public class InsertOptions extends WriteOptions {
|
||||
|
||||
private boolean insertNulls;
|
||||
|
||||
private InsertOptions(@Nullable ConsistencyLevel consistencyLevel, @Nullable RetryPolicy retryPolicy,
|
||||
@Nullable Boolean tracing, @Nullable Integer fetchSize, Duration readTimeout, Duration ttl,
|
||||
@Nullable Long timestamp, boolean ifNotExists, boolean insertNulls) {
|
||||
private InsertOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver,
|
||||
@Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, Duration ttl,
|
||||
@Nullable Long timestamp, @Nullable Boolean tracing, boolean ifNotExists, boolean insertNulls) {
|
||||
|
||||
super(consistencyLevel, retryPolicy, tracing, fetchSize, readTimeout, ttl, timestamp);
|
||||
super(consistencyLevel, executionProfileResolver, pageSize, serialConsistencyLevel, timeout, ttl, timestamp,
|
||||
tracing);
|
||||
|
||||
this.ifNotExists = ifNotExists;
|
||||
this.insertNulls = insertNulls;
|
||||
@@ -131,13 +132,20 @@ public class InsertOptions extends WriteOptions {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#retryPolicy(com.datastax.driver.core.policies.RetryPolicy)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#executionProfile(String)
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public InsertOptionsBuilder retryPolicy(RetryPolicy driverRetryPolicy) {
|
||||
public InsertOptionsBuilder executionProfile(String profileName) {
|
||||
super.executionProfile(profileName);
|
||||
return this;
|
||||
}
|
||||
|
||||
super.retryPolicy(driverRetryPolicy);
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#executionProfile(org.springframework.data.cassandra.core.cql.ExecutionProfileResolver)
|
||||
*/
|
||||
@Override
|
||||
public InsertOptionsBuilder executionProfile(ExecutionProfileResolver executionProfileResolver) {
|
||||
super.executionProfile(executionProfileResolver);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -180,6 +188,15 @@ public class InsertOptions extends WriteOptions {
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#serialConsistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel)
|
||||
*/
|
||||
@Override
|
||||
public InsertOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) {
|
||||
super.serialConsistencyLevel(consistencyLevel);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#readTimeout(java.time.Duration)
|
||||
*/
|
||||
@@ -274,8 +291,8 @@ public class InsertOptions extends WriteOptions {
|
||||
|
||||
/**
|
||||
* Insert {@literal null} values from an entity. This allows the usage of {@code INSERT} statements as upsert by
|
||||
* ensuring * that the whole entity state is persisted. Inserting {@literal null}s in Cassandra creates tombstones
|
||||
* so this * option should be used with caution.
|
||||
* ensuring that the whole entity state is persisted. Inserting {@literal null}s in Cassandra creates tombstones so
|
||||
* this option should be used with caution.
|
||||
*
|
||||
* @return {@code this} {@link InsertOptionsBuilder}
|
||||
* @since 2.1
|
||||
@@ -306,8 +323,9 @@ public class InsertOptions extends WriteOptions {
|
||||
* @return a new {@link InsertOptions} with the configured values
|
||||
*/
|
||||
public InsertOptions build() {
|
||||
return new InsertOptions(this.consistencyLevel, this.retryPolicy, this.tracing, this.pageSize, this.timeout,
|
||||
this.ttl, this.timestamp, this.ifNotExists, this.insertNulls);
|
||||
return new InsertOptions(this.consistencyLevel, this.executionProfileResolver, this.pageSize,
|
||||
this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing, this.ifNotExists,
|
||||
this.insertNulls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,8 +845,8 @@ public class ReactiveCassandraTemplate
|
||||
|
||||
if (getReactiveCqlOperations() instanceof CassandraAccessor) {
|
||||
CassandraAccessor accessor = (CassandraAccessor) getReactiveCqlOperations();
|
||||
if (accessor.getFetchSize() != -1) {
|
||||
return Mono.just(accessor.getFetchSize());
|
||||
if (accessor.getPageSize() != -1) {
|
||||
return Mono.just(accessor.getPageSize());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -315,9 +315,7 @@ public class StatementFactory {
|
||||
return statement.valuesByIds(values);
|
||||
}).apply(statement -> (RegularInsert) addWriteOptions(statement, options));
|
||||
|
||||
builder.onBuild(statementBuilder -> {
|
||||
QueryOptionsUtil.addQueryOptions(statementBuilder, options);
|
||||
});
|
||||
builder.transform(statement -> QueryOptionsUtil.addQueryOptions(statement, options));
|
||||
|
||||
return builder;
|
||||
}
|
||||
@@ -395,9 +393,7 @@ public class StatementFactory {
|
||||
});
|
||||
|
||||
query.getQueryOptions().ifPresent(options -> {
|
||||
builder.onBuild(statementBuilder -> {
|
||||
query.getQueryOptions().ifPresent(it -> QueryOptionsUtil.addQueryOptions(statementBuilder, it));
|
||||
});
|
||||
builder.transform(statementBuilder -> QueryOptionsUtil.addQueryOptions(statementBuilder, options));
|
||||
});
|
||||
|
||||
return builder;
|
||||
@@ -462,9 +458,7 @@ public class StatementFactory {
|
||||
applyUpdateIfCondition(builder, criteriaDefinitions);
|
||||
});
|
||||
|
||||
builder.onBuild(statementBuilder -> {
|
||||
QueryOptionsUtil.addQueryOptions(statementBuilder, options);
|
||||
});
|
||||
builder.transform(statement -> QueryOptionsUtil.addQueryOptions(statement, options));
|
||||
|
||||
return builder;
|
||||
}
|
||||
@@ -542,9 +536,7 @@ public class StatementFactory {
|
||||
});
|
||||
|
||||
query.getQueryOptions().ifPresent(options -> {
|
||||
builder.onBuild(statementBuilder -> {
|
||||
query.getQueryOptions().ifPresent(it -> QueryOptionsUtil.addQueryOptions(statementBuilder, it));
|
||||
});
|
||||
builder.transform(statement -> QueryOptionsUtil.addQueryOptions(statement, options));
|
||||
});
|
||||
|
||||
return builder;
|
||||
@@ -588,9 +580,7 @@ public class StatementFactory {
|
||||
applyDeleteIfCondition(builder, criteriaDefinitions);
|
||||
});
|
||||
|
||||
builder.onBuild(statementBuilder -> {
|
||||
QueryOptionsUtil.addQueryOptions(statementBuilder, options);
|
||||
});
|
||||
builder.transform(statement -> QueryOptionsUtil.addQueryOptions(statement, options));
|
||||
|
||||
return builder;
|
||||
}
|
||||
@@ -651,7 +641,10 @@ public class StatementFactory {
|
||||
select.onBuild(statementBuilder -> {
|
||||
|
||||
query.getPagingState().ifPresent(statementBuilder::setPagingState);
|
||||
query.getQueryOptions().ifPresent(it -> QueryOptionsUtil.addQueryOptions(statementBuilder, it));
|
||||
});
|
||||
|
||||
query.getQueryOptions().ifPresent(it -> {
|
||||
select.transform(statement -> QueryOptionsUtil.addQueryOptions(statement, it));
|
||||
});
|
||||
|
||||
return select;
|
||||
@@ -839,8 +832,7 @@ public class StatementFactory {
|
||||
Collection<Object> collection = (Collection<Object>) updateOp.getValue();
|
||||
Assert.isTrue(collection.size() == 1, "RemoveOp must contain a single set element");
|
||||
|
||||
return Assignment.removeSetElement(updateOp.toCqlIdentifier(),
|
||||
termFactory.create(collection.iterator().next()));
|
||||
return Assignment.removeSetElement(updateOp.toCqlIdentifier(), termFactory.create(collection.iterator().next()));
|
||||
}
|
||||
|
||||
if (updateOp.getValue() instanceof List) {
|
||||
@@ -848,8 +840,7 @@ public class StatementFactory {
|
||||
Collection<Object> collection = (Collection<Object>) updateOp.getValue();
|
||||
Assert.isTrue(collection.size() == 1, "RemoveOp must contain a single list element");
|
||||
|
||||
return Assignment.removeListElement(updateOp.toCqlIdentifier(),
|
||||
termFactory.create(collection.iterator().next()));
|
||||
return Assignment.removeListElement(updateOp.toCqlIdentifier(), termFactory.create(collection.iterator().next()));
|
||||
}
|
||||
|
||||
return Assignment.remove(updateOp.toCqlIdentifier(), termFactory.create(updateOp.getValue()));
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.data.cassandra.core.cql.ExecutionProfileResolver;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.cassandra.core.query.Filter;
|
||||
@@ -28,7 +29,6 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.oss.driver.api.core.ConsistencyLevel;
|
||||
import com.datastax.oss.driver.api.core.retry.RetryPolicy;
|
||||
|
||||
/**
|
||||
* Extension to {@link WriteOptions} for use with {@code UPDATE} operations.
|
||||
@@ -46,11 +46,12 @@ public class UpdateOptions extends WriteOptions {
|
||||
|
||||
private final @Nullable Filter ifCondition;
|
||||
|
||||
private UpdateOptions(@Nullable ConsistencyLevel consistencyLevel, @Nullable RetryPolicy retryPolicy,
|
||||
@Nullable Boolean tracing, @Nullable Integer fetchSize, Duration readTimeout, Duration ttl,
|
||||
@Nullable Long timestamp, boolean ifExists, @Nullable Filter ifCondition) {
|
||||
private UpdateOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver,
|
||||
@Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, Duration ttl,
|
||||
@Nullable Long timestamp, @Nullable Boolean tracing, boolean ifExists, @Nullable Filter ifCondition) {
|
||||
|
||||
super(consistencyLevel, retryPolicy, tracing, fetchSize, readTimeout, ttl, timestamp);
|
||||
super(consistencyLevel, executionProfileResolver, pageSize, serialConsistencyLevel, timeout, ttl, timestamp,
|
||||
tracing);
|
||||
|
||||
this.ifExists = ifExists;
|
||||
this.ifCondition = ifCondition;
|
||||
@@ -135,13 +136,20 @@ public class UpdateOptions extends WriteOptions {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#retryPolicy(com.datastax.driver.core.policies.RetryPolicy)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#executionProfile(String)
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public UpdateOptionsBuilder retryPolicy(RetryPolicy driverRetryPolicy) {
|
||||
public UpdateOptionsBuilder executionProfile(String profileName) {
|
||||
super.executionProfile(profileName);
|
||||
return this;
|
||||
}
|
||||
|
||||
super.retryPolicy(driverRetryPolicy);
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#executionProfile(org.springframework.data.cassandra.core.cql.ExecutionProfileResolver)
|
||||
*/
|
||||
@Override
|
||||
public UpdateOptionsBuilder executionProfile(ExecutionProfileResolver executionProfileResolver) {
|
||||
super.executionProfile(executionProfileResolver);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -188,6 +196,15 @@ public class UpdateOptions extends WriteOptions {
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#serialConsistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel)
|
||||
*/
|
||||
@Override
|
||||
public UpdateOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) {
|
||||
super.serialConsistencyLevel(consistencyLevel);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.WriteOptions.WriteOptionsBuilder#readTimeout(java.time.Duration)
|
||||
*/
|
||||
@@ -320,8 +337,9 @@ public class UpdateOptions extends WriteOptions {
|
||||
*/
|
||||
public UpdateOptions build() {
|
||||
|
||||
return new UpdateOptions(this.consistencyLevel, this.retryPolicy, this.tracing, this.pageSize, this.timeout,
|
||||
this.ttl, this.timestamp, this.ifExists, this.ifCondition);
|
||||
return new UpdateOptions(this.consistencyLevel, this.executionProfileResolver, this.pageSize,
|
||||
this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing, this.ifExists,
|
||||
this.ifCondition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,12 @@ public class CassandraAccessor implements InitializingBean {
|
||||
|
||||
private CqlExceptionTranslator exceptionTranslator = new CassandraExceptionTranslator();
|
||||
|
||||
/**
|
||||
* If this variable is set to a value, it will be used for setting the {@code executionProfile} property on statements
|
||||
* used for query processing.
|
||||
*/
|
||||
private ExecutionProfileResolver executionProfileResolver = ExecutionProfileResolver.none();
|
||||
|
||||
/**
|
||||
* If this variable is set to a non-negative value, it will be used for setting the {@code pageSize} property on
|
||||
* statements used for query processing.
|
||||
@@ -67,10 +73,10 @@ public class CassandraAccessor implements InitializingBean {
|
||||
private @Nullable ConsistencyLevel consistencyLevel;
|
||||
|
||||
/**
|
||||
* If this variable is set to a value, it will be used for setting the {@code retryPolicy} property on statements used
|
||||
* for query processing.
|
||||
* If this variable is set to a value, it will be used for setting the {@code serial consistencyLevel} property on
|
||||
* statements used for query processing.
|
||||
*/
|
||||
private @Deprecated @Nullable RetryPolicy retryPolicy;
|
||||
private @Nullable ConsistencyLevel serialConsistencyLevel;
|
||||
|
||||
private @Nullable SessionFactory sessionFactory;
|
||||
|
||||
@@ -127,6 +133,40 @@ public class CassandraAccessor implements InitializingBean {
|
||||
return this.exceptionTranslator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the driver execution profile for this template.
|
||||
*
|
||||
* @see Statement#setExecutionProfileName(String)
|
||||
* @see ExecutionProfileResolver
|
||||
* @since 3.0
|
||||
*/
|
||||
public void setExecutionProfile(String profileName) {
|
||||
setExecutionProfileResolver(ExecutionProfileResolver.from(profileName));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link ExecutionProfileResolver} for this template.
|
||||
*
|
||||
* @see com.datastax.oss.driver.api.core.config.DriverExecutionProfile
|
||||
* @see ExecutionProfileResolver
|
||||
* @since 3.0
|
||||
*/
|
||||
public void setExecutionProfileResolver(ExecutionProfileResolver executionProfileResolver) {
|
||||
|
||||
Assert.notNull(executionProfileResolver, "ExecutionProfileResolver must not be null");
|
||||
|
||||
this.executionProfileResolver = executionProfileResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link ExecutionProfileResolver} specified for this template.
|
||||
* @since 3.0
|
||||
*/
|
||||
public ExecutionProfileResolver getExecutionProfileResolver() {
|
||||
return executionProfileResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fetch size for this template. This is important for processing large result sets: Setting this higher than
|
||||
* the default value will increase processing speed at the cost of memory consumption; setting this lower can avoid
|
||||
@@ -170,24 +210,23 @@ public class CassandraAccessor implements InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the retry policy for this template. This is important for defining behavior when a request fails.
|
||||
* Set the serial consistency level for this template.
|
||||
*
|
||||
* @see RetryPolicy
|
||||
* @deprecated since 3.0. Use driver execution profiles instead.
|
||||
* @since 3.0
|
||||
* @see Statement#setSerialConsistencyLevel(ConsistencyLevel)
|
||||
* @see ConsistencyLevel
|
||||
*/
|
||||
@Deprecated
|
||||
public void setRetryPolicy(@Nullable RetryPolicy retryPolicy) {
|
||||
this.retryPolicy = retryPolicy;
|
||||
public void setSerialConsistencyLevel(@Nullable ConsistencyLevel consistencyLevel) {
|
||||
this.serialConsistencyLevel = consistencyLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link RetryPolicy} specified for this template.
|
||||
* @deprecated since 3.0. Use driver execution profiles instead.
|
||||
* @return the serial {@link ConsistencyLevel} specified for this template.
|
||||
* @since 3.0
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
public RetryPolicy getRetryPolicy() {
|
||||
return this.retryPolicy;
|
||||
public ConsistencyLevel getSerialConsistencyLevel() {
|
||||
return this.serialConsistencyLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,22 +302,33 @@ public class CassandraAccessor implements InitializingBean {
|
||||
* Prepare the given CQL Statement applying statement settings such as page size and consistency level.
|
||||
*
|
||||
* @param statement the CQL Statement to prepare
|
||||
* @see #setPageSize(int)
|
||||
* @see #setConsistencyLevel(ConsistencyLevel)
|
||||
* @see #setSerialConsistencyLevel(ConsistencyLevel)
|
||||
* @see #setPageSize(int)
|
||||
* @see #setExecutionProfile(String)
|
||||
* @see #setExecutionProfileResolver(ExecutionProfileResolver)
|
||||
*/
|
||||
protected Statement<?> applyStatementSettings(Statement<?> statement) {
|
||||
|
||||
Statement<?> statementToUse = statement;
|
||||
ConsistencyLevel consistencyLevel = getConsistencyLevel();
|
||||
ConsistencyLevel serialConsistencyLevel = getSerialConsistencyLevel();
|
||||
int pageSize = getPageSize();
|
||||
|
||||
if (getFetchSize() > -1 && statement.getPageSize() < 0) {
|
||||
statementToUse = statementToUse.setPageSize(getFetchSize());
|
||||
if (consistencyLevel != null) {
|
||||
statementToUse = statementToUse.setConsistencyLevel(consistencyLevel);
|
||||
}
|
||||
|
||||
if (consistencyLevel != null && statementToUse.getConsistencyLevel() == null) {
|
||||
statementToUse = statementToUse.setConsistencyLevel(getConsistencyLevel());
|
||||
if (serialConsistencyLevel != null) {
|
||||
statementToUse = statementToUse.setSerialConsistencyLevel(serialConsistencyLevel);
|
||||
}
|
||||
|
||||
if (pageSize > -1) {
|
||||
statementToUse = statementToUse.setPageSize(pageSize);
|
||||
}
|
||||
|
||||
statementToUse = getExecutionProfileResolver().apply(statementToUse);
|
||||
|
||||
return statementToUse;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.core.cql;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.oss.driver.api.core.config.DriverExecutionProfile;
|
||||
import com.datastax.oss.driver.api.core.cql.Statement;
|
||||
|
||||
/**
|
||||
* Resolver for a {@link com.datastax.oss.driver.api.core.config.DriverExecutionProfile} used with
|
||||
* {@link com.datastax.oss.driver.api.core.cql.Statement#setExecutionProfileName(String)} or
|
||||
* {@link com.datastax.oss.driver.api.core.cql.Statement#setExecutionProfile(DriverExecutionProfile)}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 3.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExecutionProfileResolver {
|
||||
|
||||
/**
|
||||
* Apply an execution profile based on the {@link Statement}.
|
||||
*
|
||||
* @param statement the statement to inspect and to apply the {@code driver execution profile} to.
|
||||
* @return the statement with the profile applied.
|
||||
*/
|
||||
Statement<?> apply(Statement<?> statement);
|
||||
|
||||
/**
|
||||
* Create a no-op {@link ExecutionProfileResolver} that preserves the {@link Statement} settings.
|
||||
*
|
||||
* @return no-op {@link ExecutionProfileResolver} that preserves the {@link Statement} settings.
|
||||
*/
|
||||
static ExecutionProfileResolver none() {
|
||||
return statement -> statement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link ExecutionProfileResolver} from a {@link DriverExecutionProfile} to apply the profile object.
|
||||
*
|
||||
* @param driverExecutionProfile must not be {@literal null}.
|
||||
* @return a {@link ExecutionProfileResolver} that applies the given {@link DriverExecutionProfile}.
|
||||
* @see Statement#setExecutionProfile(DriverExecutionProfile)
|
||||
*/
|
||||
static ExecutionProfileResolver from(DriverExecutionProfile driverExecutionProfile) {
|
||||
|
||||
Assert.notNull(driverExecutionProfile, "DriverExecutionProfile must not be null");
|
||||
|
||||
return statement -> statement.setExecutionProfile(driverExecutionProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link ExecutionProfileResolver} from a {@code profileName}.
|
||||
*
|
||||
* @param profileName must not be {@literal null} or empty.
|
||||
* @return a {@link ExecutionProfileResolver} that applies the given {@code profileName}.
|
||||
* @see Statement#setExecutionProfileName(String)
|
||||
*/
|
||||
static ExecutionProfileResolver from(String profileName) {
|
||||
|
||||
Assert.hasText(profileName, "DriverExecutionProfile name must not be empty");
|
||||
|
||||
return statement -> statement.setExecutionProfileName(profileName);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.oss.driver.api.core.ConsistencyLevel;
|
||||
import com.datastax.oss.driver.api.core.retry.RetryPolicy;
|
||||
import com.datastax.oss.driver.api.core.config.DriverExecutionProfile;
|
||||
|
||||
/**
|
||||
* Cassandra Query Options for queries. {@link QueryOptions} allow tuning of various query options on a per-request
|
||||
@@ -38,41 +38,28 @@ public class QueryOptions {
|
||||
|
||||
private static final QueryOptions EMPTY = QueryOptions.builder().build();
|
||||
|
||||
private final @Nullable Boolean tracing;
|
||||
|
||||
private final @Nullable ConsistencyLevel consistencyLevel;
|
||||
|
||||
private final Duration readTimeout;
|
||||
private final ExecutionProfileResolver executionProfileResolver;
|
||||
|
||||
private final @Nullable Integer pageSize;
|
||||
|
||||
private final @Nullable RetryPolicy retryPolicy;
|
||||
private final @Nullable ConsistencyLevel serialConsistencyLevel;
|
||||
|
||||
protected QueryOptions(@Nullable ConsistencyLevel consistencyLevel, @Nullable RetryPolicy retryPolicy,
|
||||
@Nullable Boolean tracing, @Nullable Integer fetchSize, Duration readTimeout) {
|
||||
private final Duration timeout;
|
||||
|
||||
private final @Nullable Boolean tracing;
|
||||
|
||||
protected QueryOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver,
|
||||
@Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout,
|
||||
@Nullable Boolean tracing) {
|
||||
|
||||
this.consistencyLevel = consistencyLevel;
|
||||
this.retryPolicy = retryPolicy;
|
||||
this.executionProfileResolver = executionProfileResolver;
|
||||
this.pageSize = pageSize;
|
||||
this.serialConsistencyLevel = serialConsistencyLevel;
|
||||
this.timeout = timeout;
|
||||
this.tracing = tracing;
|
||||
this.pageSize = fetchSize;
|
||||
this.readTimeout = readTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link QueryOptions} for the given {@link ConsistencyLevel} and {@link RetryPolicy}.
|
||||
*
|
||||
* @param consistencyLevel the consistency level, may be {@literal null}.
|
||||
* @param retryPolicy the retry policy, may be {@literal null}.
|
||||
* @deprecated since 2.0, use {@link #builder()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public QueryOptions(@Nullable ConsistencyLevel consistencyLevel, @Nullable RetryPolicy retryPolicy) {
|
||||
|
||||
this.consistencyLevel = consistencyLevel;
|
||||
this.retryPolicy = retryPolicy;
|
||||
this.tracing = false;
|
||||
this.pageSize = null;
|
||||
this.readTimeout = Duration.ofMillis(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +93,7 @@ public class QueryOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the the driver {@link ConsistencyLevel}
|
||||
* @return the the driver {@link ConsistencyLevel}.
|
||||
* @since 1.5
|
||||
*/
|
||||
@Nullable
|
||||
@@ -114,6 +101,14 @@ public class QueryOptions {
|
||||
return this.consistencyLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the the {@link ExecutionProfileResolver}.
|
||||
* @since 3.0
|
||||
*/
|
||||
protected ExecutionProfileResolver getExecutionProfileResolver() {
|
||||
return this.executionProfileResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of rows to fetch per chunking request. May be {@literal null} if not set.
|
||||
* @since 1.5
|
||||
@@ -124,20 +119,33 @@ public class QueryOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the read timeout in milliseconds. May be {@literal null} if not set.
|
||||
* @return the command timeout. May be {@link Duration#isNegative() negative} if not set.
|
||||
* @since 1.5
|
||||
* @see com.datastax.oss.driver.api.core.cql.Statement#setTimeout(Duration)
|
||||
* @deprecated since 3.0, use {@link #getTimeout()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
protected Duration getReadTimeout() {
|
||||
return this.readTimeout;
|
||||
return getTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the driver {@link RetryPolicy}
|
||||
* @since 1.5
|
||||
* @return the command timeout. May be {@link Duration#isNegative() negative} if not set.
|
||||
* @since 3.0
|
||||
* @see com.datastax.oss.driver.api.core.cql.Statement#setTimeout(Duration)
|
||||
*/
|
||||
protected Duration getTimeout() {
|
||||
return this.timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the the serial {@link ConsistencyLevel}.
|
||||
* @since 3.0
|
||||
* @see com.datastax.oss.driver.api.core.cql.Statement#setSerialConsistencyLevel(ConsistencyLevel)
|
||||
*/
|
||||
@Nullable
|
||||
protected RetryPolicy getRetryPolicy() {
|
||||
return this.retryPolicy;
|
||||
protected ConsistencyLevel getSerialConsistencyLevel() {
|
||||
return this.serialConsistencyLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,24 +164,27 @@ public class QueryOptions {
|
||||
*/
|
||||
public static class QueryOptionsBuilder {
|
||||
|
||||
protected @Nullable Boolean tracing;
|
||||
|
||||
protected @Nullable ConsistencyLevel consistencyLevel;
|
||||
|
||||
protected Duration timeout = Duration.ofMillis(-1);
|
||||
protected ExecutionProfileResolver executionProfileResolver = ExecutionProfileResolver.none();
|
||||
|
||||
protected @Nullable Integer pageSize;
|
||||
|
||||
protected @Nullable RetryPolicy retryPolicy;
|
||||
protected @Nullable ConsistencyLevel serialConsistencyLevel;
|
||||
|
||||
protected Duration timeout = Duration.ofMillis(-1);
|
||||
|
||||
protected @Nullable Boolean tracing;
|
||||
|
||||
QueryOptionsBuilder() {}
|
||||
|
||||
QueryOptionsBuilder(QueryOptions queryOptions) {
|
||||
|
||||
this.consistencyLevel = queryOptions.consistencyLevel;
|
||||
this.executionProfileResolver = queryOptions.executionProfileResolver;
|
||||
this.pageSize = queryOptions.pageSize;
|
||||
this.timeout = queryOptions.readTimeout;
|
||||
this.retryPolicy = queryOptions.retryPolicy;
|
||||
this.serialConsistencyLevel = queryOptions.serialConsistencyLevel;
|
||||
this.timeout = queryOptions.timeout;
|
||||
this.tracing = queryOptions.tracing;
|
||||
}
|
||||
|
||||
@@ -193,19 +204,29 @@ public class QueryOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link RetryPolicy driver RetryPolicy} to use. Setting both ( {@link RetryPolicy} and {@link RetryPolicy
|
||||
* driver RetryPolicy}) retry policies is not supported.
|
||||
* Sets the {@code execution profile} to use.
|
||||
*
|
||||
* @param retryPolicy must not be {@literal null}.
|
||||
* @param profileName must not be {@literal null} or empty.
|
||||
* @return {@code this} {@link QueryOptionsBuilder}
|
||||
* @deprecated since 3.0, use execution profiles instead.
|
||||
* @since 3.0
|
||||
* @see com.datastax.oss.driver.api.core.cql.Statement#setExecutionProfileName(String)
|
||||
*/
|
||||
@Deprecated
|
||||
public QueryOptionsBuilder retryPolicy(RetryPolicy retryPolicy) {
|
||||
public QueryOptionsBuilder executionProfile(String profileName) {
|
||||
return executionProfile(ExecutionProfileResolver.from(profileName));
|
||||
}
|
||||
|
||||
Assert.notNull(retryPolicy, "RetryPolicy must not be null");
|
||||
/**
|
||||
* Sets the {@link ExecutionProfileResolver} to use.
|
||||
*
|
||||
* @param executionProfileResolver must not be {@literal null}.
|
||||
* @return {@code this} {@link QueryOptionsBuilder}
|
||||
* @see com.datastax.oss.driver.api.core.cql.Statement#setExecutionProfile(DriverExecutionProfile)
|
||||
*/
|
||||
public QueryOptionsBuilder executionProfile(ExecutionProfileResolver executionProfileResolver) {
|
||||
|
||||
this.retryPolicy = retryPolicy;
|
||||
Assert.notNull(executionProfileResolver, "ExecutionProfileResolver must not be null");
|
||||
|
||||
this.executionProfileResolver = executionProfileResolver;
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -301,6 +322,21 @@ public class QueryOptions {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the serial {@link ConsistencyLevel} to use.
|
||||
*
|
||||
* @param consistencyLevel must not be {@literal null}.
|
||||
* @return {@code this} {@link QueryOptionsBuilder}
|
||||
*/
|
||||
public QueryOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) {
|
||||
|
||||
Assert.notNull(consistencyLevel, "Serial ConsistencyLevel must not be null");
|
||||
|
||||
this.serialConsistencyLevel = consistencyLevel;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request timeout. Overrides the default timeout.
|
||||
*
|
||||
@@ -347,7 +383,8 @@ public class QueryOptions {
|
||||
* @return a new {@link QueryOptions} with the configured values
|
||||
*/
|
||||
public QueryOptions build() {
|
||||
return new QueryOptions(this.consistencyLevel, this.retryPolicy, this.tracing, this.pageSize, this.timeout);
|
||||
return new QueryOptions(this.consistencyLevel, this.executionProfileResolver, this.pageSize,
|
||||
this.serialConsistencyLevel, this.timeout, this.tracing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.time.Duration;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.oss.driver.api.core.cql.SimpleStatementBuilder;
|
||||
import com.datastax.oss.driver.api.core.cql.Statement;
|
||||
import com.datastax.oss.driver.api.querybuilder.delete.Delete;
|
||||
import com.datastax.oss.driver.api.querybuilder.delete.DeleteSelection;
|
||||
@@ -52,12 +51,18 @@ public abstract class QueryOptionsUtil {
|
||||
statementToUse = statementToUse.setConsistencyLevel(queryOptions.getConsistencyLevel());
|
||||
}
|
||||
|
||||
statementToUse = queryOptions.getExecutionProfileResolver().apply(statementToUse);
|
||||
|
||||
if (queryOptions.getPageSize() != null) {
|
||||
statementToUse = statementToUse.setPageSize(queryOptions.getPageSize());
|
||||
}
|
||||
|
||||
if (!queryOptions.getReadTimeout().isNegative()) {
|
||||
statementToUse = statementToUse.setTimeout(queryOptions.getReadTimeout());
|
||||
if (queryOptions.getSerialConsistencyLevel() != null) {
|
||||
statementToUse = statementToUse.setSerialConsistencyLevel(queryOptions.getSerialConsistencyLevel());
|
||||
}
|
||||
|
||||
if (!queryOptions.getTimeout().isNegative()) {
|
||||
statementToUse = statementToUse.setTimeout(queryOptions.getTimeout());
|
||||
}
|
||||
|
||||
if (queryOptions.getTracing() != null) {
|
||||
@@ -71,37 +76,6 @@ public abstract class QueryOptionsUtil {
|
||||
return (T) statementToUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add common {@link QueryOptions} to all types of queries.
|
||||
*
|
||||
* @param statement a {@link SimpleStatementBuilder}, must not be {@literal null}.
|
||||
* @param queryOptions query options (e.g. consistency level) to add to the CQL statement.
|
||||
*/
|
||||
public static void addQueryOptions(SimpleStatementBuilder statementBuilder, QueryOptions queryOptions) {
|
||||
|
||||
Assert.notNull(statementBuilder, "SimpleStatementBuilder must not be null");
|
||||
|
||||
if (queryOptions.getConsistencyLevel() != null) {
|
||||
statementBuilder.setConsistencyLevel(queryOptions.getConsistencyLevel());
|
||||
}
|
||||
|
||||
if (queryOptions.getPageSize() != null) {
|
||||
statementBuilder.setPageSize(queryOptions.getPageSize());
|
||||
}
|
||||
|
||||
if (!queryOptions.getReadTimeout().isNegative()) {
|
||||
statementBuilder.setTimeout(queryOptions.getReadTimeout());
|
||||
}
|
||||
|
||||
if (queryOptions.getTracing() != null) {
|
||||
if (queryOptions.getTracing()) {
|
||||
statementBuilder.setTracing(true);
|
||||
} else {
|
||||
statementBuilder.setTracing(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add common {@link WriteOptions} options to {@link Insert} CQL statements.
|
||||
*
|
||||
|
||||
@@ -87,18 +87,24 @@ public class ReactiveCqlTemplate extends ReactiveCassandraAccessor implements Re
|
||||
*/
|
||||
private int pageSize = -1;
|
||||
|
||||
/**
|
||||
* If this variable is set to a value, it will be used for setting the {@code retryPolicy} property on statements used
|
||||
* for query processing.
|
||||
*/
|
||||
private @Deprecated @Nullable RetryPolicy retryPolicy;
|
||||
|
||||
/**
|
||||
* If this variable is set to a value, it will be used for setting the {@code consistencyLevel} property on statements
|
||||
* used for query processing.
|
||||
*/
|
||||
private @Nullable ConsistencyLevel consistencyLevel;
|
||||
|
||||
/**
|
||||
* If this variable is set to a value, it will be used for setting the {@code executionProfile} property on statements
|
||||
* used for query processing.
|
||||
*/
|
||||
private ExecutionProfileResolver executionProfileResolver = ExecutionProfileResolver.none();
|
||||
|
||||
/**
|
||||
* If this variable is set to a value, it will be used for setting the serial {@code consistencyLevel} property on
|
||||
* statements used for query processing.
|
||||
*/
|
||||
private @Nullable ConsistencyLevel serialConsistencyLevel;
|
||||
|
||||
/**
|
||||
* Construct a new {@link ReactiveCqlTemplate Note: The {@link ReactiveSessionFactory} has to be set before using the
|
||||
* instance.
|
||||
@@ -154,6 +160,40 @@ public class ReactiveCqlTemplate extends ReactiveCassandraAccessor implements Re
|
||||
return consistencyLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the driver execution profile for this template.
|
||||
*
|
||||
* @see Statement#setExecutionProfileName(String)
|
||||
* @see ExecutionProfileResolver
|
||||
* @since 3.0
|
||||
*/
|
||||
public void setExecutionProfile(String profileName) {
|
||||
setExecutionProfileResolver(ExecutionProfileResolver.from(profileName));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link ExecutionProfileResolver} for this template.
|
||||
*
|
||||
* @see com.datastax.oss.driver.api.core.config.DriverExecutionProfile
|
||||
* @see ExecutionProfileResolver
|
||||
* @since 3.0
|
||||
*/
|
||||
public void setExecutionProfileResolver(ExecutionProfileResolver executionProfileResolver) {
|
||||
|
||||
Assert.notNull(executionProfileResolver, "ExecutionProfileResolver must not be null");
|
||||
|
||||
this.executionProfileResolver = executionProfileResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link ExecutionProfileResolver} specified for this {@link ReactiveCqlTemplate}.
|
||||
* @since 3.0
|
||||
*/
|
||||
public ExecutionProfileResolver getExecutionProfileResolver() {
|
||||
return executionProfileResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fetch size for this template. This is important for processing large result sets: Setting this higher than
|
||||
* the default value will increase processing speed at the cost of memory consumption; setting this lower can avoid
|
||||
@@ -197,24 +237,23 @@ public class ReactiveCqlTemplate extends ReactiveCassandraAccessor implements Re
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the retry policy for this template. This is important for defining behavior when a request fails.
|
||||
* Set the serial consistency level for this template.
|
||||
*
|
||||
* @see RetryPolicy
|
||||
* @deprecated since 3.0. Use driver execution profiles instead.
|
||||
* @since 3.0
|
||||
* @see Statement#setSerialConsistencyLevel(ConsistencyLevel)
|
||||
* @see ConsistencyLevel
|
||||
*/
|
||||
@Deprecated
|
||||
public void setRetryPolicy(@Nullable RetryPolicy retryPolicy) {
|
||||
this.retryPolicy = retryPolicy;
|
||||
public void setSerialConsistencyLevel(@Nullable ConsistencyLevel consistencyLevel) {
|
||||
this.serialConsistencyLevel = consistencyLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link RetryPolicy} specified for this template.
|
||||
* @deprecated since 3.0. Use driver execution profiles instead.
|
||||
* @return the serial {@link ConsistencyLevel} specified for this template.
|
||||
* @since 3.0
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
public RetryPolicy getRetryPolicy() {
|
||||
return this.retryPolicy;
|
||||
public ConsistencyLevel getSerialConsistencyLevel() {
|
||||
return this.serialConsistencyLevel;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -778,22 +817,33 @@ public class ReactiveCqlTemplate extends ReactiveCassandraAccessor implements Re
|
||||
* Prepare the given CQL Statement applying statement settings such as page size and consistency level.
|
||||
*
|
||||
* @param stmt the CQL Statement to prepare
|
||||
* @see #setPageSize(int)
|
||||
* @see #setConsistencyLevel(ConsistencyLevel)
|
||||
* @see #setSerialConsistencyLevel(ConsistencyLevel)
|
||||
* @see #setPageSize(int)
|
||||
* @see #setExecutionProfile(String)
|
||||
* @see #setExecutionProfileResolver(ExecutionProfileResolver)
|
||||
*/
|
||||
protected Statement<?> applyStatementSettings(Statement<?> statement) {
|
||||
|
||||
Statement<?> statementToUse = statement;
|
||||
ConsistencyLevel consistencyLevel = getConsistencyLevel();
|
||||
ConsistencyLevel serialConsistencyLevel = getSerialConsistencyLevel();
|
||||
int pageSize = getPageSize();
|
||||
|
||||
if (getFetchSize() > -1 && statement.getPageSize() < 0) {
|
||||
statementToUse = statementToUse.setPageSize(getFetchSize());
|
||||
if (consistencyLevel != null) {
|
||||
statementToUse = statementToUse.setConsistencyLevel(consistencyLevel);
|
||||
}
|
||||
|
||||
if (consistencyLevel != null && statementToUse.getConsistencyLevel() == null) {
|
||||
statementToUse = statementToUse.setConsistencyLevel(getConsistencyLevel());
|
||||
if (serialConsistencyLevel != null) {
|
||||
statementToUse = statementToUse.setSerialConsistencyLevel(serialConsistencyLevel);
|
||||
}
|
||||
|
||||
if (pageSize > -1) {
|
||||
statementToUse = statementToUse.setPageSize(pageSize);
|
||||
}
|
||||
|
||||
statementToUse = getExecutionProfileResolver().apply(statementToUse);
|
||||
|
||||
return statementToUse;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,9 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.oss.driver.api.core.ConsistencyLevel;
|
||||
import com.datastax.oss.driver.api.core.retry.RetryPolicy;
|
||||
|
||||
/**
|
||||
* Cassandra Write Options are an extension to {@link QueryOptions} for write operations. {@link WriteOptions}allow
|
||||
* Cassandra Write Options are an extension to {@link QueryOptions} for write operations. {@link WriteOptions} allow
|
||||
* tuning of various query options on a per-request level. Only options that are set are applied to queries.
|
||||
*
|
||||
* @author David Webb
|
||||
@@ -44,41 +43,11 @@ public class WriteOptions extends QueryOptions {
|
||||
private final Duration ttl;
|
||||
private final @Nullable Long timestamp;
|
||||
|
||||
/**
|
||||
* Creates new {@link WriteOptions} for the given {@link ConsistencyLevel} and {@link RetryPolicy}.
|
||||
*
|
||||
* @param consistencyLevel the consistency level, may be {@literal null}.
|
||||
* @param retryPolicy the retry policy, may be {@literal null}.
|
||||
* @deprecated since 2.0, use {@link #builder()} or {@link #empty()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public WriteOptions(@Nullable ConsistencyLevel consistencyLevel, @Nullable RetryPolicy retryPolicy) {
|
||||
this(consistencyLevel, retryPolicy, null);
|
||||
}
|
||||
protected WriteOptions(@Nullable ConsistencyLevel consistencyLevel, ExecutionProfileResolver executionProfileResolver,
|
||||
@Nullable Integer pageSize, @Nullable ConsistencyLevel serialConsistencyLevel, Duration timeout, Duration ttl,
|
||||
@Nullable Long timestamp, @Nullable Boolean tracing) {
|
||||
|
||||
/**
|
||||
* Creates new {@link WriteOptions} for the given {@link ConsistencyLevel}, {@link RetryPolicy} and {@code ttl}.
|
||||
*
|
||||
* @param consistencyLevel the consistency level, may be {@literal null}.
|
||||
* @param retryPolicy the retry policy, may be {@literal null}.
|
||||
* @param ttl the ttl, may be {@literal null}.
|
||||
* @deprecated since 2.0, use {@link #builder()}.
|
||||
*/
|
||||
@Deprecated
|
||||
public WriteOptions(@Nullable ConsistencyLevel consistencyLevel, @Nullable RetryPolicy retryPolicy,
|
||||
@Nullable Integer ttl) {
|
||||
|
||||
super(consistencyLevel, retryPolicy);
|
||||
|
||||
this.ttl = ttl == null ? Duration.ofMillis(-1) : Duration.ofSeconds(ttl);
|
||||
this.timestamp = null;
|
||||
}
|
||||
|
||||
protected WriteOptions(@Nullable ConsistencyLevel consistencyLevel, @Nullable RetryPolicy retryPolicy,
|
||||
@Nullable Boolean tracing, @Nullable Integer fetchSize, Duration readTimeout, Duration ttl,
|
||||
@Nullable Long timestamp) {
|
||||
|
||||
super(consistencyLevel, retryPolicy, tracing, fetchSize, readTimeout);
|
||||
super(consistencyLevel, executionProfileResolver, pageSize, serialConsistencyLevel, timeout, tracing);
|
||||
|
||||
this.ttl = ttl;
|
||||
this.timestamp = timestamp;
|
||||
@@ -154,7 +123,7 @@ public class WriteOptions extends QueryOptions {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#consistencyLevel(com.datastax.driver.core.ConsistencyLevel)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#consistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel)
|
||||
*/
|
||||
@Override
|
||||
public WriteOptionsBuilder consistencyLevel(ConsistencyLevel consistencyLevel) {
|
||||
@@ -164,13 +133,20 @@ public class WriteOptions extends QueryOptions {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#retryPolicy(com.datastax.oss.driver.api.core.retry.RetryPolicy)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#executionProfile(String)
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public WriteOptionsBuilder retryPolicy(RetryPolicy driverRetryPolicy) {
|
||||
public WriteOptionsBuilder executionProfile(String profileName) {
|
||||
super.executionProfile(profileName);
|
||||
return this;
|
||||
}
|
||||
|
||||
super.retryPolicy(driverRetryPolicy);
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#executionProfile(org.springframework.data.cassandra.core.cql.ExecutionProfileResolver)
|
||||
*/
|
||||
@Override
|
||||
public WriteOptionsBuilder executionProfile(ExecutionProfileResolver executionProfileResolver) {
|
||||
super.executionProfile(executionProfileResolver);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -217,6 +193,15 @@ public class WriteOptions extends QueryOptions {
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#serialConsistencyLevel(com.datastax.oss.driver.api.core.ConsistencyLevel)
|
||||
*/
|
||||
@Override
|
||||
public WriteOptionsBuilder serialConsistencyLevel(ConsistencyLevel consistencyLevel) {
|
||||
super.serialConsistencyLevel(consistencyLevel);
|
||||
return this;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.cassandra.core.cql.QueryOptions.QueryOptionsBuilder#readTimeout(java.time.Duration)
|
||||
*/
|
||||
@@ -318,8 +303,8 @@ public class WriteOptions extends QueryOptions {
|
||||
* @return a new {@link WriteOptions} with the configured values
|
||||
*/
|
||||
public WriteOptions build() {
|
||||
return new WriteOptions(this.consistencyLevel, this.retryPolicy, this.tracing, this.pageSize, this.timeout,
|
||||
this.ttl, this.timestamp);
|
||||
return new WriteOptions(this.consistencyLevel, this.executionProfileResolver, this.pageSize,
|
||||
this.serialConsistencyLevel, this.timeout, this.ttl, this.timestamp, this.tracing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ public class StatementBuilder<S extends BuildableQuery> {
|
||||
|
||||
private List<BuilderRunnable<S>> queryActions = new ArrayList<>();
|
||||
private List<Consumer<SimpleStatementBuilder>> onBuild = new ArrayList<>();
|
||||
private List<UnaryOperator<SimpleStatement>> onBuilt = new ArrayList<>();
|
||||
|
||||
private StatementBuilder(S statement) {
|
||||
this.statement = statement;
|
||||
@@ -138,6 +139,22 @@ public class StatementBuilder<S extends BuildableQuery> {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add behavior after the {@link SimpleStatement} has been built. The {@link UnaryOperator} gets invoked with a
|
||||
* {@link SimpleStatement} allowing association of the final statement with additional settings. The
|
||||
* {@link UnaryOperator} is applied on {@link #build()}.
|
||||
*
|
||||
* @param mappingFunction the {@link UnaryOperator} function that gets notified on {@link #build()}.
|
||||
* @return {@code this} {@link StatementBuilder}.
|
||||
*/
|
||||
public StatementBuilder<S> transform(UnaryOperator<SimpleStatement> mappingFunction) {
|
||||
|
||||
Assert.notNull(mappingFunction, "Mapping function must not be null");
|
||||
|
||||
onBuilt.add(mappingFunction);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link SimpleStatement statement} by applying builder and bind functions using the default
|
||||
* {@link CodecRegistry} and {@link ParameterHandling#INLINE} parameter rendering.
|
||||
@@ -182,7 +199,7 @@ public class StatementBuilder<S extends BuildableQuery> {
|
||||
statement = runnable.run(statement, termFactory);
|
||||
}
|
||||
|
||||
return onBuild(statement.builder()).build();
|
||||
return StatementBuilder.this.build(statement.builder());
|
||||
}
|
||||
|
||||
if (parameterHandling == ParameterHandling.BY_INDEX) {
|
||||
@@ -197,7 +214,7 @@ public class StatementBuilder<S extends BuildableQuery> {
|
||||
statement = runnable.run(statement, termFactory);
|
||||
}
|
||||
|
||||
return onBuild(statement.builder().addPositionalValues(values)).build();
|
||||
return build(statement.builder().addPositionalValues(values));
|
||||
}
|
||||
|
||||
if (parameterHandling == ParameterHandling.BY_NAME) {
|
||||
@@ -216,12 +233,23 @@ public class StatementBuilder<S extends BuildableQuery> {
|
||||
SimpleStatementBuilder builder = statement.builder();
|
||||
values.forEach(builder::addNamedValue);
|
||||
|
||||
return onBuild(builder).build();
|
||||
return build(builder);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException(String.format("ParameterHandling %s not supported", parameterHandling));
|
||||
}
|
||||
|
||||
private SimpleStatement build(SimpleStatementBuilder builder) {
|
||||
|
||||
SimpleStatement statmentToUse = onBuild(builder).build();
|
||||
|
||||
for (UnaryOperator<SimpleStatement> operator : onBuilt) {
|
||||
statmentToUse = operator.apply(statmentToUse);
|
||||
}
|
||||
|
||||
return statmentToUse;
|
||||
}
|
||||
|
||||
private static Term toLiteralTerms(@Nullable Object value, CodecRegistry codecRegistry) {
|
||||
|
||||
if (value instanceof List) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
@@ -24,6 +24,8 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.data.cassandra.core.query.Query;
|
||||
|
||||
import com.datastax.oss.driver.api.core.DefaultConsistencyLevel;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DeleteOptions}.
|
||||
*
|
||||
@@ -31,7 +33,7 @@ import org.springframework.data.cassandra.core.query.Query;
|
||||
*/
|
||||
public class DeleteOptionsUnitTests {
|
||||
|
||||
@Test // DATACASS-575
|
||||
@Test // DATACASS-575, DATACASS-708
|
||||
public void shouldConfigureDeleteOptions() {
|
||||
|
||||
Instant now = Instant.ofEpochSecond(1234);
|
||||
@@ -40,8 +42,11 @@ public class DeleteOptionsUnitTests {
|
||||
.ttl(10) //
|
||||
.timestamp(now) //
|
||||
.withIfExists() //
|
||||
.executionProfile("foo") //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.LOCAL_ONE) //
|
||||
.build();
|
||||
|
||||
|
||||
assertThat(deleteOptions.getTtl()).isEqualTo(Duration.ofSeconds(10));
|
||||
assertThat(deleteOptions.getTimestamp()).isEqualTo(now.toEpochMilli() * 1000);
|
||||
assertThat(deleteOptions.isIfExists()).isTrue();
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.time.ZoneOffset;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.datastax.oss.driver.api.core.DefaultConsistencyLevel;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link InsertOptions}.
|
||||
*
|
||||
@@ -32,12 +34,18 @@ import org.junit.Test;
|
||||
*/
|
||||
public class InsertOptionsUnitTests {
|
||||
|
||||
@Test // DATACASS-250, DATACASS-155
|
||||
@Test // DATACASS-250, DATACASS-155, DATACASS-708
|
||||
public void shouldConfigureInsertOptions() {
|
||||
|
||||
Instant now = LocalDateTime.now().toInstant(ZoneOffset.UTC);
|
||||
|
||||
InsertOptions insertOptions = InsertOptions.builder().ttl(10).timestamp(now).withIfNotExists().build();
|
||||
InsertOptions insertOptions = InsertOptions.builder() //
|
||||
.ttl(10) //
|
||||
.timestamp(now) //
|
||||
.withIfNotExists() //
|
||||
.executionProfile("foo") //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.LOCAL_ONE) //
|
||||
.build();
|
||||
|
||||
assertThat(insertOptions.getTtl()).isEqualTo(Duration.ofSeconds(10));
|
||||
assertThat(insertOptions.getTimestamp()).isEqualTo(now.toEpochMilli() * 1000);
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.cassandra.core.convert.CassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.convert.UpdateMapper;
|
||||
import org.springframework.data.cassandra.core.cql.QueryOptions;
|
||||
import org.springframework.data.cassandra.core.cql.WriteOptions;
|
||||
import org.springframework.data.cassandra.core.cql.util.StatementBuilder;
|
||||
import org.springframework.data.cassandra.core.cql.util.StatementBuilder.ParameterHandling;
|
||||
@@ -42,6 +43,8 @@ import org.springframework.data.cassandra.core.query.Update;
|
||||
import org.springframework.data.cassandra.domain.Group;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
import com.datastax.oss.driver.api.core.DefaultConsistencyLevel;
|
||||
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
|
||||
import com.datastax.oss.driver.api.querybuilder.delete.Delete;
|
||||
import com.datastax.oss.driver.api.querybuilder.insert.RegularInsert;
|
||||
import com.datastax.oss.driver.api.querybuilder.select.Select;
|
||||
@@ -71,6 +74,22 @@ public class StatementFactoryUnitTests {
|
||||
assertThat(select.build(ParameterHandling.INLINE).getQuery()).isEqualTo("SELECT * FROM group");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
public void selectShouldApplyQueryOptions() {
|
||||
|
||||
QueryOptions queryOptions = QueryOptions.builder() //
|
||||
.executionProfile("foo") //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.QUORUM) //
|
||||
.build();
|
||||
|
||||
StatementBuilder<Select> select = statementFactory.select(Query.empty().queryOptions(queryOptions),
|
||||
converter.getMappingContext().getRequiredPersistentEntity(Group.class));
|
||||
|
||||
SimpleStatement statement = select.build();
|
||||
assertThat(statement.getExecutionProfileName()).isEqualTo("foo");
|
||||
assertThat(statement.getSerialConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.QUORUM);
|
||||
}
|
||||
|
||||
@Test // DATACASS-343
|
||||
public void shouldMapSelectQueryWithColumnsAndCriteria() {
|
||||
|
||||
@@ -149,6 +168,25 @@ public class StatementFactoryUnitTests {
|
||||
.isEqualTo("DELETE FROM group USING TIMESTAMP 1234 WHERE foo='bar'");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
public void deleteShouldApplyQueryOptions() {
|
||||
|
||||
Person person = new Person();
|
||||
person.id = "foo";
|
||||
|
||||
QueryOptions queryOptions = QueryOptions.builder() //
|
||||
.executionProfile("foo") //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.QUORUM) //
|
||||
.build();
|
||||
|
||||
StatementBuilder<Delete> delete = statementFactory.delete(Query.empty().queryOptions(queryOptions),
|
||||
converter.getMappingContext().getRequiredPersistentEntity(Group.class));
|
||||
|
||||
SimpleStatement statement = delete.build();
|
||||
assertThat(statement.getExecutionProfileName()).isEqualTo("foo");
|
||||
assertThat(statement.getSerialConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.QUORUM);
|
||||
}
|
||||
|
||||
@Test // DATACASS-656
|
||||
public void shouldCreateInsert() {
|
||||
|
||||
@@ -160,6 +198,24 @@ public class StatementFactoryUnitTests {
|
||||
assertThat(insert.build(ParameterHandling.INLINE).getQuery()).isEqualTo("INSERT INTO person (id) VALUES ('foo')");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
public void insertShouldApplyQueryOptions() {
|
||||
|
||||
Person person = new Person();
|
||||
person.id = "foo";
|
||||
|
||||
WriteOptions queryOptions = WriteOptions.builder() //
|
||||
.executionProfile("foo") //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.QUORUM) //
|
||||
.build();
|
||||
|
||||
StatementBuilder<RegularInsert> insert = statementFactory.insert(person, queryOptions);
|
||||
|
||||
SimpleStatement statement = insert.build();
|
||||
assertThat(statement.getExecutionProfileName()).isEqualTo("foo");
|
||||
assertThat(statement.getSerialConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.QUORUM);
|
||||
}
|
||||
|
||||
@Test // DATACASS-656
|
||||
public void shouldCreateInsertIfNotExists() {
|
||||
|
||||
@@ -387,6 +443,24 @@ public class StatementFactoryUnitTests {
|
||||
.isEqualTo("UPDATE person SET first_name='baz' WHERE foo='bar' IF foo='baz'");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
public void updateShouldApplyQueryOptions() {
|
||||
|
||||
UpdateOptions queryOptions = UpdateOptions.builder() //
|
||||
.executionProfile("foo") //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.QUORUM) //
|
||||
.build();
|
||||
|
||||
Query query = Query.query(Criteria.where("foo").is("bar")).queryOptions(queryOptions);
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(query,
|
||||
Update.empty().set("firstName", "baz"), personEntity);
|
||||
|
||||
SimpleStatement statement = update.build();
|
||||
assertThat(statement.getExecutionProfileName()).isEqualTo("foo");
|
||||
assertThat(statement.getSerialConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.QUORUM);
|
||||
}
|
||||
|
||||
@Test // DATACASS-656
|
||||
public void shouldCreateSetUpdateFromObject() {
|
||||
|
||||
@@ -470,6 +544,27 @@ public class StatementFactoryUnitTests {
|
||||
.isEqualTo("UPDATE person SET first_name=NULL, list=[], map=NULL, number=NULL, set_col={} WHERE id='foo'");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
public void updateObjectShouldApplyQueryOptions() {
|
||||
|
||||
WriteOptions queryOptions = WriteOptions.builder() //
|
||||
.executionProfile("foo") //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.QUORUM) //
|
||||
.build();
|
||||
|
||||
Person person = new Person();
|
||||
person.id = "foo";
|
||||
person.set = Collections.emptySet();
|
||||
person.list = Collections.emptyList();
|
||||
|
||||
StatementBuilder<com.datastax.oss.driver.api.querybuilder.update.Update> update = statementFactory.update(person,
|
||||
queryOptions);
|
||||
|
||||
SimpleStatement statement = update.build();
|
||||
assertThat(statement.getExecutionProfileName()).isEqualTo("foo");
|
||||
assertThat(statement.getSerialConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.QUORUM);
|
||||
}
|
||||
|
||||
@Test // DATACASS-512
|
||||
public void shouldCreateCountQuery() {
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
@@ -24,6 +24,8 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.data.cassandra.core.query.Query;
|
||||
|
||||
import com.datastax.oss.driver.api.core.DefaultConsistencyLevel;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link UpdateOptions}.
|
||||
*
|
||||
@@ -32,7 +34,7 @@ import org.springframework.data.cassandra.core.query.Query;
|
||||
*/
|
||||
public class UpdateOptionsUnitTests {
|
||||
|
||||
@Test // DATACASS-250, DATACASS-155
|
||||
@Test // DATACASS-250, DATACASS-155, DATACASS-708
|
||||
public void shouldConfigureUpdateOptions() {
|
||||
|
||||
Instant now = Instant.ofEpochSecond(1234);
|
||||
@@ -40,6 +42,8 @@ public class UpdateOptionsUnitTests {
|
||||
UpdateOptions updateOptions = UpdateOptions.builder() //
|
||||
.ttl(10) //
|
||||
.timestamp(now) //
|
||||
.executionProfile("foo") //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.LOCAL_ONE) //
|
||||
.withIfExists() //
|
||||
.build();
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.data.cassandra.CassandraConnectionFailureException;
|
||||
import org.springframework.data.cassandra.CassandraInvalidQueryException;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.scheduling.annotation.AsyncResult;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
||||
@@ -121,7 +122,7 @@ public class AsyncCqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void executeCqlShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, asyncCqlTemplate -> {
|
||||
doTestStrings(asyncCqlTemplate -> {
|
||||
|
||||
asyncCqlTemplate.execute("SELECT * from USERS");
|
||||
|
||||
@@ -143,7 +144,7 @@ public class AsyncCqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryForResultSetShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, asyncCqlTemplate -> {
|
||||
doTestStrings(asyncCqlTemplate -> {
|
||||
|
||||
AsyncResultSet resultSet = getUninterruptibly(asyncCqlTemplate.queryForResultSet("SELECT * from USERS"));
|
||||
|
||||
@@ -155,7 +156,7 @@ public class AsyncCqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryWithResultSetExtractorShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, asyncCqlTemplate -> {
|
||||
doTestStrings(asyncCqlTemplate -> {
|
||||
|
||||
List<String> rows = getUninterruptibly(
|
||||
asyncCqlTemplate.query("SELECT * from USERS", (row, index) -> row.getString(0)));
|
||||
@@ -298,7 +299,7 @@ public class AsyncCqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void executeStatementShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, asyncCqlTemplate -> {
|
||||
doTestStrings(asyncCqlTemplate -> {
|
||||
|
||||
asyncCqlTemplate.execute(SimpleStatement.newInstance("SELECT * from USERS"));
|
||||
|
||||
@@ -320,7 +321,7 @@ public class AsyncCqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryForResultStatementSetShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, asyncCqlTemplate -> {
|
||||
doTestStrings(asyncCqlTemplate -> {
|
||||
|
||||
ListenableFuture<AsyncResultSet> future = asyncCqlTemplate
|
||||
.queryForResultSet(SimpleStatement.newInstance("SELECT * from USERS"));
|
||||
@@ -333,7 +334,7 @@ public class AsyncCqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryWithResultSetStatementExtractorShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, asyncCqlTemplate -> {
|
||||
doTestStrings(asyncCqlTemplate -> {
|
||||
|
||||
ListenableFuture<List<String>> future = asyncCqlTemplate.query(SimpleStatement.newInstance("SELECT * from USERS"),
|
||||
(row, index) -> row.getString(0));
|
||||
@@ -482,7 +483,7 @@ public class AsyncCqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryPreparedStatementWithCallbackShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, asyncCqlTemplate -> {
|
||||
doTestStrings(asyncCqlTemplate -> {
|
||||
|
||||
ListenableFuture<CompletionStage<AsyncResultSet>> futureOfFuture = asyncCqlTemplate.execute("SELECT * from USERS",
|
||||
(session, ps) -> session.executeAsync(ps.bind("A")));
|
||||
@@ -498,7 +499,7 @@ public class AsyncCqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void executePreparedStatementWithCallbackShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, asyncCqlTemplate -> {
|
||||
doTestStrings(asyncCqlTemplate -> {
|
||||
|
||||
when(this.preparedStatement.bind("White")).thenReturn(this.boundStatement);
|
||||
when(this.resultSet.wasApplied()).thenReturn(true);
|
||||
@@ -756,7 +757,11 @@ public class AsyncCqlTemplateUnitTests {
|
||||
assertThat(getUninterruptibly(future)).isTrue();
|
||||
}
|
||||
|
||||
private <T> void doTestStrings(Integer fetchSize, ConsistencyLevel consistencyLevel,
|
||||
private void doTestStrings(Consumer<AsyncCqlTemplate> cqlTemplateConsumer) {
|
||||
doTestStrings(null, null, cqlTemplateConsumer);
|
||||
}
|
||||
|
||||
private void doTestStrings(@Nullable Integer fetchSize, @Nullable ConsistencyLevel consistencyLevel,
|
||||
Consumer<AsyncCqlTemplate> cqlTemplateConsumer) {
|
||||
|
||||
String[] results = { "Walter", "Hank", " Jesse" };
|
||||
@@ -783,24 +788,12 @@ public class AsyncCqlTemplateUnitTests {
|
||||
|
||||
Statement statement = statementArgumentCaptor.getValue();
|
||||
|
||||
if (statement instanceof PreparedStatement || statement instanceof BoundStatement) {
|
||||
if (fetchSize != null) {
|
||||
assertThat(statement.getPageSize()).isEqualTo(fetchSize.intValue());
|
||||
}
|
||||
|
||||
if (fetchSize != null) {
|
||||
verify(statement).setPageSize(fetchSize.intValue());
|
||||
}
|
||||
|
||||
if (consistencyLevel != null) {
|
||||
verify(statement).setConsistencyLevel(consistencyLevel);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (fetchSize != null) {
|
||||
assertThat(statement.getPageSize()).isEqualTo(fetchSize.intValue());
|
||||
}
|
||||
|
||||
if (consistencyLevel != null) {
|
||||
assertThat(statement.getConsistencyLevel()).isEqualTo(consistencyLevel);
|
||||
}
|
||||
if (consistencyLevel != null) {
|
||||
assertThat(statement.getConsistencyLevel()).isEqualTo(consistencyLevel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.data.cassandra.CassandraConnectionFailureException;
|
||||
import org.springframework.data.cassandra.CassandraInvalidQueryException;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.datastax.oss.driver.api.core.ConsistencyLevel;
|
||||
import com.datastax.oss.driver.api.core.CqlSession;
|
||||
@@ -112,7 +113,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void executeCqlShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, cqlTemplate -> {
|
||||
doTestStrings(cqlTemplate -> {
|
||||
|
||||
cqlTemplate.execute("SELECT * from USERS");
|
||||
|
||||
@@ -123,7 +124,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void executeCqlWithArgumentsShouldCallExecution() {
|
||||
|
||||
doTestStrings(5, DefaultConsistencyLevel.ONE, cqlTemplate -> {
|
||||
doTestStrings(5, DefaultConsistencyLevel.ONE, null, "foo", cqlTemplate -> {
|
||||
|
||||
cqlTemplate.execute("SELECT * from USERS");
|
||||
|
||||
@@ -134,7 +135,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryForResultSetShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, cqlTemplate -> {
|
||||
doTestStrings(cqlTemplate -> {
|
||||
|
||||
ResultSet resultSet = cqlTemplate.queryForResultSet("SELECT * from USERS");
|
||||
|
||||
@@ -146,7 +147,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryWithResultSetExtractorShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, cqlTemplate -> {
|
||||
doTestStrings(cqlTemplate -> {
|
||||
|
||||
List<String> rows = cqlTemplate.query("SELECT * from USERS", (row, index) -> row.getString(0));
|
||||
|
||||
@@ -158,7 +159,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryWithResultSetExtractorWithArgumentsShouldCallExecution() {
|
||||
|
||||
doTestStrings(5, ConsistencyLevel.ONE, cqlTemplate -> {
|
||||
doTestStrings(5, ConsistencyLevel.ONE, ConsistencyLevel.EACH_QUORUM, "foo", cqlTemplate -> {
|
||||
|
||||
List<String> rows = cqlTemplate.query("SELECT * from USERS", (row, index) -> row.getString(0));
|
||||
|
||||
@@ -274,7 +275,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void executeStatementShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, cqlTemplate -> {
|
||||
doTestStrings(cqlTemplate -> {
|
||||
|
||||
cqlTemplate.execute(SimpleStatement.newInstance("SELECT * from USERS"));
|
||||
|
||||
@@ -285,7 +286,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void executeStatementWithArgumentsShouldCallExecution() {
|
||||
|
||||
doTestStrings(5, ConsistencyLevel.ONE, cqlTemplate -> {
|
||||
doTestStrings(5, ConsistencyLevel.ONE, null, "foo", cqlTemplate -> {
|
||||
|
||||
cqlTemplate.execute(SimpleStatement.newInstance("SELECT * from USERS"));
|
||||
|
||||
@@ -296,7 +297,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryForResultStatementSetShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, cqlTemplate -> {
|
||||
doTestStrings(cqlTemplate -> {
|
||||
|
||||
ResultSet resultSet = cqlTemplate.queryForResultSet(SimpleStatement.newInstance("SELECT * from USERS"));
|
||||
|
||||
@@ -308,7 +309,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryWithResultSetStatementExtractorShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, cqlTemplate -> {
|
||||
doTestStrings(cqlTemplate -> {
|
||||
|
||||
List<String> result = cqlTemplate.query(SimpleStatement.newInstance("SELECT * from USERS"),
|
||||
(row, index) -> row.getString(0));
|
||||
@@ -321,7 +322,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryWithResultSetStatementExtractorWithArgumentsShouldCallExecution() {
|
||||
|
||||
doTestStrings(5, ConsistencyLevel.ONE, cqlTemplate -> {
|
||||
doTestStrings(5, ConsistencyLevel.ONE, null, "foo", cqlTemplate -> {
|
||||
|
||||
List<String> result = cqlTemplate.query(SimpleStatement.newInstance("SELECT * from USERS"),
|
||||
(row, index) -> row.getString(0));
|
||||
@@ -441,7 +442,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void queryPreparedStatementWithCallbackShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, cqlTemplate -> {
|
||||
doTestStrings(cqlTemplate -> {
|
||||
|
||||
ResultSet resultSet = cqlTemplate.execute("SELECT * from USERS", (session, ps) -> session.execute(ps.bind("A")));
|
||||
|
||||
@@ -456,7 +457,7 @@ public class CqlTemplateUnitTests {
|
||||
@Test // DATACASS-292
|
||||
public void executePreparedStatementWithCallbackShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, cqlTemplate -> {
|
||||
doTestStrings(cqlTemplate -> {
|
||||
|
||||
when(this.preparedStatement.bind("White")).thenReturn(this.boundStatement);
|
||||
when(this.resultSet.wasApplied()).thenReturn(true);
|
||||
@@ -678,7 +679,12 @@ public class CqlTemplateUnitTests {
|
||||
assertThat(applied).isTrue();
|
||||
}
|
||||
|
||||
private <T> void doTestStrings(Integer fetchSize, ConsistencyLevel consistencyLevel,
|
||||
private void doTestStrings(Consumer<CqlTemplate> cqlTemplateConsumer) {
|
||||
doTestStrings(null, null, null, null, cqlTemplateConsumer);
|
||||
}
|
||||
|
||||
private void doTestStrings(@Nullable Integer fetchSize, @Nullable ConsistencyLevel consistencyLevel,
|
||||
@Nullable ConsistencyLevel serialConsistencyLevel, @Nullable String executionProfile,
|
||||
Consumer<CqlTemplate> cqlTemplateConsumer) {
|
||||
|
||||
String[] results = { "Walter", "Hank", " Jesse" };
|
||||
@@ -701,6 +707,14 @@ public class CqlTemplateUnitTests {
|
||||
template.setConsistencyLevel(consistencyLevel);
|
||||
}
|
||||
|
||||
if (serialConsistencyLevel != null) {
|
||||
template.setSerialConsistencyLevel(serialConsistencyLevel);
|
||||
}
|
||||
|
||||
if (executionProfile != null) {
|
||||
template.setExecutionProfile(executionProfile);
|
||||
}
|
||||
|
||||
cqlTemplateConsumer.accept(template);
|
||||
|
||||
ArgumentCaptor<Statement> statementArgumentCaptor = ArgumentCaptor.forClass(Statement.class);
|
||||
@@ -708,24 +722,20 @@ public class CqlTemplateUnitTests {
|
||||
|
||||
Statement statement = statementArgumentCaptor.getValue();
|
||||
|
||||
if (statement instanceof PreparedStatement || statement instanceof BoundStatement) {
|
||||
if (fetchSize != null) {
|
||||
assertThat(statement.getPageSize()).isEqualTo(fetchSize.intValue());
|
||||
}
|
||||
|
||||
if (fetchSize != null) {
|
||||
verify(statement).setPageSize(fetchSize.intValue());
|
||||
}
|
||||
if (consistencyLevel != null) {
|
||||
assertThat(statement.getConsistencyLevel()).isEqualTo(consistencyLevel);
|
||||
}
|
||||
|
||||
if (consistencyLevel != null) {
|
||||
verify(statement).setConsistencyLevel(consistencyLevel);
|
||||
}
|
||||
} else {
|
||||
if (serialConsistencyLevel != null) {
|
||||
assertThat(statement.getSerialConsistencyLevel()).isEqualTo(serialConsistencyLevel);
|
||||
}
|
||||
|
||||
if (fetchSize != null) {
|
||||
assertThat(statement.getPageSize()).isEqualTo(fetchSize.intValue());
|
||||
}
|
||||
|
||||
if (consistencyLevel != null) {
|
||||
assertThat(statement.getConsistencyLevel()).isEqualTo(consistencyLevel);
|
||||
}
|
||||
if (executionProfile != null) {
|
||||
assertThat(statement.getExecutionProfileName()).isEqualTo(executionProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.core.cql;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.datastax.oss.driver.api.core.config.DriverExecutionProfile;
|
||||
import com.datastax.oss.driver.api.core.cql.Statement;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ExecutionProfileResolver}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class ExecutionProfileResolverUnitTests {
|
||||
|
||||
@Test // DATACASS-708
|
||||
public void shouldSetProfileName() {
|
||||
|
||||
Statement statement = mock(Statement.class);
|
||||
|
||||
ExecutionProfileResolver.from("foo").apply(statement);
|
||||
|
||||
verify(statement).setExecutionProfileName("foo");
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
public void shouldSetProfileObject() {
|
||||
|
||||
Statement statement = mock(Statement.class);
|
||||
DriverExecutionProfile profile = mock(DriverExecutionProfile.class);
|
||||
|
||||
ExecutionProfileResolver.from(profile).apply(statement);
|
||||
|
||||
verify(statement).setExecutionProfile(profile);
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public class QueryOptionsUnitTests {
|
||||
|
||||
assertThat(queryOptions.getClass()).isEqualTo(QueryOptions.class);
|
||||
assertThat(queryOptions.getConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.ANY);
|
||||
assertThat(queryOptions.getReadTimeout()).isEqualTo(Duration.ofSeconds(1));
|
||||
assertThat(queryOptions.getTimeout()).isEqualTo(Duration.ofSeconds(1));
|
||||
assertThat(queryOptions.getPageSize()).isEqualTo(10);
|
||||
assertThat(queryOptions.getTracing()).isTrue();
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class QueryOptionsUnitTests {
|
||||
assertThat(mutated).isNotSameAs(queryOptions);
|
||||
assertThat(mutated.getClass()).isEqualTo(QueryOptions.class);
|
||||
assertThat(mutated.getConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.ANY);
|
||||
assertThat(mutated.getReadTimeout()).isEqualTo(Duration.ofSeconds(5));
|
||||
assertThat(mutated.getTimeout()).isEqualTo(Duration.ofSeconds(5));
|
||||
assertThat(mutated.getPageSize()).isEqualTo(10);
|
||||
assertThat(mutated.getTracing()).isTrue();
|
||||
}
|
||||
|
||||
@@ -39,16 +39,24 @@ public class QueryOptionsUtilUnitTests {
|
||||
|
||||
@Mock SimpleStatement simpleStatement;
|
||||
|
||||
@Test // DATACASS-202
|
||||
@Test // DATACASS-202, DATACASS-708
|
||||
public void addPreparedStatementOptionsShouldAddDriverQueryOptions() {
|
||||
|
||||
when(simpleStatement.setConsistencyLevel(any())).thenReturn(simpleStatement);
|
||||
when(simpleStatement.setSerialConsistencyLevel(any())).thenReturn(simpleStatement);
|
||||
when(simpleStatement.setExecutionProfileName(anyString())).thenReturn(simpleStatement);
|
||||
|
||||
QueryOptions queryOptions = QueryOptions.builder() //
|
||||
.consistencyLevel(DefaultConsistencyLevel.EACH_QUORUM) //
|
||||
.serialConsistencyLevel(DefaultConsistencyLevel.LOCAL_ONE) //
|
||||
.executionProfile("foo") //
|
||||
.build();
|
||||
|
||||
QueryOptionsUtil.addQueryOptions(simpleStatement, queryOptions);
|
||||
|
||||
verify(simpleStatement).setConsistencyLevel(DefaultConsistencyLevel.EACH_QUORUM);
|
||||
verify(simpleStatement).setSerialConsistencyLevel(DefaultConsistencyLevel.LOCAL_ONE);
|
||||
verify(simpleStatement).setExecutionProfileName("foo");
|
||||
}
|
||||
|
||||
@Test // DATACASS-202
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.springframework.data.cassandra.ReactiveResultSet;
|
||||
import org.springframework.data.cassandra.ReactiveSession;
|
||||
import org.springframework.data.cassandra.ReactiveSessionFactory;
|
||||
import org.springframework.data.cassandra.core.cql.session.DefaultReactiveSessionFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.datastax.oss.driver.api.core.ConsistencyLevel;
|
||||
import com.datastax.oss.driver.api.core.DefaultConsistencyLevel;
|
||||
@@ -135,7 +136,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void executeCqlShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, reactiveCqlTemplate -> {
|
||||
doTestStrings(reactiveCqlTemplate -> {
|
||||
|
||||
reactiveCqlTemplate.execute("SELECT * from USERS").as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
@@ -146,7 +147,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void executeCqlWithArgumentsShouldCallExecution() {
|
||||
|
||||
doTestStrings(5, DefaultConsistencyLevel.ONE, reactiveCqlTemplate -> {
|
||||
doTestStrings(5, DefaultConsistencyLevel.ONE, null, "foo", reactiveCqlTemplate -> {
|
||||
|
||||
reactiveCqlTemplate.execute("SELECT * from USERS").as(StepVerifier::create) //
|
||||
.expectNextCount(1) //
|
||||
@@ -159,7 +160,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void queryForResultSetShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, reactiveCqlTemplate -> {
|
||||
doTestStrings(reactiveCqlTemplate -> {
|
||||
|
||||
Mono<ReactiveResultSet> mono = reactiveCqlTemplate.queryForResultSet("SELECT * from USERS");
|
||||
|
||||
@@ -172,7 +173,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void queryWithResultSetExtractorShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, reactiveCqlTemplate -> {
|
||||
doTestStrings(reactiveCqlTemplate -> {
|
||||
|
||||
Flux<String> flux = reactiveCqlTemplate.query("SELECT * from USERS", (row, index) -> row.getString(0));
|
||||
|
||||
@@ -185,7 +186,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void queryWithResultSetExtractorWithArgumentsShouldCallExecution() {
|
||||
|
||||
doTestStrings(5, ConsistencyLevel.ONE, reactiveCqlTemplate -> {
|
||||
doTestStrings(5, ConsistencyLevel.ONE, null, "foo", reactiveCqlTemplate -> {
|
||||
|
||||
Flux<String> flux = reactiveCqlTemplate.query("SELECT * from USERS", (row, index) -> row.getString(0));
|
||||
|
||||
@@ -336,7 +337,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void executeStatementShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, reactiveCqlTemplate -> {
|
||||
doTestStrings(reactiveCqlTemplate -> {
|
||||
|
||||
reactiveCqlTemplate.execute(SimpleStatement.newInstance("SELECT * from USERS")).as(StepVerifier::create) //
|
||||
.expectNextCount(1) //
|
||||
@@ -349,7 +350,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void executeStatementWithArgumentsShouldCallExecution() {
|
||||
|
||||
doTestStrings(5, ConsistencyLevel.ONE, reactiveCqlTemplate -> {
|
||||
doTestStrings(5, ConsistencyLevel.ONE, DefaultConsistencyLevel.EACH_QUORUM, "foo", reactiveCqlTemplate -> {
|
||||
|
||||
reactiveCqlTemplate.execute(SimpleStatement.newInstance("SELECT * from USERS")).as(StepVerifier::create) //
|
||||
.expectNextCount(1) //
|
||||
@@ -362,7 +363,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void queryForResultStatementSetShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, reactiveCqlTemplate -> {
|
||||
doTestStrings(reactiveCqlTemplate -> {
|
||||
|
||||
reactiveCqlTemplate.queryForResultSet(SimpleStatement.newInstance("SELECT * from USERS"))
|
||||
.flatMapMany(ReactiveResultSet::rows).as(StepVerifier::create) //
|
||||
@@ -376,7 +377,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void queryWithResultSetStatementExtractorShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, reactiveCqlTemplate -> {
|
||||
doTestStrings(reactiveCqlTemplate -> {
|
||||
|
||||
Flux<String> flux = reactiveCqlTemplate.query(SimpleStatement.newInstance("SELECT * from USERS"),
|
||||
(row, index) -> row.getString(0));
|
||||
@@ -390,7 +391,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void queryWithResultSetStatementExtractorWithArgumentsShouldCallExecution() {
|
||||
|
||||
doTestStrings(5, ConsistencyLevel.ONE, reactiveCqlTemplate -> {
|
||||
doTestStrings(5, ConsistencyLevel.ONE, null, "foo", reactiveCqlTemplate -> {
|
||||
|
||||
Flux<String> flux = reactiveCqlTemplate.query(SimpleStatement.newInstance("SELECT * from USERS"),
|
||||
(row, index) -> row.getString(0));
|
||||
@@ -533,7 +534,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void queryPreparedStatementWithCallbackShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, reactiveCqlTemplate -> {
|
||||
doTestStrings(reactiveCqlTemplate -> {
|
||||
|
||||
Flux<Row> flux = reactiveCqlTemplate.execute("SELECT * from USERS", (session, ps) -> {
|
||||
|
||||
@@ -547,7 +548,7 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
@Test // DATACASS-335
|
||||
public void executePreparedStatementWithCallbackShouldCallExecution() {
|
||||
|
||||
doTestStrings(null, null, reactiveCqlTemplate -> {
|
||||
doTestStrings(reactiveCqlTemplate -> {
|
||||
|
||||
Mono<Boolean> applied = reactiveCqlTemplate.execute("UPDATE users SET name = ?", "White");
|
||||
when(this.preparedStatement.bind("White")).thenReturn(this.boundStatement);
|
||||
@@ -779,7 +780,12 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
verify(session, times(2)).execute(boundStatement);
|
||||
}
|
||||
|
||||
private <T> void doTestStrings(Integer fetchSize, ConsistencyLevel consistencyLevel,
|
||||
private void doTestStrings(Consumer<ReactiveCqlTemplate> cqlTemplateConsumer) {
|
||||
doTestStrings(null, null, null, null, cqlTemplateConsumer);
|
||||
}
|
||||
|
||||
private void doTestStrings(@Nullable Integer fetchSize, @Nullable ConsistencyLevel consistencyLevel,
|
||||
@Nullable ConsistencyLevel serialConsistencyLevel, @Nullable String executionProfile,
|
||||
Consumer<ReactiveCqlTemplate> cqlTemplateConsumer) {
|
||||
|
||||
String[] results = { "Walter", "Hank", " Jesse" };
|
||||
@@ -801,6 +807,14 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
template.setConsistencyLevel(consistencyLevel);
|
||||
}
|
||||
|
||||
if (serialConsistencyLevel != null) {
|
||||
template.setSerialConsistencyLevel(serialConsistencyLevel);
|
||||
}
|
||||
|
||||
if (executionProfile != null) {
|
||||
template.setExecutionProfile(executionProfile);
|
||||
}
|
||||
|
||||
cqlTemplateConsumer.accept(template);
|
||||
|
||||
ArgumentCaptor<Statement> statementArgumentCaptor = ArgumentCaptor.forClass(Statement.class);
|
||||
@@ -808,24 +822,20 @@ public class ReactiveCqlTemplateUnitTests {
|
||||
|
||||
Statement statement = statementArgumentCaptor.getValue();
|
||||
|
||||
if (statement instanceof PreparedStatement || statement instanceof BoundStatement) {
|
||||
if (fetchSize != null) {
|
||||
assertThat(statement.getPageSize()).isEqualTo(fetchSize.intValue());
|
||||
}
|
||||
|
||||
if (fetchSize != null) {
|
||||
verify(statement).setPageSize(fetchSize.intValue());
|
||||
}
|
||||
if (consistencyLevel != null) {
|
||||
assertThat(statement.getConsistencyLevel()).isEqualTo(consistencyLevel);
|
||||
}
|
||||
|
||||
if (consistencyLevel != null) {
|
||||
verify(statement).setConsistencyLevel(consistencyLevel);
|
||||
}
|
||||
} else {
|
||||
if (serialConsistencyLevel != null) {
|
||||
assertThat(statement.getSerialConsistencyLevel()).isEqualTo(serialConsistencyLevel);
|
||||
}
|
||||
|
||||
if (fetchSize != null) {
|
||||
assertThat(statement.getPageSize()).isEqualTo(fetchSize.intValue());
|
||||
}
|
||||
|
||||
if (consistencyLevel != null) {
|
||||
assertThat(statement.getConsistencyLevel()).isEqualTo(consistencyLevel);
|
||||
}
|
||||
if (executionProfile != null) {
|
||||
assertThat(statement.getExecutionProfileName()).isEqualTo(executionProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class WriteOptionsUnitTests {
|
||||
assertThat(writeOptions.getTtl()).isEqualTo(Duration.ofSeconds(123));
|
||||
assertThat(writeOptions.getTimestamp()).isEqualTo(1519000753);
|
||||
assertThat(writeOptions.getConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.ANY);
|
||||
assertThat(writeOptions.getReadTimeout()).isEqualTo(Duration.ofMillis(1));
|
||||
assertThat(writeOptions.getTimeout()).isEqualTo(Duration.ofMillis(1));
|
||||
assertThat(writeOptions.getPageSize()).isEqualTo(10);
|
||||
assertThat(writeOptions.getTracing()).isTrue();
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public class WriteOptionsUnitTests {
|
||||
|
||||
WriteOptions writeOptions = WriteOptions.builder().timeout(Duration.ofMinutes(1)).build();
|
||||
|
||||
assertThat(writeOptions.getReadTimeout()).isEqualTo(Duration.ofSeconds(60));
|
||||
assertThat(writeOptions.getTimeout()).isEqualTo(Duration.ofSeconds(60));
|
||||
assertThat(writeOptions.getPageSize()).isNull();
|
||||
assertThat(writeOptions.getTracing()).isNull();
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class WriteOptionsUnitTests {
|
||||
assertThat(mutated.getTtl()).isEqualTo(Duration.ofSeconds(123));
|
||||
assertThat(mutated.getTimestamp()).isEqualTo(now.toEpochMilli() * 1000);
|
||||
assertThat(mutated.getConsistencyLevel()).isEqualTo(DefaultConsistencyLevel.ANY);
|
||||
assertThat(mutated.getReadTimeout()).isEqualTo(Duration.ofMillis(100));
|
||||
assertThat(mutated.getTimeout()).isEqualTo(Duration.ofMillis(100));
|
||||
assertThat(mutated.getPageSize()).isEqualTo(10);
|
||||
assertThat(mutated.getTracing()).isTrue();
|
||||
}
|
||||
|
||||
@@ -137,5 +137,17 @@ public class StatementBuilderUnitTests {
|
||||
|
||||
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM person");
|
||||
assertThat(statement.getPositionalValues()).hasSize(1);
|
||||
|
||||
}
|
||||
|
||||
@Test // DATACASS-708
|
||||
public void shouldTransformBuiltStatement() {
|
||||
|
||||
SimpleStatement statement = StatementBuilder.of(QueryBuilder.selectFrom("person").all())
|
||||
.transform(statement1 -> statement1.setExecutionProfileName("foo"))
|
||||
.build(StatementBuilder.ParameterHandling.BY_NAME);
|
||||
|
||||
assertThat(statement.getQuery()).isEqualTo("SELECT * FROM person");
|
||||
assertThat(statement.getExecutionProfileName()).isEqualTo("foo");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +171,10 @@ Keyspace creation via `CqlSessionFactoryBean` (`cassandra:session`) is not affec
|
||||
=== Utilities
|
||||
|
||||
* `GuavaListenableFutureAdapter`
|
||||
* `QueryOptions` and `WriteOptions` constructor taking `ConsistencyLevel` and `RetryPolicy` arguments.
|
||||
Use the builder in conjunction of execution profiles as replacement.
|
||||
* `CassandraAccessor.setRetryPolicy(…)` and `ReactiveCqlTemplate.setRetryPolicy(…)` methods.
|
||||
Use execution profiles as replacement.
|
||||
|
||||
=== Namespace support
|
||||
|
||||
|
||||
Reference in New Issue
Block a user