Skip to content

Commit a715548

Browse files
authored
[couchbase] Ignore transient primary index creation error. (testcontainers#4681)
This changeset makes sure that when a primary index is created, a transient error is ignored since the indexing engine will automatically retry the statement later. Transient errors can happen because we just created the bucket and the indexer might not have caught up to that bucket just yet, but it will eventually. In addition, a check has been added afterwards to make sure that the primary index is online (so, ready for the user to query) before returning to the caller, improving the overall stability of queries.
1 parent 02a8eed commit a715548

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseContainer.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,30 @@ private void createBuckets() {
473473
.add("statement", "CREATE PRIMARY INDEX on `" + bucket.getName() + "`")
474474
.build(), true);
475475

476-
checkSuccessfulResponse(queryResponse, "Could not create primary index for bucket " + bucket.getName());
476+
try {
477+
checkSuccessfulResponse(queryResponse, "Could not create primary index for bucket " + bucket.getName());
478+
} catch (IllegalStateException ex) {
479+
// potentially ignore the error, the index will be eventually built.
480+
if (!ex.getMessage().contains("Index creation will be retried in background")) {
481+
throw ex;
482+
}
483+
}
484+
485+
timePhase(
486+
"createBucket:" + bucket.getName() + ":primaryIndexOnline",
487+
() -> Unreliables.retryUntilTrue(1, TimeUnit.MINUTES, () -> {
488+
@Cleanup Response stateResponse = doHttpRequest(QUERY_PORT, "/query/service", "POST", new FormBody.Builder()
489+
.add("statement", "SELECT count(*) > 0 AS online FROM system:indexes where keyspace_id = \"" + bucket.getName() + "\" and is_primary = true and state = \"online\"")
490+
.build(), true);
491+
492+
String body = stateResponse.body() != null ? stateResponse.body().string() : null;
493+
checkSuccessfulResponse(stateResponse, "Could not poll primary index state for bucket: " + bucket.getName());
494+
495+
return Optional.of(MAPPER.readTree(body))
496+
.map(n -> n.at("/results/0/online"))
497+
.map(JsonNode::asBoolean)
498+
.orElse(false);
499+
}));
477500
} else {
478501
logger().info("Primary index creation for bucket {} ignored, since QUERY service is not present.", bucket.getName());
479502
}
@@ -508,7 +531,7 @@ private void checkSuccessfulResponse(final Response response, final String messa
508531
}
509532
}
510533

511-
throw new IllegalStateException(message + ": " + response.toString() + ", body=" + (body == null ? "<null>" : body));
534+
throw new IllegalStateException(message + ": " + response + ", body=" + (body == null ? "<null>" : body));
512535
}
513536
}
514537

0 commit comments

Comments
 (0)