From b1eebe540edb5753c747db0f4d90dce3d83145fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernal=20Varela=20G=C3=B3mez?= Date: Wed, 21 Dec 2016 10:38:08 +0100 Subject: [PATCH 1/5] Revision of the Exceptions constructors with no params Motivation ---------- All the java client exceptions having a a method with no parameters dont make a super call. The oracle compiler in compilation time add this call but all the exceptions have as father the CouchbaseException and his no params constructor nor have the super call. This is a problem because the stack trace is never initialized. Modifications ------------- Add super() to all the constructors. Result ------ The Exception is correctly initialized. Change-Id: I24460e247cebc8d7b4275ec55f22cc7591693485 Reviewed-on: http://review.couchbase.org/71182 Reviewed-by: Michael Nitschinger Tested-by: Michael Nitschinger Reviewed-on: http://review.couchbase.org/71966 Reviewed-by: Sergey Avseyev --- .../client/java/error/BucketAlreadyExistsException.java | 1 + .../client/java/error/BucketDoesNotExistException.java | 1 + .../com/couchbase/client/java/error/CASMismatchException.java | 1 + .../client/java/error/CouchbaseOutOfMemoryException.java | 1 + .../client/java/error/DesignDocumentAlreadyExistsException.java | 1 + .../couchbase/client/java/error/DesignDocumentException.java | 1 + .../client/java/error/DocumentAlreadyExistsException.java | 1 + .../client/java/error/DocumentDoesNotExistException.java | 1 + .../com/couchbase/client/java/error/DurabilityException.java | 1 + .../com/couchbase/client/java/error/FlushDisabledException.java | 1 + .../client/java/error/IndexAlreadyExistsException.java | 1 + .../couchbase/client/java/error/IndexDoesNotExistException.java | 1 + .../couchbase/client/java/error/IndexesNotReadyException.java | 2 ++ .../couchbase/client/java/error/InvalidPasswordException.java | 1 + .../com/couchbase/client/java/error/RequestTooBigException.java | 1 + .../couchbase/client/java/error/TemporaryFailureException.java | 1 + .../client/java/error/TemporaryLockFailureException.java | 1 + .../com/couchbase/client/java/error/TranscodingException.java | 1 + .../couchbase/client/java/error/ViewDoesNotExistException.java | 1 + .../java/repository/mapping/RepositoryMappingException.java | 1 + 20 files changed, 21 insertions(+) diff --git a/src/main/java/com/couchbase/client/java/error/BucketAlreadyExistsException.java b/src/main/java/com/couchbase/client/java/error/BucketAlreadyExistsException.java index 17786474..e3ec5af0 100644 --- a/src/main/java/com/couchbase/client/java/error/BucketAlreadyExistsException.java +++ b/src/main/java/com/couchbase/client/java/error/BucketAlreadyExistsException.java @@ -26,6 +26,7 @@ public class BucketAlreadyExistsException extends CouchbaseException { public BucketAlreadyExistsException() { + super(); } public BucketAlreadyExistsException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/BucketDoesNotExistException.java b/src/main/java/com/couchbase/client/java/error/BucketDoesNotExistException.java index b05b7020..2ea5dc7c 100644 --- a/src/main/java/com/couchbase/client/java/error/BucketDoesNotExistException.java +++ b/src/main/java/com/couchbase/client/java/error/BucketDoesNotExistException.java @@ -26,6 +26,7 @@ public class BucketDoesNotExistException extends CouchbaseException { public BucketDoesNotExistException() { + super(); } public BucketDoesNotExistException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/CASMismatchException.java b/src/main/java/com/couchbase/client/java/error/CASMismatchException.java index a11a6bd2..552b8604 100644 --- a/src/main/java/com/couchbase/client/java/error/CASMismatchException.java +++ b/src/main/java/com/couchbase/client/java/error/CASMismatchException.java @@ -26,6 +26,7 @@ public class CASMismatchException extends CouchbaseException { public CASMismatchException() { + super(); } public CASMismatchException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/CouchbaseOutOfMemoryException.java b/src/main/java/com/couchbase/client/java/error/CouchbaseOutOfMemoryException.java index 9706e060..664d0e1b 100644 --- a/src/main/java/com/couchbase/client/java/error/CouchbaseOutOfMemoryException.java +++ b/src/main/java/com/couchbase/client/java/error/CouchbaseOutOfMemoryException.java @@ -26,6 +26,7 @@ public class CouchbaseOutOfMemoryException extends CouchbaseException { public CouchbaseOutOfMemoryException() { + super(); } public CouchbaseOutOfMemoryException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/DesignDocumentAlreadyExistsException.java b/src/main/java/com/couchbase/client/java/error/DesignDocumentAlreadyExistsException.java index c936b335..b38c8068 100644 --- a/src/main/java/com/couchbase/client/java/error/DesignDocumentAlreadyExistsException.java +++ b/src/main/java/com/couchbase/client/java/error/DesignDocumentAlreadyExistsException.java @@ -22,6 +22,7 @@ public class DesignDocumentAlreadyExistsException extends DesignDocumentException { public DesignDocumentAlreadyExistsException() { + super(); } public DesignDocumentAlreadyExistsException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/DesignDocumentException.java b/src/main/java/com/couchbase/client/java/error/DesignDocumentException.java index 9cb16ac7..cd318c68 100644 --- a/src/main/java/com/couchbase/client/java/error/DesignDocumentException.java +++ b/src/main/java/com/couchbase/client/java/error/DesignDocumentException.java @@ -24,6 +24,7 @@ public class DesignDocumentException extends CouchbaseException { public DesignDocumentException() { + super(); } public DesignDocumentException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/DocumentAlreadyExistsException.java b/src/main/java/com/couchbase/client/java/error/DocumentAlreadyExistsException.java index bccd502e..7655ac3b 100644 --- a/src/main/java/com/couchbase/client/java/error/DocumentAlreadyExistsException.java +++ b/src/main/java/com/couchbase/client/java/error/DocumentAlreadyExistsException.java @@ -26,6 +26,7 @@ public class DocumentAlreadyExistsException extends CouchbaseException { public DocumentAlreadyExistsException() { + super(); } public DocumentAlreadyExistsException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/DocumentDoesNotExistException.java b/src/main/java/com/couchbase/client/java/error/DocumentDoesNotExistException.java index 4e270ff0..f73025a6 100644 --- a/src/main/java/com/couchbase/client/java/error/DocumentDoesNotExistException.java +++ b/src/main/java/com/couchbase/client/java/error/DocumentDoesNotExistException.java @@ -26,6 +26,7 @@ public class DocumentDoesNotExistException extends CouchbaseException { public DocumentDoesNotExistException() { + super(); } public DocumentDoesNotExistException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/DurabilityException.java b/src/main/java/com/couchbase/client/java/error/DurabilityException.java index f791357b..6a6ecad3 100644 --- a/src/main/java/com/couchbase/client/java/error/DurabilityException.java +++ b/src/main/java/com/couchbase/client/java/error/DurabilityException.java @@ -26,6 +26,7 @@ public class DurabilityException extends CouchbaseException { public DurabilityException() { + super(); } public DurabilityException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/FlushDisabledException.java b/src/main/java/com/couchbase/client/java/error/FlushDisabledException.java index 30f1af34..f51b4efe 100644 --- a/src/main/java/com/couchbase/client/java/error/FlushDisabledException.java +++ b/src/main/java/com/couchbase/client/java/error/FlushDisabledException.java @@ -24,6 +24,7 @@ public class FlushDisabledException extends CouchbaseException { public FlushDisabledException() { + super(); } public FlushDisabledException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/IndexAlreadyExistsException.java b/src/main/java/com/couchbase/client/java/error/IndexAlreadyExistsException.java index eed36bb4..94669a69 100644 --- a/src/main/java/com/couchbase/client/java/error/IndexAlreadyExistsException.java +++ b/src/main/java/com/couchbase/client/java/error/IndexAlreadyExistsException.java @@ -36,6 +36,7 @@ public class IndexAlreadyExistsException extends CouchbaseException { public IndexAlreadyExistsException() { + super(); } public IndexAlreadyExistsException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/IndexDoesNotExistException.java b/src/main/java/com/couchbase/client/java/error/IndexDoesNotExistException.java index 619a1d18..e4cc03c0 100644 --- a/src/main/java/com/couchbase/client/java/error/IndexDoesNotExistException.java +++ b/src/main/java/com/couchbase/client/java/error/IndexDoesNotExistException.java @@ -33,6 +33,7 @@ public class IndexDoesNotExistException extends CouchbaseException { public IndexDoesNotExistException() { + super(); } public IndexDoesNotExistException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/IndexesNotReadyException.java b/src/main/java/com/couchbase/client/java/error/IndexesNotReadyException.java index 22127ab2..27374879 100644 --- a/src/main/java/com/couchbase/client/java/error/IndexesNotReadyException.java +++ b/src/main/java/com/couchbase/client/java/error/IndexesNotReadyException.java @@ -35,7 +35,9 @@ @InterfaceStability.Experimental @InterfaceAudience.Private public class IndexesNotReadyException extends CouchbaseException { + public IndexesNotReadyException() { + super(); } public IndexesNotReadyException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/InvalidPasswordException.java b/src/main/java/com/couchbase/client/java/error/InvalidPasswordException.java index 677ef18d..ce2067bb 100644 --- a/src/main/java/com/couchbase/client/java/error/InvalidPasswordException.java +++ b/src/main/java/com/couchbase/client/java/error/InvalidPasswordException.java @@ -26,6 +26,7 @@ public class InvalidPasswordException extends CouchbaseException { public InvalidPasswordException() { + super(); } public InvalidPasswordException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/RequestTooBigException.java b/src/main/java/com/couchbase/client/java/error/RequestTooBigException.java index b16c62d8..f554ec74 100644 --- a/src/main/java/com/couchbase/client/java/error/RequestTooBigException.java +++ b/src/main/java/com/couchbase/client/java/error/RequestTooBigException.java @@ -26,6 +26,7 @@ public class RequestTooBigException extends CouchbaseException { public RequestTooBigException() { + super(); } public RequestTooBigException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/TemporaryFailureException.java b/src/main/java/com/couchbase/client/java/error/TemporaryFailureException.java index 1e4d68de..8b37a482 100644 --- a/src/main/java/com/couchbase/client/java/error/TemporaryFailureException.java +++ b/src/main/java/com/couchbase/client/java/error/TemporaryFailureException.java @@ -28,6 +28,7 @@ public class TemporaryFailureException extends CouchbaseException { public TemporaryFailureException() { + super(); } public TemporaryFailureException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/TemporaryLockFailureException.java b/src/main/java/com/couchbase/client/java/error/TemporaryLockFailureException.java index 47be91c9..c6379be6 100644 --- a/src/main/java/com/couchbase/client/java/error/TemporaryLockFailureException.java +++ b/src/main/java/com/couchbase/client/java/error/TemporaryLockFailureException.java @@ -33,6 +33,7 @@ public class TemporaryLockFailureException extends CouchbaseException { public TemporaryLockFailureException() { + super(); } public TemporaryLockFailureException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/TranscodingException.java b/src/main/java/com/couchbase/client/java/error/TranscodingException.java index 9a8827b3..e4356502 100644 --- a/src/main/java/com/couchbase/client/java/error/TranscodingException.java +++ b/src/main/java/com/couchbase/client/java/error/TranscodingException.java @@ -24,6 +24,7 @@ public class TranscodingException extends CouchbaseException { public TranscodingException() { + super(); } public TranscodingException(String message) { diff --git a/src/main/java/com/couchbase/client/java/error/ViewDoesNotExistException.java b/src/main/java/com/couchbase/client/java/error/ViewDoesNotExistException.java index 5f933c91..9516c9be 100644 --- a/src/main/java/com/couchbase/client/java/error/ViewDoesNotExistException.java +++ b/src/main/java/com/couchbase/client/java/error/ViewDoesNotExistException.java @@ -24,6 +24,7 @@ public class ViewDoesNotExistException extends CouchbaseException { public ViewDoesNotExistException() { + super(); } public ViewDoesNotExistException(String message) { diff --git a/src/main/java/com/couchbase/client/java/repository/mapping/RepositoryMappingException.java b/src/main/java/com/couchbase/client/java/repository/mapping/RepositoryMappingException.java index 9dfa4332..4751ec43 100644 --- a/src/main/java/com/couchbase/client/java/repository/mapping/RepositoryMappingException.java +++ b/src/main/java/com/couchbase/client/java/repository/mapping/RepositoryMappingException.java @@ -20,6 +20,7 @@ public class RepositoryMappingException extends CouchbaseException { public RepositoryMappingException() { + super(); } public RepositoryMappingException(String message) { From 1944cce731bbc16bb405354496e9a3719d47da7b Mon Sep 17 00:00:00 2001 From: Michael Nitschinger Date: Mon, 2 Jan 2017 19:28:40 +0100 Subject: [PATCH 2/5] Ignore Guava collection tests by default. When they are enabled by default and used with the maven command line runner it seems like the test suite never ends. We need to look into this separately but for now we can unblock the testing. Change-Id: I257e3dc6181e0e1f472f91c5b12eaff99c04a79f Reviewed-on: http://review.couchbase.org/71470 Reviewed-by: Sergey Avseyev Reviewed-by: Subhashni Balakrishnan Tested-by: Michael Nitschinger Reviewed-on: http://review.couchbase.org/71969 --- .../datastructures/collections/CouchbaseArrayListGuavaTest.java | 1 + .../datastructures/collections/CouchbaseArraySetGuavaTest.java | 1 + .../java/datastructures/collections/CouchbaseMapGuavaTest.java | 1 + 3 files changed, 3 insertions(+) diff --git a/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseArrayListGuavaTest.java b/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseArrayListGuavaTest.java index e3b10435..92e1ca4f 100644 --- a/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseArrayListGuavaTest.java +++ b/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseArrayListGuavaTest.java @@ -40,6 +40,7 @@ */ @RunWith(Suite.class) @Suite.SuiteClasses({ CouchbaseArrayListGuavaTest.GuavaTests.class }) +@Ignore public class CouchbaseArrayListGuavaTest { //the holder for the guava-generated test suite diff --git a/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseArraySetGuavaTest.java b/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseArraySetGuavaTest.java index 6861ad0a..5e340bff 100644 --- a/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseArraySetGuavaTest.java +++ b/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseArraySetGuavaTest.java @@ -42,6 +42,7 @@ */ @RunWith(Suite.class) @Suite.SuiteClasses({CouchbaseArraySetGuavaTest.GuavaTests.class}) +@Ignore public class CouchbaseArraySetGuavaTest { //the holder for the guava-generated test suite diff --git a/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseMapGuavaTest.java b/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseMapGuavaTest.java index 60c0564b..76eb8d30 100644 --- a/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseMapGuavaTest.java +++ b/src/integration/java/com/couchbase/client/java/datastructures/collections/CouchbaseMapGuavaTest.java @@ -42,6 +42,7 @@ */ @RunWith(Suite.class) @Suite.SuiteClasses({ CouchbaseMapGuavaTest.GuavaTests.class }) +@Ignore public class CouchbaseMapGuavaTest { //the holder for the guava-generated test suite From d2ddbef59fd7fb825d2f0b1829793eca654e8d01 Mon Sep 17 00:00:00 2001 From: Michael Nitschinger Date: Fri, 13 Jan 2017 06:53:26 +0100 Subject: [PATCH 3/5] Prepare 2.3.7 Release Change-Id: I8513041c6c3bf1a4570c821bfd6c822a3b02fcfa Reviewed-on: http://review.couchbase.org/71968 Tested-by: Michael Nitschinger Reviewed-by: Sergey Avseyev --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 04d1f16a..0f186006 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ com.couchbase.client java-client - 2.3.6 + 2.3.7 jar Couchbase Java SDK @@ -28,7 +28,7 @@ UTF-8 UTF-8 - 1.3.6 + 1.3.7 4.12 1.10.19 1.7.7 From 1d3c2d2faf807a27c6061b554238874ea17b40d8 Mon Sep 17 00:00:00 2001 From: Subhashni Balakrishnan Date: Wed, 4 Jan 2017 11:09:21 -0800 Subject: [PATCH 4/5] JCBC-1035 Fix flaky N1QL cluster level query integration tests Motivation ---------- N1QL cluster level query tests were quite flaky because the buckets shared the same cluster object which uses one of the open buckets in bucket cache to execute the query. As the bucket cache is a concurrent hash map, there are no order guarantees. Changes ------- Dont share cluster between the buckets. Also used request_plus scan consistency as the read pretty soon after write. Results ------- Tests consistently pass Change-Id: Iaf06b9c82dac8757fceb1575c23e84a583396206 Reviewed-on: http://review.couchbase.org/71562 Tested-by: Subhashni Balakrishnan Reviewed-by: Michael Nitschinger Reviewed-on: http://review.couchbase.org/71970 Tested-by: Michael Nitschinger Reviewed-by: Sergey Avseyev --- .../client/java/N1qlClusterLevelTest.java | 88 ++++++++++--------- .../couchbase/client/java/N1qlQueryTest.java | 2 +- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/integration/java/com/couchbase/client/java/N1qlClusterLevelTest.java b/src/integration/java/com/couchbase/client/java/N1qlClusterLevelTest.java index c468f309..b5d132b3 100644 --- a/src/integration/java/com/couchbase/client/java/N1qlClusterLevelTest.java +++ b/src/integration/java/com/couchbase/client/java/N1qlClusterLevelTest.java @@ -35,8 +35,9 @@ import com.couchbase.client.java.query.N1qlQuery; import com.couchbase.client.java.query.N1qlQueryResult; import com.couchbase.client.java.query.N1qlQueryRow; +import com.couchbase.client.java.query.N1qlParams; +import com.couchbase.client.java.query.consistency.ScanConsistency; import com.couchbase.client.java.util.CouchbaseTestContext; -import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -50,8 +51,10 @@ */ public class N1qlClusterLevelTest { - public static CouchbaseTestContext ctx; + private static CouchbaseTestContext ctx; private static CouchbaseTestContext ctx2; + private static CouchbaseTestContext ctx3; + @BeforeClass public static void init() { @@ -61,44 +64,52 @@ public static void init() { .adhoc(true) .bucketQuota(100) .build() - .ignoreIfNoN1ql() - .ensurePrimaryIndex(); + .ignoreIfNoN1ql() + .ensurePrimaryIndex(); ctx2 = CouchbaseTestContext.builder() .bucketName("N1qlCluster2") + .bucketPassword("protected") + .adhoc(true) + .bucketQuota(100) + .build() + .ignoreIfNoN1ql() + .ensurePrimaryIndex(); + + ctx3 = CouchbaseTestContext.builder() + .bucketName("N1qlCluster3") .bucketPassword("safe") .adhoc(true) .bucketQuota(100) - .buildWithCluster(ctx.cluster(), ctx.env()) - .ignoreIfNoN1ql() - .ensurePrimaryIndex(); - } + .build() + .ignoreIfNoN1ql() + .ensurePrimaryIndex(); - @After - public void resetAuthenticator() { - ctx.cluster().authenticate(new ClassicAuthenticator()); + + JsonObject content1 = JsonObject.create().put("foreignKey", "baz"); + JsonObject content2 = JsonObject.create().put("foo", "bar"); + ctx.bucket().upsert(JsonDocument.create("join", content1)); + ctx2.bucket().upsert(JsonDocument.create("baz", content2)); + ctx3.bucket().upsert(JsonDocument.create("baz", content2)); + Authenticator authenticator = new ClassicAuthenticator() + .bucket(ctx.bucketName(), "protected") + .bucket(ctx2.bucketName(), "protected"); + ctx.cluster().authenticate(authenticator); } @AfterClass public static void cleanup() { - ctx.destroyBucket(); + ctx.destroyBucketAndDisconnect(); ctx2.destroyBucketAndDisconnect(); + ctx3.destroyBucketAndDisconnect(); } @Test public void shouldJoinProtectedBuckets() { - Authenticator authenticator = new ClassicAuthenticator() - .bucket(ctx.bucketName(), "protected") - .bucket(ctx2.bucketName(), "safe"); - JsonObject content1 = JsonObject.create().put("foreignKey", "baz"); - JsonObject content2 = JsonObject.create().put("foo", "bar"); - ctx.bucket().upsert(JsonDocument.create("join", content1)); - ctx2.bucket().upsert(JsonDocument.create("baz", content2)); - ctx.cluster().authenticate(authenticator); - N1qlQuery query = N1qlQuery.simple( "SELECT A.*, B.* FROM `" + ctx.bucketName() + "` AS A" + - " JOIN `" + ctx2.bucketName() + "` as B ON KEYS A.foreignKey"); + " JOIN `" + ctx2.bucketName() + "` as B ON KEYS A.foreignKey", + N1qlParams.build().consistency(ScanConsistency.REQUEST_PLUS)); N1qlQueryResult result = ctx.cluster().query(query); @@ -118,11 +129,7 @@ public void shouldJoinProtectedBuckets() { public void shouldJoinProtectedBucketsAsynchronously() { Authenticator authenticator = new ClassicAuthenticator() .bucket(ctx.bucketName(), "protected") - .bucket(ctx2.bucketName(), "safe"); - JsonObject content1 = JsonObject.create().put("foreignKey", "baz"); - JsonObject content2 = JsonObject.create().put("foo", "bar"); - ctx.bucket().upsert(JsonDocument.create("join", content1)); - ctx2.bucket().upsert(JsonDocument.create("baz", content2)); + .bucket(ctx2.bucketName(), "protected"); AsyncCluster asyncCluster = CouchbaseAsyncCluster.create(ctx.env(), ctx.seedNode()); asyncCluster.authenticate(authenticator); @@ -132,7 +139,8 @@ public void shouldJoinProtectedBucketsAsynchronously() { N1qlQuery query = N1qlQuery.simple( "SELECT A.*, B.* FROM `" + ctx.bucketName() + "` AS A" + - " JOIN `" + ctx2.bucketName() + "` as B ON KEYS A.foreignKey"); + " JOIN `" + ctx2.bucketName() + "` as B ON KEYS A.foreignKey", + N1qlParams.build().consistency(ScanConsistency.REQUEST_PLUS)); try { AsyncN1qlQueryResult result = asyncCluster.query(query).timeout(2, TimeUnit.SECONDS).toBlocking().single(); @@ -158,17 +166,10 @@ public void shouldJoinProtectedBucketsAsynchronously() { @Test public void shouldFailJoinWithPartialCredentials() { - Authenticator authenticator = new ClassicAuthenticator() - .bucket(ctx2.bucketName(), "safe"); - JsonObject content1 = JsonObject.create().put("foreignKey", "baz"); - JsonObject content2 = JsonObject.create().put("foo", "bar"); - ctx.bucket().upsert(JsonDocument.create("join", content1)); - ctx2.bucket().upsert(JsonDocument.create("baz", content2)); - ctx.cluster().authenticate(authenticator); - N1qlQuery query = N1qlQuery.simple( "SELECT A.*, B.* FROM `" + ctx.bucketName() + "` AS A" + - " JOIN `" + ctx2.bucketName() + "` as B ON KEYS A.foreignKey"); + " JOIN `" + ctx3.bucketName() + "` as B ON KEYS A.foreignKey", + N1qlParams.build().consistency(ScanConsistency.REQUEST_PLUS)); N1qlQueryResult result = ctx.cluster().query(query); @@ -211,12 +212,13 @@ public void shouldFailOnClusterWithoutOpenBucketsAsync() { @Test public void shouldFailOnClusterWithoutCredentials() { - ctx.cluster().authenticate(new ClassicAuthenticator()); + ctx2.cluster().authenticate(new ClassicAuthenticator()); - N1qlQuery query = N1qlQuery.simple("SELECT * FROM " + ctx2.bucketName()); + N1qlQuery query = N1qlQuery.simple("SELECT * FROM " + ctx2.bucketName(), + N1qlParams.build().consistency(ScanConsistency.REQUEST_PLUS)); try { - ctx.cluster().query(query); + ctx2.cluster().query(query); fail("Expected IllegalStateException"); } catch (IllegalStateException e) { assertThat(e).hasMessage("CLUSTER_N1QL credentials are required in the Authenticator for cluster level querying"); @@ -230,11 +232,11 @@ public void shouldFailOnClusterWhenAuthenticatorDoesntSupportClusterN1QL() { when(mock.getCredentials(any(CredentialContext.class), anyString())) .thenThrow(cause); - ctx.cluster().authenticate(mock); - N1qlQuery query = N1qlQuery.simple("SELECT * FROM " + ctx2.bucketName()); + ctx3.cluster().authenticate(mock); + N1qlQuery query = N1qlQuery.simple("SELECT * FROM " + ctx3.bucketName()); try { - ctx.cluster().query(query); + ctx3.cluster().query(query); fail("Expected IllegalStateException"); } catch (IllegalStateException e) { assertThat(e) diff --git a/src/integration/java/com/couchbase/client/java/N1qlQueryTest.java b/src/integration/java/com/couchbase/client/java/N1qlQueryTest.java index c9dd6eb3..c0253042 100644 --- a/src/integration/java/com/couchbase/client/java/N1qlQueryTest.java +++ b/src/integration/java/com/couchbase/client/java/N1qlQueryTest.java @@ -329,7 +329,7 @@ public void shouldWorkWithPrettyFalse() { ctx.ignoreIfClusterUnder(Version.parseVersion("4.5.1")); N1qlQuery query = N1qlQuery.simple( select("*").fromCurrentBucket().limit(1), - N1qlParams.build().pretty(false) + N1qlParams.build().pretty(false).consistency(CONSISTENCY) ); N1qlQueryResult result = ctx.bucket().query(query); From f774df31012686aae5445851c5593216f440cc41 Mon Sep 17 00:00:00 2001 From: Michael Nitschinger Date: Thu, 12 Jan 2017 13:03:01 +0100 Subject: [PATCH 5/5] JCBC-999: Redispatch config messages if failed. Motivation ---------- If messages going down the config service in core-io, because the sockets are opened dynamically and other components depend on this fail fast mode (while not ideal), such messages need to be retried aggressively to overcome issues where a node is down for example. Modifications ------------- Simple retry logic has been added to the config service messages, retrying after 100ms and as a result providing a better experience, even if a node is down or not reachable. In the future, if needed, we can make this configurable but for now lets just stick with sane defaults. Result ------ Bucket and Cluster-level config messages have a much higher chance of succeeding, even under individual node failures. Change-Id: If27355d444fc411dd933a65e74c07816cb5dd376 Reviewed-on: http://review.couchbase.org/71897 Tested-by: Michael Nitschinger Reviewed-by: Sergey Avseyev Reviewed-by: Subhashni Balakrishnan Reviewed-on: http://review.couchbase.org/71967 --- .../client/java/bucket/BucketFlusher.java | 4 +++ .../bucket/DefaultAsyncBucketManager.java | 9 +++++-- .../cluster/DefaultAsyncClusterManager.java | 25 ++++++++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/couchbase/client/java/bucket/BucketFlusher.java b/src/main/java/com/couchbase/client/java/bucket/BucketFlusher.java index 7667a6a4..4e51e74f 100644 --- a/src/main/java/com/couchbase/client/java/bucket/BucketFlusher.java +++ b/src/main/java/com/couchbase/client/java/bucket/BucketFlusher.java @@ -26,6 +26,7 @@ import com.couchbase.client.core.message.kv.GetResponse; import com.couchbase.client.core.message.kv.UpsertRequest; import com.couchbase.client.core.message.kv.UpsertResponse; +import com.couchbase.client.core.time.Delay; import com.couchbase.client.deps.io.netty.buffer.Unpooled; import com.couchbase.client.deps.io.netty.util.CharsetUtil; import com.couchbase.client.java.error.FlushDisabledException; @@ -38,6 +39,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import static com.couchbase.client.java.util.retry.RetryBuilder.any; + /** * Helper class to flush a bucket properly and wait for it to be completed. * @@ -137,6 +140,7 @@ public List call(UpsertResponse response) { private static Observable initiateFlush(final ClusterFacade core, final String bucket, final String password) { return core .send(new FlushRequest(bucket, password)) + .retryWhen(any().delay(Delay.fixed(100, TimeUnit.MILLISECONDS)).max(Integer.MAX_VALUE).build()) .map(new Func1() { @Override public Boolean call(FlushResponse flushResponse) { diff --git a/src/main/java/com/couchbase/client/java/bucket/DefaultAsyncBucketManager.java b/src/main/java/com/couchbase/client/java/bucket/DefaultAsyncBucketManager.java index c662b636..657de8c0 100644 --- a/src/main/java/com/couchbase/client/java/bucket/DefaultAsyncBucketManager.java +++ b/src/main/java/com/couchbase/client/java/bucket/DefaultAsyncBucketManager.java @@ -20,6 +20,7 @@ import static com.couchbase.client.java.query.dsl.Expression.s; import static com.couchbase.client.java.query.dsl.Expression.x; import static com.couchbase.client.java.util.OnSubscribeDeferAndWatch.deferAndWatch; +import static com.couchbase.client.java.util.retry.RetryBuilder.any; import static com.couchbase.client.java.util.retry.RetryBuilder.anyOf; import java.util.ArrayList; @@ -116,7 +117,9 @@ public Observable info() { public Observable call() { return core.send(new BucketConfigRequest("/pools/default/buckets/", null, bucket, password)); } - }).map(new Func1() { + }) + .retryWhen(any().delay(Delay.fixed(100, TimeUnit.MILLISECONDS)).max(Integer.MAX_VALUE).build()) + .map(new Func1() { @Override public BucketInfo call(BucketConfigResponse response) { try { @@ -148,7 +151,9 @@ public Observable getDesignDocuments(final boolean development) public Observable call() { return core.send(new GetDesignDocumentsRequest(bucket, password)); } - }).flatMap(new Func1>() { + }) + .retryWhen(any().delay(Delay.fixed(100, TimeUnit.MILLISECONDS)).max(Integer.MAX_VALUE).build()) + .flatMap(new Func1>() { @Override public Observable call(GetDesignDocumentsResponse response) { JsonObject converted; diff --git a/src/main/java/com/couchbase/client/java/cluster/DefaultAsyncClusterManager.java b/src/main/java/com/couchbase/client/java/cluster/DefaultAsyncClusterManager.java index f89ed1fa..6d1e95d3 100644 --- a/src/main/java/com/couchbase/client/java/cluster/DefaultAsyncClusterManager.java +++ b/src/main/java/com/couchbase/client/java/cluster/DefaultAsyncClusterManager.java @@ -18,13 +18,23 @@ import com.couchbase.client.core.ClusterFacade; import com.couchbase.client.core.CouchbaseException; import com.couchbase.client.core.annotations.InterfaceStability; -import com.couchbase.client.core.message.config.*; +import com.couchbase.client.core.message.config.BucketsConfigRequest; +import com.couchbase.client.core.message.config.BucketsConfigResponse; +import com.couchbase.client.core.message.config.ClusterConfigRequest; +import com.couchbase.client.core.message.config.ClusterConfigResponse; +import com.couchbase.client.core.message.config.InsertBucketRequest; +import com.couchbase.client.core.message.config.InsertBucketResponse; +import com.couchbase.client.core.message.config.RemoveBucketRequest; +import com.couchbase.client.core.message.config.RemoveBucketResponse; +import com.couchbase.client.core.message.config.UpdateBucketRequest; +import com.couchbase.client.core.message.config.UpdateBucketResponse; import com.couchbase.client.core.message.internal.AddNodeRequest; import com.couchbase.client.core.message.internal.AddNodeResponse; import com.couchbase.client.core.message.internal.AddServiceRequest; import com.couchbase.client.core.message.internal.AddServiceResponse; import com.couchbase.client.core.service.ServiceType; import com.couchbase.client.java.ConnectionString; +import com.couchbase.client.core.time.Delay; import com.couchbase.client.java.CouchbaseAsyncBucket; import com.couchbase.client.java.bucket.BucketType; import com.couchbase.client.java.cluster.api.AsyncClusterApiClient; @@ -47,6 +57,8 @@ import java.util.Map; import java.util.concurrent.TimeUnit; +import static com.couchbase.client.java.util.retry.RetryBuilder.any; + public class DefaultAsyncClusterManager implements AsyncClusterManager { final ClusterFacade core; @@ -90,6 +102,7 @@ public Observable call(Boolean aBoolean) { return core.send(new ClusterConfigRequest(username, password)); } }) + .retryWhen(any().delay(Delay.fixed(100, TimeUnit.MILLISECONDS)).max(Integer.MAX_VALUE).build()) .doOnNext(new Action1() { @Override public void call(ClusterConfigResponse response) { @@ -123,6 +136,7 @@ public Observable call(Boolean aBoolean) { return core.send(new BucketsConfigRequest(username, password)); } }) + .retryWhen(any().delay(Delay.fixed(100, TimeUnit.MILLISECONDS)).max(Integer.MAX_VALUE).build()) .doOnNext(new Action1() { @Override public void call(BucketsConfigResponse response) { @@ -206,7 +220,9 @@ public Observable removeBucket(final String name) { public Observable call(Boolean aBoolean) { return core.send(new RemoveBucketRequest(name, username, password)); } - }).map(new Func1() { + }) + .retryWhen(any().delay(Delay.fixed(100, TimeUnit.MILLISECONDS)).max(Integer.MAX_VALUE).build()) + .map(new Func1() { @Override public Boolean call(RemoveBucketResponse response) { return response.status().isSuccess(); @@ -232,6 +248,7 @@ public Observable call(Boolean exists) { return core.send(new InsertBucketRequest(payload, username, password)); } }) + .retryWhen(any().delay(Delay.fixed(100, TimeUnit.MILLISECONDS)).max(Integer.MAX_VALUE).build()) .map(new Func1() { @Override public BucketSettings call(InsertBucketResponse response) { @@ -260,7 +277,9 @@ public void call(Boolean exists) { public Observable call(Boolean exists) { return core.send(new UpdateBucketRequest(settings.name(), payload, username, password)); } - }).map(new Func1() { + }) + .retryWhen(any().delay(Delay.fixed(100, TimeUnit.MILLISECONDS)).max(Integer.MAX_VALUE).build()) + .map(new Func1() { @Override public BucketSettings call(UpdateBucketResponse response) { if (!response.status().isSuccess()) {