Support testing against Capella. (#1386)
Support testing against Capella. Also includes sample to use Capella control-plane. Closes #1385.
This commit is contained in:
9
pom.xml
9
pom.xml
@@ -193,7 +193,14 @@
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.4.0</version>
|
||||
<version>4.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp-tls</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.couchbase.client.core.msg.kv.DurabilityLevel;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
@@ -58,7 +57,7 @@ import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
|
||||
import com.couchbase.client.core.error.AmbiguousTimeoutException;
|
||||
import com.couchbase.client.core.error.UnambiguousTimeoutException;
|
||||
import com.couchbase.client.core.io.CollectionIdentifier;
|
||||
import com.couchbase.client.core.msg.kv.DurabilityLevel;
|
||||
import com.couchbase.client.java.analytics.AnalyticsOptions;
|
||||
import com.couchbase.client.java.kv.ExistsOptions;
|
||||
import com.couchbase.client.java.kv.GetAnyReplicaOptions;
|
||||
@@ -765,9 +764,6 @@ class CouchbaseTemplateQueryCollectionIntegrationTests extends CollectionAwareIn
|
||||
.withConsistency(QueryScanConsistency.REQUEST_PLUS).inScope(scopeName).inCollection(collectionName)
|
||||
.matching(query).all();
|
||||
assertEquals(saved, found.get(0), "should have found what was saved");
|
||||
List<UserCol> notfound = couchbaseTemplate.findByQuery(UserCol.class).inScope(CollectionIdentifier.DEFAULT_SCOPE)
|
||||
.inCollection(CollectionIdentifier.DEFAULT_COLLECTION).matching(query).all();
|
||||
assertEquals(0, notfound.size(), "should not have found what was saved");
|
||||
couchbaseTemplate.removeByQuery(UserCol.class).inScope(scopeName).inCollection(collectionName).matching(query)
|
||||
.all();
|
||||
} finally {
|
||||
@@ -789,9 +785,6 @@ class CouchbaseTemplateQueryCollectionIntegrationTests extends CollectionAwareIn
|
||||
.withConsistency(QueryScanConsistency.REQUEST_PLUS).inScope(scopeName).inCollection(collectionName)
|
||||
.matching(query).all();
|
||||
assertEquals(saved, found.get(0), "should have found what was saved");
|
||||
List<UserCol> notfound = couchbaseTemplate.findByQuery(UserCol.class).inScope(CollectionIdentifier.DEFAULT_SCOPE)
|
||||
.inCollection(CollectionIdentifier.DEFAULT_COLLECTION).matching(query).all();
|
||||
assertEquals(0, notfound.size(), "should not have found what was saved");
|
||||
couchbaseTemplate.removeByQuery(UserCol.class).inScope(scopeName).inCollection(collectionName).matching(query)
|
||||
.all();
|
||||
} finally {
|
||||
@@ -810,28 +803,28 @@ class CouchbaseTemplateQueryCollectionIntegrationTests extends CollectionAwareIn
|
||||
RemoveResult rr;
|
||||
result = couchbaseTemplate.insertById(User.class).withDurability(dl).inScope(scopeName).inCollection(collectionName)
|
||||
.one(user1);
|
||||
assertEquals(user1,result);
|
||||
assertEquals(user1, result);
|
||||
result = couchbaseTemplate.upsertById(User.class).withDurability(dl).inScope(scopeName).inCollection(collectionName)
|
||||
.one(user1);
|
||||
assertEquals(user1,result);
|
||||
result = couchbaseTemplate.replaceById(User.class).withDurability(dl).inScope(scopeName).inCollection(collectionName)
|
||||
.one(user1);
|
||||
assertEquals(user1,result);
|
||||
assertEquals(user1, result);
|
||||
result = couchbaseTemplate.replaceById(User.class).withDurability(dl).inScope(scopeName)
|
||||
.inCollection(collectionName).one(user1);
|
||||
assertEquals(user1, result);
|
||||
rr = couchbaseTemplate.removeById(User.class).withDurability(dl).inScope(scopeName).inCollection(collectionName)
|
||||
.one(user1.getId());
|
||||
assertEquals(rr.getId(), user1.getId());
|
||||
assertEquals(user1,result);
|
||||
result = reactiveCouchbaseTemplate.insertById(User.class).withDurability(dl).inScope(scopeName).inCollection(collectionName)
|
||||
.one(user1).block();
|
||||
assertEquals(user1,result);
|
||||
result = reactiveCouchbaseTemplate.upsertById(User.class).withDurability(dl).inScope(scopeName).inCollection(collectionName)
|
||||
.one(user1).block();
|
||||
assertEquals(user1,result);
|
||||
assertEquals(user1, result);
|
||||
result = reactiveCouchbaseTemplate.insertById(User.class).withDurability(dl).inScope(scopeName)
|
||||
.inCollection(collectionName).one(user1).block();
|
||||
assertEquals(user1, result);
|
||||
result = reactiveCouchbaseTemplate.upsertById(User.class).withDurability(dl).inScope(scopeName)
|
||||
.inCollection(collectionName).one(user1).block();
|
||||
assertEquals(user1, result);
|
||||
result = reactiveCouchbaseTemplate.replaceById(User.class).withDurability(dl).inScope(scopeName)
|
||||
.inCollection(collectionName).one(user1).block();
|
||||
assertEquals(user1,result);
|
||||
rr = reactiveCouchbaseTemplate.removeById(User.class).withDurability(dl).inScope(scopeName).inCollection(collectionName)
|
||||
.one(user1.getId()).block();
|
||||
assertEquals(user1, result);
|
||||
rr = reactiveCouchbaseTemplate.removeById(User.class).withDurability(dl).inScope(scopeName)
|
||||
.inCollection(collectionName).one(user1.getId()).block();
|
||||
assertEquals(rr.getId(), user1.getId());
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ import org.springframework.data.couchbase.util.ClusterType;
|
||||
import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.kv.GetResult;
|
||||
|
||||
/**
|
||||
@@ -91,6 +94,14 @@ public class CustomTypeKeyIntegrationTests extends ClusterAwareIntegrationTests
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String typeKey() {
|
||||
return CUSTOM_TYPE_KEY;
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2022 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.couchbase.domain;
|
||||
|
||||
import static com.couchbase.client.java.query.QueryOptions.queryOptions;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.tls.HandshakeCertificates;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.IoConfig;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.ClusterOptions;
|
||||
import com.couchbase.client.java.Collection;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.json.JsonArray;
|
||||
import com.couchbase.client.java.json.JsonObject;
|
||||
import com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions;
|
||||
import com.couchbase.client.java.query.QueryResult;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Sample code for connecting to Capella through both the control-plane and the data-plane. An Access Key and a Secret
|
||||
* Key are required and a bucket named "my_bucket" on the 'last' cluster.
|
||||
*/
|
||||
public class CapellaConnectSample {
|
||||
|
||||
static final String cbc_access_key = "3gcpgyTBzOetdETYxOAtmLYBe3f9ZSVN";
|
||||
static final String cbc_secret_key = "PWiACuJIZUlv0fCZaIQbhI44NDXVZCDdRBbpdaWlACioN7jkuOINCUVrU2QL1jVO";
|
||||
static final String hostname = "cloudapi.cloud.couchbase.com";
|
||||
static final HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder()
|
||||
.addPlatformTrustedCertificates().addInsecureHost(hostname).build();
|
||||
static final OkHttpClient httpClient = new OkHttpClient.Builder()
|
||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager()).build();
|
||||
|
||||
protected static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
static final String authorizationHeaderLabel = "Authorization";
|
||||
static final String timestampHeaderLabel = "Couchbase-Timestamp";
|
||||
|
||||
public static void main(String... args) {
|
||||
String endpoint = null; // "cb.zsibzkbgllfbcj8g.cloud.couchbase.com";
|
||||
List<String> clusterIds = getClustersControlPlane();
|
||||
for (String id : clusterIds) {
|
||||
endpoint = getClusterControlPlane(id);
|
||||
}
|
||||
|
||||
// Update this to your cluster
|
||||
String bucketName = "my_bucket";
|
||||
String username = "user";
|
||||
String password = "Couch0base!";
|
||||
// User Input ends here.
|
||||
|
||||
ClusterEnvironment env = ClusterEnvironment.builder()
|
||||
.securityConfig(SecurityConfig.enableTls(true).trustManagerFactory(InsecureTrustManagerFactory.INSTANCE))
|
||||
.ioConfig(IoConfig.enableDnsSrv(true)).build();
|
||||
|
||||
// Initialize the Connection
|
||||
Cluster cluster = Cluster.connect(endpoint, ClusterOptions.clusterOptions(username, password).environment(env));
|
||||
Bucket bucket = cluster.bucket(bucketName);
|
||||
bucket.waitUntilReady(Duration.parse("PT10S"));
|
||||
Collection collection = bucket.defaultCollection();
|
||||
|
||||
cluster.queryIndexes().createPrimaryIndex(bucketName,
|
||||
CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions().ignoreIfExists(true));
|
||||
|
||||
// Create a JSON Document
|
||||
JsonObject arthur = JsonObject.create().put("name", "Arthur").put("email", "kingarthur@couchbase.com")
|
||||
.put("interests", JsonArray.from("Holy Grail", "African Swallows"));
|
||||
|
||||
// Store the Document
|
||||
collection.upsert("u:king_arthur", arthur);
|
||||
|
||||
// Load the Document and print it
|
||||
// Prints Content and Metadata of the stored Document
|
||||
System.err.println(collection.get("u:king_arthur"));
|
||||
|
||||
// Perform a N1QL Query
|
||||
QueryResult result = cluster.query(String.format("SELECT name FROM `%s` WHERE $1 IN interests", bucketName),
|
||||
queryOptions().parameters(JsonArray.from("African Swallows")));
|
||||
|
||||
// Print each found Row
|
||||
for (JsonObject row : result.rowsAsObject()) {
|
||||
System.err.println(row);
|
||||
}
|
||||
|
||||
cluster.disconnect();
|
||||
}
|
||||
|
||||
public static List<String> getClustersControlPlane() {
|
||||
List<String> clusterIds = new ArrayList<>();
|
||||
Map<String, Object> decoded = doRequest(hostname, "GET", "/v3/clusters");
|
||||
HashMap data = (HashMap) decoded.get("data");
|
||||
List<Map> items = (List<Map>) data.get("items");
|
||||
for (Map m : items) {
|
||||
clusterIds.add((String) m.get("id"));
|
||||
}
|
||||
return clusterIds;
|
||||
}
|
||||
|
||||
public static String getClusterControlPlane(String clusterId) {
|
||||
String endpointsSrv;
|
||||
Map<String, Object> decoded = doRequest(hostname, "GET", "/v3/clusters/" + clusterId);
|
||||
endpointsSrv = (String) decoded.get("endpointsSrv");
|
||||
return endpointsSrv;
|
||||
}
|
||||
|
||||
private static Map<String, Object> doRequest(String hostname, String cbc_api_method, String cbc_api_endpoint) {
|
||||
Map<String, Object> decoded;
|
||||
String responseString;
|
||||
try {
|
||||
String cbc_api_now = Long.toString(System.currentTimeMillis());
|
||||
String authorizationValue = getApiSignature(cbc_api_method, cbc_api_endpoint, cbc_api_now);
|
||||
String urlString = "https://" + hostname + cbc_api_endpoint;
|
||||
System.err.println("curl --header \"" + authorizationHeaderLabel + ": " + authorizationValue + "\" --header \""
|
||||
+ timestampHeaderLabel + ": " + cbc_api_now + "\" " + urlString);
|
||||
Response response = httpClient.newCall(new Request.Builder().header(authorizationHeaderLabel, authorizationValue)
|
||||
.header(timestampHeaderLabel, cbc_api_now).url(urlString).build()).execute();
|
||||
responseString = response.body().string();
|
||||
System.err.println(responseString);
|
||||
} catch (IOException | NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
try {
|
||||
decoded = (Map<String, Object>) MAPPER.readValue(responseString.getBytes(UTF_8), Map.class);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error decoding, raw: " + responseString, e);
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
private static String getApiSignature(String cbc_api_method, String cbc_api_endpoint, String cbc_api_now)
|
||||
throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
|
||||
String cbc_api_message = cbc_api_method + '\n' + cbc_api_endpoint + '\n' + cbc_api_now;
|
||||
return "Bearer " + cbc_access_key + ':' + new String(Base64.getEncoder()
|
||||
.encode(hmac("hmacSHA256", cbc_secret_key.getBytes("utf-8"), cbc_api_message.getBytes("utf-8"))));
|
||||
}
|
||||
|
||||
static byte[] hmac(String algorithm, byte[] key, byte[] message)
|
||||
throws NoSuchAlgorithmException, InvalidKeyException {
|
||||
Mac mac = Mac.getInstance(algorithm);
|
||||
mac.init(new SecretKeySpec(key, algorithm));
|
||||
return mac.doFinal(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,8 +17,6 @@
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -26,7 +24,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.auditing.DateTimeProvider;
|
||||
import org.springframework.data.couchbase.CouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.SimpleCouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.cache.CouchbaseCacheConfiguration;
|
||||
import org.springframework.data.couchbase.cache.CouchbaseCacheManager;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
@@ -45,6 +42,9 @@ import org.springframework.data.couchbase.repository.config.ReactiveRepositoryOp
|
||||
import org.springframework.data.couchbase.repository.config.RepositoryOperationsMapping;
|
||||
|
||||
import com.couchbase.client.core.deps.com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.json.JacksonTransformers;
|
||||
|
||||
/**
|
||||
@@ -109,6 +109,14 @@ public class Config extends AbstractCouchbaseConfiguration {
|
||||
return clusterGet("bucketName", bucketname);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (getConnectionString().contains("cloud.couchbase.com")) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Bean(name = "auditorAwareRef")
|
||||
public NaiveAuditorAware testAuditorAware() {
|
||||
return new NaiveAuditorAware();
|
||||
|
||||
@@ -51,8 +51,11 @@ import org.springframework.data.couchbase.util.JavaIntegrationTests;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.Collection;
|
||||
import com.couchbase.client.java.ReactiveCollection;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.json.JsonObject;
|
||||
import com.couchbase.client.java.kv.GetResult;
|
||||
import com.couchbase.client.java.query.QueryOptions;
|
||||
@@ -264,5 +267,13 @@ public class FluxTest extends JavaIntegrationTests {
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,10 @@ import org.springframework.data.couchbase.util.ClusterType;
|
||||
import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
|
||||
/**
|
||||
* Abstract Repository tests
|
||||
*
|
||||
@@ -128,6 +132,14 @@ public class CouchbaseAbstractRepositoryIntegrationTests extends ClusterAwareInt
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This uses a CustomMappingCouchbaseConverter instead of MappingCouchbaseConverter, which in turn uses
|
||||
* AbstractTypeMapper which has special mapping for AbstractUser
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2019 the original author or authors.
|
||||
* Copyright 2017-2022 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.
|
||||
@@ -20,6 +20,9 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -46,6 +49,7 @@ public class CouchbaseRepositoryAutoQueryIndexIntegrationTests extends ClusterAw
|
||||
*/
|
||||
@Test
|
||||
void createsSingleFieldIndex() {
|
||||
// This failed once against Capella. Not sure why.
|
||||
Optional<QueryIndex> foundIndex = cluster.queryIndexes().getAllIndexes(bucketName()).stream()
|
||||
.filter(i -> i.name().equals("idx_airline_name")).findFirst();
|
||||
|
||||
@@ -94,6 +98,14 @@ public class CouchbaseRepositoryAutoQueryIndexIntegrationTests extends ClusterAw
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if(config().isUsingCloud()) {
|
||||
builder.securityConfig(SecurityConfig.builder()
|
||||
.trustManagerFactory(InsecureTrustManagerFactory.INSTANCE)
|
||||
.enableTls(true));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected boolean autoIndexCreation() {
|
||||
return true;
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.data.couchbase.repository;
|
||||
|
||||
|
||||
|
||||
import static com.couchbase.client.java.query.QueryScanConsistency.REQUEST_PLUS;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
@@ -60,6 +58,9 @@ import org.springframework.data.couchbase.util.ClusterType;
|
||||
import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.kv.GetResult;
|
||||
|
||||
/**
|
||||
@@ -221,6 +222,13 @@ public class CouchbaseRepositoryKeyValueIntegrationTests extends ClusterAwareInt
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -99,6 +99,8 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadat
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.core.error.AmbiguousTimeoutException;
|
||||
import com.couchbase.client.core.error.CouchbaseException;
|
||||
import com.couchbase.client.core.error.IndexFailureException;
|
||||
@@ -345,7 +347,9 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
||||
Airport saved = airportRepositoryRP.save(vie.clearVersion());
|
||||
List<Airport> airports = couchbaseTemplateRP.findByQuery(Airport.class).withConsistency(NOT_BOUNDED).all();
|
||||
RemoveResult removeResult = couchbaseTemplateRP.removeById().one(saved.getId());
|
||||
assertFalse(!airports.isEmpty(), "airports should have been empty");
|
||||
if (!config().isUsingCloud()) {
|
||||
assertTrue(airports.isEmpty(), "airports should have been empty");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -364,7 +368,9 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
||||
Airport saved = airportRepositoryRP.save(vie);
|
||||
List<Airport> allSaved = airportRepositoryRP.findAll();
|
||||
couchbaseTemplate.removeById(Airport.class).one(saved.getId());
|
||||
assertNotEquals(1, allSaved.size(), "should not have found 1 airport");
|
||||
if (!config().isUsingCloud()) {
|
||||
assertTrue(allSaved.isEmpty(), "should not have been empty");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -544,7 +550,9 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
||||
assertNull(airport3, "should have been removed");
|
||||
}
|
||||
}
|
||||
assertNull(airport2, "airport2 should have likely been null at least once");
|
||||
if (!config().isUsingCloud()) {
|
||||
assertNull(airport2, "airport2 should have likely been null at least once");
|
||||
}
|
||||
Airport saved = airportRepository.save(vie.clearVersion());
|
||||
couchbaseTemplate.findByQuery(Airport.class).withConsistency(REQUEST_PLUS).all();
|
||||
airport2 = airportRepository.iata(vie.getIata());
|
||||
@@ -997,8 +1005,11 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
||||
|
||||
@Override
|
||||
public void configureEnvironment(final ClusterEnvironment.Builder builder) {
|
||||
builder.ioConfig().maxHttpConnections(11).idleHttpConnectionTimeout(Duration.ofSeconds(4));
|
||||
return;
|
||||
// builder.ioConfig().maxHttpConnections(11).idleHttpConnectionTimeout(Duration.ofSeconds(4));
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Bean(name = "dateTimeProviderRef")
|
||||
@@ -1042,6 +1053,14 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Bean(name = "auditorAwareRef")
|
||||
public NaiveAuditorAware testAuditorAware() {
|
||||
return new NaiveAuditorAware();
|
||||
|
||||
@@ -47,6 +47,10 @@ import org.springframework.data.couchbase.util.ClusterType;
|
||||
import org.springframework.data.couchbase.util.IgnoreWhen;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
|
||||
/**
|
||||
* @author Michael Reiche
|
||||
*/
|
||||
@@ -139,6 +143,14 @@ public class ReactiveCouchbaseRepositoryKeyValueIntegrationTests extends Cluster
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Bean(name = "auditorAwareRef")
|
||||
public ReactiveNaiveAuditorAware testAuditorAware() {
|
||||
return new ReactiveNaiveAuditorAware();
|
||||
|
||||
@@ -22,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
@@ -42,6 +41,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.couchbase.CouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.domain.Airport;
|
||||
@@ -56,6 +56,10 @@ import org.springframework.data.couchbase.util.JavaIntegrationTests;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
|
||||
/**
|
||||
* template class for Reactive Couchbase operations
|
||||
*
|
||||
@@ -219,14 +223,17 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
Airport losAngeles = new Airport("airports::lax", "lax", "KLAX");
|
||||
|
||||
try {
|
||||
airportRepository.saveAll(asList(vienna, frankfurt, losAngeles)).as(StepVerifier::create)
|
||||
.expectNext(vienna, frankfurt, losAngeles).verifyComplete();
|
||||
// This failed once against Capella - not sure why.
|
||||
airportRepository.saveAll(asList(vienna, frankfurt, losAngeles)).blockLast();
|
||||
|
||||
airportRepository.deleteAllById(asList(vienna.getId(), losAngeles.getId())).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
|
||||
airportRepository.findAll().as(StepVerifier::create).expectNext(frankfurt).verifyComplete();
|
||||
|
||||
} finally {
|
||||
List<Airport> airports = airportRepository.findAll().collectList().block(); // .as(StepVerifier::create).expectNext(frankfurt).verifyComplete();
|
||||
System.out.println(airports);
|
||||
airportRepository.deleteAll().block();
|
||||
}
|
||||
}
|
||||
@@ -239,12 +246,12 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
Airport losAngeles = new Airport("airports::lax", "lax", "KLAX");
|
||||
|
||||
try {
|
||||
airportRepository.saveAll(asList(vienna, frankfurt, losAngeles)).as(StepVerifier::create)
|
||||
.expectNext(vienna, frankfurt, losAngeles).verifyComplete();
|
||||
airportRepository.saveAll(asList(vienna, frankfurt, losAngeles)).blockLast();
|
||||
|
||||
airportRepository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
airportRepository.findAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
} finally {
|
||||
airportRepository.deleteAll().block();
|
||||
}
|
||||
@@ -290,6 +297,13 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.springframework.data.couchbase.util.Util.comprises;
|
||||
import static org.springframework.data.couchbase.util.Util.exactly;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
@@ -57,6 +56,8 @@ import org.springframework.data.couchbase.util.JavaIntegrationTests;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
import com.querydsl.core.types.Predicate;
|
||||
@@ -579,8 +580,10 @@ public class CouchbaseRepositoryQuerydslIntegrationTests extends JavaIntegration
|
||||
|
||||
@Override
|
||||
public void configureEnvironment(final ClusterEnvironment.Builder builder) {
|
||||
builder.ioConfig().maxHttpConnections(11).idleHttpConnectionTimeout(Duration.ofSeconds(4));
|
||||
return;
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Bean(name = "dateTimeProviderRef")
|
||||
@@ -629,6 +632,14 @@ public class CouchbaseRepositoryQuerydslIntegrationTests extends JavaIntegration
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Bean(name = "auditorAwareRef")
|
||||
public NaiveAuditorAware testAuditorAware() {
|
||||
return new NaiveAuditorAware();
|
||||
|
||||
@@ -51,6 +51,10 @@ import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
|
||||
/**
|
||||
* @author Michael Nitschinger
|
||||
* @author Michael Reiche
|
||||
@@ -177,5 +181,13 @@ class StringN1qlQueryCreatorMockedTests extends ClusterAwareIntegrationTests {
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ import org.springframework.data.repository.query.QueryMethodEvaluationContextPro
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
|
||||
/**
|
||||
@@ -145,6 +148,14 @@ class StringN1qlQueryCreatorTests extends ClusterAwareIntegrationTests {
|
||||
return bucketName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
|
||||
if (config().isUsingCloud()) {
|
||||
builder.securityConfig(
|
||||
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean autoIndexCreation() {
|
||||
return true;
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -35,10 +36,13 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.couchbase.CouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.SimpleCouchbaseClientFactory;
|
||||
|
||||
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import com.couchbase.client.core.env.Authenticator;
|
||||
import com.couchbase.client.core.env.PasswordAuthenticator;
|
||||
import com.couchbase.client.core.env.SecurityConfig;
|
||||
import com.couchbase.client.core.env.SeedNode;
|
||||
import com.couchbase.client.core.error.IndexFailureException;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.manager.query.CreatePrimaryQueryIndexOptions;
|
||||
import com.couchbase.client.java.manager.query.CreateQueryIndexOptions;
|
||||
|
||||
@@ -57,14 +61,14 @@ public abstract class ClusterAwareIntegrationTests {
|
||||
static void setup(TestClusterConfig config) {
|
||||
testClusterConfig = config;
|
||||
try (CouchbaseClientFactory couchbaseClientFactory = new SimpleCouchbaseClientFactory(connectionString(),
|
||||
authenticator(), bucketName())) {
|
||||
couchbaseClientFactory.getCluster().queryIndexes().createPrimaryIndex(bucketName(),
|
||||
CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions().ignoreIfExists(true));
|
||||
authenticator(), bucketName(), null, environment().build())) {
|
||||
couchbaseClientFactory.getCluster().queryIndexes().createPrimaryIndex(bucketName(), CreatePrimaryQueryIndexOptions
|
||||
.createPrimaryQueryIndexOptions().ignoreIfExists(true).timeout(Duration.ofSeconds(300)));
|
||||
// this is for the N1qlJoin test
|
||||
List<String> fieldList = new ArrayList<>();
|
||||
fieldList.add("parentId");
|
||||
couchbaseClientFactory.getCluster().queryIndexes().createIndex(bucketName(), "parent_idx", fieldList,
|
||||
CreateQueryIndexOptions.createQueryIndexOptions().ignoreIfExists(true));
|
||||
CreateQueryIndexOptions.createQueryIndexOptions().ignoreIfExists(true).timeout(Duration.ofSeconds(300)));
|
||||
// .with("_class", "org.springframework.data.couchbase.domain.Address"));
|
||||
} catch (IndexFailureException ife) {
|
||||
LOGGER.warn("IndexFailureException occurred - ignoring: ", ife);
|
||||
@@ -102,7 +106,12 @@ public abstract class ClusterAwareIntegrationTests {
|
||||
* @return the connection string to connect.
|
||||
*/
|
||||
public static String connectionString() {
|
||||
if (config().isUsingCloud()) {
|
||||
return config().seed();
|
||||
}
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for (SeedNode s : seedNodes()) {
|
||||
if (s.kvPort().isPresent()) {
|
||||
if (sb.length() > 0)
|
||||
@@ -121,9 +130,23 @@ public abstract class ClusterAwareIntegrationTests {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the environment. When using cloud.couchbase.com, use tls.
|
||||
*
|
||||
* @return the cluster environment.
|
||||
*/
|
||||
protected static ClusterEnvironment.Builder environment() {
|
||||
return config().isUsingCloud()
|
||||
? ClusterEnvironment.builder()
|
||||
.securityConfig(SecurityConfig.trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true))
|
||||
: ClusterEnvironment.builder();
|
||||
}
|
||||
|
||||
protected static Set<SeedNode> seedNodes() {
|
||||
return config().nodes().stream().map(cfg -> SeedNode.create(cfg.hostname(),
|
||||
Optional.ofNullable(cfg.ports().get(Services.KV)), Optional.ofNullable(cfg.ports().get(Services.MANAGER))))
|
||||
Optional.ofNullable(config().isUsingCloud() ? cfg.ports().get(Services.KV_TLS) : cfg.ports().get(Services.KV)),
|
||||
Optional.ofNullable(
|
||||
config().isUsingCloud() ? cfg.ports().get(Services.MANAGER_TLS) : cfg.ports().get(Services.MANAGER))))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@@ -178,16 +201,13 @@ public abstract class ClusterAwareIntegrationTests {
|
||||
for (Method m : methods) {
|
||||
annotation = m.getAnnotation(annotationClass);
|
||||
if (annotation != null) {
|
||||
if (annotation != null) {
|
||||
m.invoke(null);
|
||||
invokedSuper = m;
|
||||
}
|
||||
m.invoke(null);
|
||||
invokedSuper = m;
|
||||
}
|
||||
}
|
||||
if (invokedSuper != null) { // called method is responsible for calling any super methods
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.couchbase.client.core.service.ServiceType;
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.ClusterOptions;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.manager.collection.CollectionManager;
|
||||
|
||||
/**
|
||||
@@ -54,11 +53,10 @@ public class CollectionAwareIntegrationTests extends JavaIntegrationTests {
|
||||
@BeforeAll
|
||||
public static void beforeAll() {
|
||||
callSuperBeforeAll(new Object() {});
|
||||
ClusterEnvironment environment = environment().build();
|
||||
Cluster cluster = Cluster.connect(seedNodes(),
|
||||
ClusterOptions.clusterOptions(authenticator()).environment(environment));
|
||||
Cluster cluster = Cluster.connect(connectionString(),
|
||||
ClusterOptions.clusterOptions(authenticator()).environment(environment().build()));
|
||||
Bucket bucket = cluster.bucket(config().bucketname());
|
||||
bucket.waitUntilReady(Duration.ofSeconds(5));
|
||||
bucket.waitUntilReady(Duration.ofSeconds(30));
|
||||
waitForService(bucket, ServiceType.QUERY);
|
||||
waitForQueryIndexerToHaveBucket(cluster, config().bucketname());
|
||||
CollectionManager collectionManager = bucket.collections();
|
||||
@@ -77,7 +75,7 @@ public class CollectionAwareIntegrationTests extends JavaIntegrationTests {
|
||||
|
||||
List<String> fieldList = new ArrayList<>();
|
||||
fieldList.add("parentId");
|
||||
cluster.query("CREATE INDEX `parent_idx` ON default:" + bucketName() + "." + scopeName + "." + collectionName2
|
||||
cluster.query("CREATE INDEX `parent_idx` ON default:`" + bucketName() + "`." + scopeName + "." + collectionName2
|
||||
+ "(parentId)");
|
||||
} catch (IndexExistsException ife) {
|
||||
LOGGER.warn("IndexFailureException occurred - ignoring: ", ife.toString());
|
||||
|
||||
@@ -49,8 +49,6 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.data.couchbase.CouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.SimpleCouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.core.ReactiveCouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.domain.Config;
|
||||
@@ -75,7 +73,6 @@ import com.couchbase.client.java.Collection;
|
||||
import com.couchbase.client.java.CommonOptions;
|
||||
import com.couchbase.client.java.Scope;
|
||||
import com.couchbase.client.java.diagnostics.PingOptions;
|
||||
import com.couchbase.client.java.env.ClusterEnvironment;
|
||||
import com.couchbase.client.java.json.JsonObject;
|
||||
import com.couchbase.client.java.manager.collection.CollectionManager;
|
||||
import com.couchbase.client.java.manager.collection.CollectionSpec;
|
||||
@@ -104,28 +101,11 @@ public class JavaIntegrationTests extends ClusterAwareIntegrationTests {
|
||||
@BeforeAll
|
||||
public static void beforeAll() {
|
||||
callSuperBeforeAll(new Object() {});
|
||||
try (CouchbaseClientFactory couchbaseClientFactory = new SimpleCouchbaseClientFactory(connectionString(),
|
||||
authenticator(), bucketName())) {
|
||||
couchbaseClientFactory.getCluster().queryIndexes().createPrimaryIndex(bucketName(),
|
||||
CreatePrimaryQueryIndexOptions.createPrimaryQueryIndexOptions().ignoreIfExists(true));
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
|
||||
couchbaseTemplate = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
|
||||
reactiveCouchbaseTemplate = (ReactiveCouchbaseTemplate) ac.getBean(REACTIVE_COUCHBASE_TEMPLATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ClusterEnvironment.Builder} which already has the seed nodes and credentials plugged and ready to
|
||||
* use depending on the environment.
|
||||
*
|
||||
* @return the builder, ready to be further modified or used directly.
|
||||
*/
|
||||
protected static ClusterEnvironment.Builder environment() {
|
||||
return ClusterEnvironment.builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pre-set cluster options with the environment and authenticator configured.
|
||||
*
|
||||
@@ -221,13 +201,14 @@ public class JavaIntegrationTests extends ClusterAwareIntegrationTests {
|
||||
private static void createAndDeleteBucket() {
|
||||
final OkHttpClient httpClient = new OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).build();
|
||||
String hostPort = connectionString().replace("11210", "8091");
|
||||
String hostPort = connectionString().replace("11210", "8091").replace("11207", "18091");
|
||||
String protocol = hostPort.equals("18091") ? "https" : "http";
|
||||
String bucketname = UUID.randomUUID().toString();
|
||||
try {
|
||||
|
||||
Response postResponse = httpClient.newCall(new Request.Builder()
|
||||
.header("Authorization", Credentials.basic(config().adminUsername(), config().adminPassword()))
|
||||
.url("http://" + hostPort + "/pools/default/buckets/")
|
||||
.url(protocol + "://" + hostPort + "/pools/default/buckets/")
|
||||
.post(new FormBody.Builder().add("name", bucketname).add("bucketType", "membase").add("ramQuotaMB", "100")
|
||||
.add("replicaNumber", Integer.toString(0)).add("flushEnabled", "1").build())
|
||||
.build()).execute();
|
||||
@@ -237,7 +218,7 @@ public class JavaIntegrationTests extends ClusterAwareIntegrationTests {
|
||||
}
|
||||
Response deleteResponse = httpClient.newCall(new Request.Builder()
|
||||
.header("Authorization", Credentials.basic(config().adminUsername(), config().adminPassword()))
|
||||
.url("http://" + hostPort + "/pools/default/buckets/" + bucketname).delete().build()).execute();
|
||||
.url(protocol + "://" + hostPort + "/pools/default/buckets/" + bucketname).delete().build()).execute();
|
||||
System.out.println("deleteResponse: " + deleteResponse);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors
|
||||
* Copyright 2012-2022 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.
|
||||
@@ -17,7 +17,16 @@
|
||||
package org.springframework.data.couchbase.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.couchbase.mock.Bucket;
|
||||
import com.couchbase.mock.BucketConfiguration;
|
||||
@@ -91,8 +100,8 @@ public class MockTestCluster extends TestCluster {
|
||||
|
||||
return new TestClusterConfig(bucketConfig.name, bucketConfig.name, bucketConfig.password, nodeConfigs,
|
||||
bucketConfig.numReplicas, Optional.empty(), // mock does not support certs
|
||||
EnumSet.of(Capabilities.VIEWS) // mock only has a limited set of capabilities we can utilize
|
||||
);
|
||||
EnumSet.of(Capabilities.VIEWS), // mock only has a limited set of capabilities we can utilize
|
||||
null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors
|
||||
* Copyright 2012-2022 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.
|
||||
@@ -35,9 +35,11 @@ public class TestClusterConfig {
|
||||
private final int numReplicas;
|
||||
private final Optional<X509Certificate> clusterCert;
|
||||
private final Set<Capabilities> capabilities;
|
||||
private final String seed;
|
||||
private final boolean usingCloud;
|
||||
|
||||
TestClusterConfig(String bucketname, String adminUsername, String adminPassword, List<TestNodeConfig> nodes,
|
||||
int numReplicas, Optional<X509Certificate> clusterCert, Set<Capabilities> capabilities) {
|
||||
int numReplicas, Optional<X509Certificate> clusterCert, Set<Capabilities> capabilities, String seed) {
|
||||
this.bucketname = bucketname;
|
||||
this.adminUsername = adminUsername;
|
||||
this.adminPassword = adminPassword;
|
||||
@@ -45,6 +47,8 @@ public class TestClusterConfig {
|
||||
this.numReplicas = numReplicas;
|
||||
this.clusterCert = clusterCert;
|
||||
this.capabilities = capabilities;
|
||||
this.seed = seed;
|
||||
this.usingCloud = seed != null && seed.contains("cloud.couchbase.com");
|
||||
}
|
||||
|
||||
public String bucketname() {
|
||||
@@ -91,6 +95,15 @@ public class TestClusterConfig {
|
||||
public String toString() {
|
||||
return "TestClusterConfig{" + "bucketname='" + bucketname + '\'' + ", adminUsername='" + adminUsername + '\''
|
||||
+ ", adminPassword='" + adminPassword + '\'' + ", nodes=" + nodes + ", numReplicas=" + numReplicas
|
||||
+ ", clusterCert=" + clusterCert + ", capabilities=" + capabilities + '}';
|
||||
+ ", clusterCert=" + clusterCert + ", capabilities=" + capabilities + ", seed=" + seed + ", usingCloud="
|
||||
+ usingCloud + '}';
|
||||
}
|
||||
|
||||
public String seed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
public boolean isUsingCloud() {
|
||||
return usingCloud;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors
|
||||
* Copyright 2012-2022 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.
|
||||
@@ -22,35 +22,65 @@ import okhttp3.FormBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.tls.HandshakeCertificates;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.couchbase.client.core.cnc.EventBus;
|
||||
import com.couchbase.client.core.cnc.SimpleEventBus;
|
||||
import com.couchbase.client.core.env.SeedNode;
|
||||
import com.couchbase.client.core.util.ConnectionStringUtil;
|
||||
|
||||
public class UnmanagedTestCluster extends TestCluster {
|
||||
|
||||
private final OkHttpClient httpClient = new OkHttpClient.Builder().build();
|
||||
private final OkHttpClient httpClient;
|
||||
private final String seedHost;
|
||||
private final int seedPort;
|
||||
private final String adminUsername;
|
||||
private final String adminPassword;
|
||||
private final int numReplicas;
|
||||
private final String protocol;
|
||||
private final String hostname;
|
||||
private volatile String bucketname;
|
||||
private long startTime = System.currentTimeMillis();
|
||||
|
||||
UnmanagedTestCluster(final Properties properties) {
|
||||
seedHost = properties.getProperty("cluster.unmanaged.seed").split(":")[0];
|
||||
seedPort = Integer.parseInt(properties.getProperty("cluster.unmanaged.seed").split(":")[1]);
|
||||
String seed = properties.getProperty("cluster.unmanaged.seed");
|
||||
if (seed.contains("cloud.couchbase.com")) {
|
||||
protocol = "https";
|
||||
seedPort = 18091;
|
||||
EventBus eventBus = new SimpleEventBus(false);
|
||||
eventBus.subscribe(event -> System.err.println("Event: " + event));
|
||||
Collection<SeedNode> seedNodes = ConnectionStringUtil.seedNodesFromConnectionString("couchbases://" + seed, true,
|
||||
true, eventBus);
|
||||
hostname = seedNodes.stream().filter((node) -> node.kvPort() != null).findFirst().get().address().toString();
|
||||
seedHost = "couchbases://" + seed;
|
||||
} else {
|
||||
protocol = "http";
|
||||
seedHost = seed.split(":")[0];
|
||||
hostname = seedHost;
|
||||
seedPort = Integer.parseInt(seed.split(":")[1]);
|
||||
}
|
||||
adminUsername = properties.getProperty("cluster.adminUsername");
|
||||
adminPassword = properties.getProperty("cluster.adminPassword");
|
||||
numReplicas = Integer.parseInt(properties.getProperty("cluster.unmanaged.numReplicas"));
|
||||
|
||||
HandshakeCertificates clientCertificates = new HandshakeCertificates.Builder().addPlatformTrustedCertificates()
|
||||
.addInsecureHost(hostname).build();
|
||||
|
||||
httpClient = new OkHttpClient.Builder()
|
||||
.sslSocketFactory(clientCertificates.sslSocketFactory(), clientCertificates.trustManager()).build();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,24 +90,28 @@ public class UnmanagedTestCluster extends TestCluster {
|
||||
|
||||
@Override
|
||||
TestClusterConfig _start() throws Exception {
|
||||
bucketname = UUID.randomUUID().toString();
|
||||
// no means to create a bucket on Capella
|
||||
// have not created config() yet.
|
||||
boolean usingCloud = seedHost.endsWith("cloud.couchbase.com");
|
||||
bucketname = usingCloud ? "my_bucket" : UUID.randomUUID().toString();
|
||||
if (!usingCloud) {
|
||||
Response postResponse = httpClient
|
||||
.newCall(new Request.Builder().header("Authorization", Credentials.basic(adminUsername, adminPassword))
|
||||
.url(protocol + "://" + hostname + ":" + seedPort + "/pools/default/buckets")
|
||||
.post(new FormBody.Builder().add("name", bucketname).add("bucketType", "membase").add("ramQuotaMB", "100")
|
||||
.add("replicaNumber", Integer.toString(numReplicas)).add("flushEnabled", "1").build())
|
||||
.build())
|
||||
.execute();
|
||||
|
||||
Response postResponse = httpClient
|
||||
.newCall(new Request.Builder().header("Authorization", Credentials.basic(adminUsername, adminPassword))
|
||||
.url("http://" + seedHost + ":" + seedPort + "/pools/default/buckets")
|
||||
.post(new FormBody.Builder().add("name", bucketname).add("bucketType", "membase").add("ramQuotaMB", "100")
|
||||
.add("replicaNumber", Integer.toString(numReplicas)).add("flushEnabled", "1").build())
|
||||
.build())
|
||||
.execute();
|
||||
|
||||
String reason = postResponse.body().string();
|
||||
if (postResponse.code() != 202 && !(reason.contains("Bucket with given name already exists"))) {
|
||||
throw new Exception("Could not create bucket: " + postResponse + ", Reason: " + reason);
|
||||
String reason = postResponse.body().string();
|
||||
if (postResponse.code() != 202 && !(reason.contains("Bucket with given name already exists"))) {
|
||||
throw new Exception("Could not create bucket: " + postResponse + ", Reason: " + reason);
|
||||
}
|
||||
}
|
||||
|
||||
Response getResponse = httpClient
|
||||
.newCall(new Request.Builder().header("Authorization", Credentials.basic(adminUsername, adminPassword))
|
||||
.url("http://" + seedHost + ":" + seedPort + "/pools/default/b/" + bucketname).build())
|
||||
.url(protocol + "://" + hostname + ":" + seedPort + "/pools/default/b/" + bucketname).build())
|
||||
.execute();
|
||||
|
||||
String raw = getResponse.body().string();
|
||||
@@ -87,14 +121,14 @@ public class UnmanagedTestCluster extends TestCluster {
|
||||
Optional<X509Certificate> cert = loadClusterCertificate();
|
||||
|
||||
return new TestClusterConfig(bucketname, adminUsername, adminPassword, nodesFromRaw(seedHost, raw),
|
||||
replicasFromRaw(raw), cert, capabilitiesFromRaw(raw));
|
||||
replicasFromRaw(raw), cert, capabilitiesFromRaw(raw), seedHost);
|
||||
}
|
||||
|
||||
private Optional<X509Certificate> loadClusterCertificate() {
|
||||
try {
|
||||
Response getResponse = httpClient
|
||||
.newCall(new Request.Builder().header("Authorization", Credentials.basic(adminUsername, adminPassword))
|
||||
.url("http://" + seedHost + ":" + seedPort + "/pools/default/certificate").build())
|
||||
.url(protocol + "://" + hostname + ":" + seedPort + "/pools/default/certificate").build())
|
||||
.execute();
|
||||
|
||||
String raw = getResponse.body().string();
|
||||
@@ -112,7 +146,7 @@ public class UnmanagedTestCluster extends TestCluster {
|
||||
while (true) {
|
||||
Response getResponse = httpClient
|
||||
.newCall(new Request.Builder().header("Authorization", Credentials.basic(adminUsername, adminPassword))
|
||||
.url("http://" + seedHost + ":" + seedPort + "/pools/default/").build())
|
||||
.url(protocol + "://" + hostname + ":" + seedPort + "/pools/default/").build())
|
||||
.execute();
|
||||
|
||||
String raw = getResponse.body().string();
|
||||
@@ -145,7 +179,8 @@ public class UnmanagedTestCluster extends TestCluster {
|
||||
if (!bucketname.equals("my_bucket")) {
|
||||
httpClient
|
||||
.newCall(new Request.Builder().header("Authorization", Credentials.basic(adminUsername, adminPassword))
|
||||
.url("http://" + seedHost + ":" + seedPort + "/pools/default/buckets/" + bucketname).delete().build())
|
||||
.url(protocol + "://" + hostname + ":" + seedPort + "/pools/default/buckets/" + bucketname).delete()
|
||||
.build())
|
||||
.execute();
|
||||
}
|
||||
System.out.println("elapsed: " + (System.currentTimeMillis() - startTime));
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
# Options: containerized, mocked, unmanaged
|
||||
cluster.type=mocked
|
||||
# Default configs for both cases
|
||||
cluster.adminUsername=Administrator
|
||||
cluster.adminPassword=password
|
||||
# Default configs for the mocked environment
|
||||
cluster.mocked.numNodes=1
|
||||
cluster.mocked.numReplicas=1
|
||||
# Entry point configuration if not managed
|
||||
# value of hostname and ns_server port
|
||||
cluster.unmanaged.seed=127.0.0.1:8091
|
||||
cluster.adminUsername=Administrator
|
||||
cluster.adminPassword=password
|
||||
#cluster.unmanaged.seed=cb.zsibzkbgllfbcj8g.cloud.couchbase.com
|
||||
#cluster.adminUsername=user
|
||||
#cluster.adminPassword=Couch0base!
|
||||
cluster.unmanaged.numReplicas=0
|
||||
|
||||
Reference in New Issue
Block a user