Skip to content

Commit

Permalink
Bump couchbase sdk to 3_4_3. (#1663)
Browse files Browse the repository at this point in the history
Requires some refactoring around @Stability.Internal APIs.
Also fixed a test to get it to pass.

Closes #1661,#1662.
  • Loading branch information
mikereiche authored Feb 17, 2023
1 parent ddd1974 commit 02afaee
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 51 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
</parent>

<properties>
<couchbase>3.4.1</couchbase>
<couchbase.osgi>3.4.1</couchbase.osgi>
<couchbase>3.4.3</couchbase>
<couchbase.osgi>3.4.3</couchbase.osgi>
<springdata.commons>3.1.0-SNAPSHOT</springdata.commons>
<java-module-name>spring.data.couchbase</java-module-name>
<hibernate.validator>7.0.1.Final</hibernate.validator>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.springframework.data.couchbase.core;

import com.couchbase.client.core.api.query.CoreQueryContext;
import com.couchbase.client.core.io.CollectionIdentifier;
import reactor.core.publisher.Flux;

import java.util.Optional;
Expand All @@ -28,7 +30,6 @@
import org.springframework.data.couchbase.core.support.TemplateUtils;
import org.springframework.util.Assert;

import com.couchbase.client.core.deps.com.fasterxml.jackson.databind.node.ObjectNode;
import com.couchbase.client.java.ReactiveScope;
import com.couchbase.client.java.json.JsonObject;
import com.couchbase.client.java.query.QueryOptions;
Expand Down Expand Up @@ -100,11 +101,10 @@ public Flux<RemoveResult> all() {
} else {
TransactionQueryOptions opts = OptionsBuilder
.buildTransactionQueryOptions(buildQueryOptions(pArgs.getOptions()));
ObjectNode convertedOptions = com.couchbase.client.java.transactions.internal.OptionsUtil
.createTransactionOptions(pArgs.getScope() == null ? null : rs, statement, opts);
CoreQueryContext queryContext = CollectionIdentifier.DEFAULT_SCOPE.equals(rs.name()) ? null : CoreQueryContext.of(rs.bucketName(), rs.name());
return transactionContext.get().getCore()
.queryBlocking(statement, template.getBucketName(), pArgs.getScope(), convertedOptions, false)
.flatMapIterable(result -> result.rows).map(row -> {
.queryBlocking(statement, queryContext, opts.builder().build(), false)
.flatMapIterable(result -> result.collectRows()).map(row -> {
JsonObject json = JsonObject.fromJson(row.data());
return new RemoveResult(json.getString(TemplateUtils.SELECT_ID), json.getLong(TemplateUtils.SELECT_CAS),
Optional.empty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ public QueryOptions getOptions() {
return options;
}

// for logging only
public JsonObject n1ql() {
JsonObject query = JsonObject.create().put("statement", expression.toString());
options.build().injectParams(query);
query.put("options", OptionsBuilder.getQueryOpts(options.build()));
return query;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.springframework.data.couchbase.core.query;

import static com.couchbase.client.core.util.Validators.notNull;
import static org.springframework.data.couchbase.core.query.Meta.MetaKey.RETRY_STRATEGY;
import static org.springframework.data.couchbase.core.query.Meta.MetaKey.SCAN_CONSISTENCY;
import static org.springframework.data.couchbase.core.query.Meta.MetaKey.TIMEOUT;
Expand All @@ -24,9 +25,13 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import com.couchbase.client.core.api.query.CoreQueryScanConsistency;
import com.couchbase.client.core.classic.query.ClassicCoreQueryOps;
import com.couchbase.client.core.error.InvalidArgumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotatedElementUtils;
Expand Down Expand Up @@ -67,21 +72,21 @@ public class OptionsBuilder {
static QueryOptions buildQueryOptions(Query query, QueryOptions options, QueryScanConsistency scanConsistency) {
options = options != null ? options : QueryOptions.queryOptions();
if (query.getParameters() != null) {
if (query.getParameters() instanceof JsonArray) {
if (query.getParameters() instanceof JsonArray && !((JsonArray) query.getParameters()).isEmpty()) {
options.parameters((JsonArray) query.getParameters());
} else {
} else if( query.getParameters() instanceof JsonObject && !((JsonObject)query.getParameters()).isEmpty()){
options.parameters((JsonObject) query.getParameters());
}
}

Meta meta = query.getMeta() != null ? query.getMeta() : new Meta();
QueryOptions.Built optsBuilt = options.build();
JsonObject optsJson = getQueryOpts(optsBuilt);

QueryScanConsistency metaQueryScanConsistency = meta.get(SCAN_CONSISTENCY) != null
? ((ScanConsistency) meta.get(SCAN_CONSISTENCY)).query()
: null;
QueryScanConsistency qsc = fromFirst(QueryScanConsistency.NOT_BOUNDED, query.getScanConsistency(),
getScanConsistency(optsJson), scanConsistency, metaQueryScanConsistency);
scanConsistency(optsBuilt), scanConsistency, metaQueryScanConsistency);
Duration timeout = fromFirst(Duration.ofSeconds(0), getTimeout(optsBuilt), meta.get(TIMEOUT));
RetryStrategy retryStrategy = fromFirst(null, getRetryStrategy(optsBuilt), meta.get(RETRY_STRATEGY));

Expand All @@ -100,6 +105,21 @@ static QueryOptions buildQueryOptions(Query query, QueryOptions options, QuerySc
return options;
}

private static QueryScanConsistency scanConsistency(QueryOptions.Built optsBuilt){
CoreQueryScanConsistency scanConsistency = optsBuilt.scanConsistency();
if (scanConsistency == null){
return null;
}
switch (scanConsistency) {
case NOT_BOUNDED:
return QueryScanConsistency.NOT_BOUNDED;
case REQUEST_PLUS:
return QueryScanConsistency.REQUEST_PLUS;
default:
throw new InvalidArgumentException("Unknown scan consistency type " + scanConsistency, null, null);
}
}

public static TransactionQueryOptions buildTransactionQueryOptions(QueryOptions options) {
QueryOptions.Built built = options.build();
TransactionQueryOptions txOptions = TransactionQueryOptions.queryOptions();
Expand All @@ -110,8 +130,21 @@ public static TransactionQueryOptions buildTransactionQueryOptions(QueryOptions
throw new IllegalArgumentException("QueryOptions.flexIndex is not supported in a transaction");
}

Object value = optsJson.get("args");
if(value instanceof JsonObject){
txOptions.parameters((JsonObject)value);
}else if(value instanceof JsonArray) {
txOptions.parameters((JsonArray) value);
} else if(value != null) {
throw InvalidArgumentException.fromMessage(
"non-null args property was neither JsonObject(namedParameters) nor JsonArray(positionalParameters) "
+ value);
}

for (Map.Entry<String, Object> entry : optsJson.toMap().entrySet()) {
txOptions.raw(entry.getKey(), entry.getValue());
if(!entry.getKey().equals("args")) {
txOptions.raw(entry.getKey(), entry.getValue());
}
}

if (LOG.isDebugEnabled()) {
Expand Down Expand Up @@ -370,10 +403,8 @@ static String toString(MutateInOptions o) {
return s.toString();
}

private static JsonObject getQueryOpts(QueryOptions.Built optsBuilt) {
JsonObject jo = JsonObject.create();
optsBuilt.injectParams(jo);
return jo;
public static JsonObject getQueryOpts(QueryOptions.Built optsBuilt) {
return JsonObject.fromJson(ClassicCoreQueryOps.convertOptions(optsBuilt).toString().getBytes());
}

/**
Expand All @@ -396,18 +427,6 @@ public static <T> T fromFirst(T deflt, Object... choice) {
return chosen;
}

private static QueryScanConsistency getScanConsistency(JsonObject opts) {
String str = opts.getString("scan_consistency");
if ("at_plus".equals(str)) {
return null;
}
return str == null ? null : QueryScanConsistency.valueOf(str.toUpperCase());
}

private static JsonObject getScanVectors(JsonObject opts) {
return opts.getObject("scan_vectors");
}

private static Duration getTimeout(QueryOptions.Built optsBuilt) {
Optional<Duration> timeout = optsBuilt.timeout();
return timeout.isPresent() ? timeout.get() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
import com.couchbase.client.java.query.QueryScanConsistency;

/**
* KV tests Theses tests rely on a cb server running.
* KV test - these tests rely on a cb server running.
*
* @author Michael Nitschinger
* @author Michael Reiche
Expand All @@ -81,11 +81,11 @@ public void beforeEach() {
@Test
void findByIdWithLock() {
try {
User user = new User(UUID.randomUUID().toString(), "user1", "user1");
User user = new User("1", "user1", "user1");

couchbaseTemplate.upsertById(User.class).one(user);

User foundUser = couchbaseTemplate.findById(User.class).withLock(Duration.ofSeconds(2)).one(user.getId());
User foundUser = couchbaseTemplate.findById(User.class).withLock(Duration.ofSeconds(5)).one(user.getId());
user.setVersion(foundUser.getVersion());// version will have changed
assertEquals(user, foundUser);

Expand All @@ -94,8 +94,15 @@ void findByIdWithLock() {
);
assertTrue(exception.retryReasons().contains(RetryReason.KV_LOCKED), "should have been locked");
} finally {
sleepSecs(2);
couchbaseTemplate.removeByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
for(int i=0; i< 10; i++) {
sleepSecs(2);
try {
couchbaseTemplate.removeByQuery(User.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
break;
} catch (Exception e) {
e.printStackTrace(); // gives IndexFailureException if the lock is still active
}
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
import java.util.List;
import java.util.Locale;

import com.couchbase.client.core.deps.com.fasterxml.jackson.databind.node.ArrayNode;
import com.couchbase.client.java.query.QueryOptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity;
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
import org.springframework.data.couchbase.core.query.OptionsBuilder;
import org.springframework.data.couchbase.core.query.Query;
import org.springframework.data.couchbase.domain.Person;
import org.springframework.data.couchbase.domain.PersonRepository;
Expand Down Expand Up @@ -119,18 +122,17 @@ void queryParametersArray() throws Exception {
QueryMethod queryMethod = new QueryMethod(method, new DefaultRepositoryMetadata(UserRepository.class),
new SpelAwareProxyProjectionFactory());
Query expected = (new Query()).addCriteria(where(i("firstname")).in("Oliver", "Charles"));
JsonArray parameters = JsonArray.create().add(JsonArray.create().add("Oliver").add("Charles"));
QueryOptions expectedQOptions = QueryOptions.queryOptions().parameters(parameters);
N1qlQueryCreator creator = new N1qlQueryCreator(tree,
getAccessor(getParameters(method), new Object[] { new Object[] { "Oliver", "Charles" } }), queryMethod,
converter, bucketName);
Query query = creator.createQuery();

// Query expected = (new Query()).addCriteria(where("firstname").in("Oliver", "Charles"));
assertEquals(" WHERE `firstname` in $1", query.export(new int[1]));
JsonObject expectedOptions = JsonObject.create();
expected.buildQueryOptions(null, null).build().injectParams(expectedOptions);
JsonObject actualOptions = JsonObject.create();
expected.buildQueryOptions(null, null).build().injectParams(actualOptions);
assertEquals(expectedOptions.removeKey("client_context_id"), actualOptions.removeKey("client_context_id"));
ArrayNode expectedOptions = expected.buildQueryOptions(expectedQOptions, null).build().positionalParameters();
ArrayNode actualOptions = query.buildQueryOptions(null, null).build().positionalParameters();
assertEquals(expectedOptions.toString(), actualOptions.toString());
}

@Test
Expand All @@ -148,12 +150,12 @@ void queryParametersJsonArray() throws Exception {
Query query = creator.createQuery();

Query expected = (new Query()).addCriteria(where(i("firstname")).in("Oliver", "Charles"));
JsonArray parameters = JsonArray.create().add(JsonArray.create().add("Oliver").add("Charles"));
QueryOptions expectedQOptions = QueryOptions.queryOptions().parameters(parameters);
assertEquals(" WHERE `firstname` in $1", query.export(new int[1]));
JsonObject expectedOptions = JsonObject.create();
expected.buildQueryOptions(null, null).build().injectParams(expectedOptions);
JsonObject actualOptions = JsonObject.create();
expected.buildQueryOptions(null, null).build().injectParams(actualOptions);
assertEquals(expectedOptions.removeKey("client_context_id"), actualOptions.removeKey("client_context_id"));
ArrayNode expectedOptions = expected.buildQueryOptions(expectedQOptions, null).build().positionalParameters();
ArrayNode actualOptions = query.buildQueryOptions(null, null).build().positionalParameters();
assertEquals(expectedOptions.toString(), actualOptions.toString());
}

@Test
Expand All @@ -171,13 +173,13 @@ void queryParametersList() throws Exception {
Query query = creator.createQuery();

Query expected = (new Query()).addCriteria(where(i("firstname")).in("Oliver", "Charles"));
JsonArray parameters = JsonArray.create().add(JsonArray.create().add("Oliver").add("Charles"));
QueryOptions expectedQOptions = QueryOptions.queryOptions().parameters(parameters);

assertEquals(" WHERE `firstname` in $1", query.export(new int[1]));
JsonObject expectedOptions = JsonObject.create();
expected.buildQueryOptions(null, null).build().injectParams(expectedOptions);
JsonObject actualOptions = JsonObject.create();
expected.buildQueryOptions(null, null).build().injectParams(actualOptions);
assertEquals(expectedOptions.removeKey("client_context_id"), actualOptions.removeKey("client_context_id"));
ArrayNode expectedOptions = expected.buildQueryOptions(expectedQOptions, null).build().positionalParameters();
ArrayNode actualOptions = query.buildQueryOptions(null, null).build().positionalParameters();
assertEquals(expectedOptions.toString(), actualOptions.toString());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public static CompletableFuture<Void> createPrimaryIndex(Cluster cluster, String
options.timeout(Duration.ofSeconds(300));
options.ignoreIfExists(true);
final CreatePrimaryQueryIndexOptions.Built builtOpts = options.build();
final String indexName = builtOpts.indexName().orElse(null);
final String indexName = builtOpts.indexName();

String keyspace = "default:`" + bucketName + "`.`" + scopeName + "`.`" + collectionName + "`";
String statement = "CREATE PRIMARY INDEX ";
Expand Down

0 comments on commit 02afaee

Please sign in to comment.