Skip to content

Commit

Permalink
JCBC-1594: Retry query error 4040.
Browse files Browse the repository at this point in the history
It has been discovered that this error is returned by a 6.5 or later
cluster even if the client sends the prepared statement paylods (because
it does not look at them anymore due to security reasons).

If the client receives a 4040, it is expected to clear the cache entry
for this specific prepared statement and reprepare transparently.

Change-Id: I10fe886fa43e971b444b59b5f96149fce694b85c
Reviewed-on: http://review.couchbase.org/122597
Reviewed-by: Graham Pople <grahampople@gmail.com>
Tested-by: Michael Nitschinger <michael.nitschinger@couchbase.com>
  • Loading branch information
daschl authored and Michael Nitschinger committed Feb 24, 2020
1 parent a3efbe2 commit 87ae812
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 19 deletions.
Expand Up @@ -301,7 +301,7 @@ private static boolean shouldRetry(JsonObject errorJson) {

if (code == null || msg == null) return false;

if (code == 4050 || code == 4070 ||
if (code == 4040 || code == 4050 || code == 4070 ||
(code == 5000 && msg.contains(ERROR_5000_SPECIFIC_MESSAGE))) {
return true;
}
Expand Down
Expand Up @@ -49,7 +49,6 @@
import com.couchbase.client.java.query.Select;
import com.couchbase.client.java.query.Statement;
import com.couchbase.client.java.util.LRUCache;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Test;
import org.mockito.internal.stubbing.answers.ReturnsElementsOf;
Expand All @@ -71,8 +70,8 @@ public static void tearDown() {
}

@Test
public void testPreparedStatementInCacheBypassesPreparation() throws Exception {
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
public void testPreparedStatementInCacheBypassesPreparation() {
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));

Expand Down Expand Up @@ -100,8 +99,8 @@ public void testPreparedStatementInCacheBypassesPreparation() throws Exception {
}

@Test
public void testPreparedStatementNotInCacheTriggersPreparation() throws Exception {
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
public void testPreparedStatementNotInCacheTriggersPreparation() {
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));

Expand Down Expand Up @@ -135,7 +134,7 @@ public void testPreparedStatementNotInCacheTriggersPreparation() throws Exceptio

@Test
public void testExtractionOfPayloadFromPrepareResponse() {
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
N1qlQueryExecutor executor = new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true);

Expand All @@ -155,8 +154,8 @@ public void testExtractionOfPayloadFromPrepareResponse() {
}

@Test
public void testCachedPlanExecutionErrorTriggersRetry() throws Exception {
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
public void testCachedPlanExecutionErrorTriggersRetry() {
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));

Expand Down Expand Up @@ -191,8 +190,8 @@ public void testCachedPlanExecutionErrorTriggersRetry() throws Exception {
}

@Test
public void testUncachedPlanExecutionErrorTriggersRetry() throws Exception {
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
public void testUncachedPlanExecutionErrorTriggersRetry() {
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));

Expand Down Expand Up @@ -243,8 +242,8 @@ public void testUncachedPlanExecutionErrorTriggersRetry() throws Exception {


@Test
public void testUncachedPlanExecutionDoubleErrorTriggersRetryThenFails() throws Exception {
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
public void testUncachedPlanExecutionDoubleErrorTriggersRetryThenFails() {
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));

Expand Down Expand Up @@ -299,8 +298,8 @@ public void testUncachedPlanExecutionDoubleErrorTriggersRetryThenFails() throws
assertEquals(4050, errors.get(0).getInt("code").intValue());
}

private void testRetryCondition(int code, String msg, boolean retryExpected) throws Exception {
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
private void testRetryCondition(int code, String msg, boolean retryExpected) {
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));

Expand Down Expand Up @@ -362,22 +361,27 @@ private void testRetryCondition(int code, String msg, boolean retryExpected) thr
}

@Test
public void testRetryOn4050() throws Exception {
public void testRetryOn4040() {
testRetryCondition(4040, "notRelevant", true);
}

@Test
public void testRetryOn4050() {
testRetryCondition(4050, "notRelevant", true);
}

@Test
public void testRetryOn4070() throws Exception {
public void testRetryOn4070() {
testRetryCondition(4070, "notRelevant", true);
}

@Test
public void testRetryOn5000WithSpecificMessage() throws Exception {
public void testRetryOn5000WithSpecificMessage() {
testRetryCondition(5000, "toto" + N1qlQueryExecutor.ERROR_5000_SPECIFIC_MESSAGE, true);
}

@Test
public void testNoRetryOn5000WithRandomMessage() throws Exception {
public void testNoRetryOn5000WithRandomMessage() {
testRetryCondition(5000, "notRelevant", false);
}
}

0 comments on commit 87ae812

Please sign in to comment.