diff --git a/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseContainer.java b/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseContainer.java index e43cf8f652d..d1e328d7c96 100644 --- a/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseContainer.java +++ b/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseContainer.java @@ -15,6 +15,7 @@ */ package org.testcontainers.couchbase; +import com.couchbase.client.core.service.ServiceType; import com.couchbase.client.core.utils.Base64; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.CouchbaseCluster; @@ -288,13 +289,16 @@ public void createBucket(BucketSettings bucketSetting, UserSettings userSettings } catch (Exception e) { logger().warn("Unable to insert user '" + bucketSetting.name() + "', maybe you are using older version"); } + Bucket bucket = getCouchbaseCluster().openBucket(bucketSettings.name(), bucketSettings.password()); if (index) { - Bucket bucket = getCouchbaseCluster().openBucket(bucketSettings.name(), bucketSettings.password()); new CouchbaseQueryServiceWaitStrategy(bucket).waitUntilReady(this); if (primaryIndex) { bucket.query(Index.createPrimaryIndex().on(bucketSetting.name())); } } + if (fts) { + new CouchbaseServiceWaitStrategy(bucket, ServiceType.SEARCH).waitUntilReady(this); + } } public void callCouchbaseRestAPI(String url, String payload) throws IOException { @@ -453,7 +457,8 @@ private List getDefaultAdminRoles(String bucketName) { new UserRole("query_update", bucketName), new UserRole("query_select", bucketName), new UserRole("query_insert", bucketName), - new UserRole("query_delete", bucketName) + new UserRole("query_delete", bucketName), + new UserRole("fts_admin", bucketName) ); } diff --git a/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseQueryServiceWaitStrategy.java b/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseQueryServiceWaitStrategy.java index 853dd7d8eb7..e5105b8ad38 100644 --- a/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseQueryServiceWaitStrategy.java +++ b/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseQueryServiceWaitStrategy.java @@ -1,55 +1,17 @@ package org.testcontainers.couchbase; -import com.couchbase.client.core.message.cluster.GetClusterConfigRequest; -import com.couchbase.client.core.message.cluster.GetClusterConfigResponse; import com.couchbase.client.core.service.ServiceType; import com.couchbase.client.java.Bucket; import lombok.extern.slf4j.Slf4j; -import org.rnorth.ducttape.TimeoutException; -import org.testcontainers.containers.ContainerLaunchException; -import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy; - -import java.time.Duration; -import java.util.concurrent.TimeUnit; - -import static org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess; /** * @author ctayeb * Created on 06/06/2017 */ @Slf4j -public class CouchbaseQueryServiceWaitStrategy extends AbstractWaitStrategy { - - private final Bucket bucket; +public class CouchbaseQueryServiceWaitStrategy extends CouchbaseServiceWaitStrategy { public CouchbaseQueryServiceWaitStrategy(Bucket bucket) { - this.bucket = bucket; - startupTimeout = Duration.ofSeconds(120); - } - - @Override - protected void waitUntilReady() { - log.info("Waiting for {} seconds for QUERY service", startupTimeout.getSeconds()); - - // try to connect to the URL - try { - retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> { - getRateLimiter().doWhenReady(() -> { - GetClusterConfigResponse clusterConfig = bucket.core() - .send(new GetClusterConfigRequest()) - .toBlocking().single(); - boolean queryServiceEnabled = clusterConfig.config() - .bucketConfig(bucket.name()) - .serviceEnabled(ServiceType.QUERY); - if (!queryServiceEnabled) { - throw new ContainerLaunchException("Query service not ready yet"); - } - }); - return true; - }); - } catch (TimeoutException e) { - throw new ContainerLaunchException("Timed out waiting for QUERY service"); - } + super(bucket, ServiceType.QUERY); } } diff --git a/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseServiceWaitStrategy.java b/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseServiceWaitStrategy.java new file mode 100644 index 00000000000..92546542923 --- /dev/null +++ b/modules/couchbase/src/main/java/org/testcontainers/couchbase/CouchbaseServiceWaitStrategy.java @@ -0,0 +1,54 @@ +package org.testcontainers.couchbase; + +import com.couchbase.client.core.message.cluster.GetClusterConfigRequest; +import com.couchbase.client.core.message.cluster.GetClusterConfigResponse; +import com.couchbase.client.core.service.ServiceType; +import com.couchbase.client.java.Bucket; +import lombok.extern.slf4j.Slf4j; +import org.rnorth.ducttape.TimeoutException; +import org.testcontainers.containers.ContainerLaunchException; +import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +import static org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess; + +@Slf4j +class CouchbaseServiceWaitStrategy extends AbstractWaitStrategy { + + private final Bucket bucket; + + private final ServiceType serviceType; + + public CouchbaseServiceWaitStrategy(Bucket bucket, ServiceType serviceType) { + this.bucket = bucket; + this.serviceType = serviceType; + startupTimeout = Duration.ofSeconds(120); + } + + @Override + protected void waitUntilReady() { + log.info("Waiting for {} seconds for {} service", startupTimeout.getSeconds(), serviceType); + + // try to connect to the URL + try { + retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> { + getRateLimiter().doWhenReady(() -> { + GetClusterConfigResponse clusterConfig = bucket.core() + .send(new GetClusterConfigRequest()) + .toBlocking().single(); + boolean serviceEnabled = clusterConfig.config() + .bucketConfig(bucket.name()) + .serviceEnabled(serviceType); + if (!serviceEnabled) { + throw new ContainerLaunchException(serviceType + " service not ready yet"); + } + }); + return true; + }); + } catch (TimeoutException e) { + throw new ContainerLaunchException("Timed out waiting for QUERY service"); + } + } +} diff --git a/modules/couchbase/src/test/java/org/testcontainers/couchbase/BaseCouchbaseContainerFtsTest.java b/modules/couchbase/src/test/java/org/testcontainers/couchbase/BaseCouchbaseContainerFtsTest.java new file mode 100644 index 00000000000..b33e7343103 --- /dev/null +++ b/modules/couchbase/src/test/java/org/testcontainers/couchbase/BaseCouchbaseContainerFtsTest.java @@ -0,0 +1,60 @@ +package org.testcontainers.couchbase; + +import com.couchbase.client.core.message.search.GetSearchIndexRequest; +import com.couchbase.client.core.message.search.GetSearchIndexResponse; +import com.couchbase.client.core.message.search.UpsertSearchIndexRequest; +import com.couchbase.client.core.message.search.UpsertSearchIndexResponse; +import org.junit.Assert; +import org.junit.Test; + +public abstract class BaseCouchbaseContainerFtsTest extends BaseCouchbaseContainerTest { + private static final String FTS_INDEX_NAME = "testIndex"; + private static final String FTS_INDEX = + "{\n" + + " \"name\": \"name\",\n" + + " \"type\": \"fulltext-index\",\n" + + " \"params\": {\n" + + " \"mapping\": {\n" + + " \"default_mapping\": {\n" + + " \"enabled\": true,\n" + + " \"dynamic\": true\n" + + " },\n" + + " \"default_type\": \"_default\",\n" + + " \"default_analyzer\": \"standard\",\n" + + " \"default_datetime_parser\": \"dateTimeOptional\",\n" + + " \"default_field\": \"_all\",\n" + + " \"store_dynamic\": false,\n" + + " \"index_dynamic\": true\n" + + " },\n" + + " \"store\": {\n" + + " \"indexType\": \"scorch\",\n" + + " \"kvStoreName\": \"\"\n" + + " },\n" + + " \"doc_config\": {\n" + + " \"mode\": \"type_field\",\n" + + " \"type_field\": \"type\",\n" + + " \"docid_prefix_delim\": \"\",\n" + + " \"docid_regexp\": \"\"\n" + + " }\n" + + " },\n" + + " \"sourceType\": \"couchbase\",\n" + + " \"sourceName\": \"" + TEST_BUCKET + "\"\n" + + "}"; + + @Test + public void shouldCreateFtsIndex() { + UpsertSearchIndexResponse upsertSearchIndexResponse = getBucket().core() + .send(new UpsertSearchIndexRequest(FTS_INDEX_NAME, FTS_INDEX, TEST_BUCKET, DEFAULT_PASSWORD)) + .map(UpsertSearchIndexResponse.class::cast) + .toBlocking() + .single(); + Assert.assertTrue(upsertSearchIndexResponse.status().isSuccess()); + + GetSearchIndexResponse getSearchIndexResponse = getBucket().core() + .send(new GetSearchIndexRequest(FTS_INDEX_NAME, TEST_BUCKET, DEFAULT_PASSWORD)) + .map(GetSearchIndexResponse.class::cast) + .toBlocking() + .single(); + Assert.assertTrue(getSearchIndexResponse.status().isSuccess()); + } +} diff --git a/modules/couchbase/src/test/java/org/testcontainers/couchbase/Couchbase6_5Test.java b/modules/couchbase/src/test/java/org/testcontainers/couchbase/Couchbase6_5Test.java new file mode 100644 index 00000000000..c8b504b2f7a --- /dev/null +++ b/modules/couchbase/src/test/java/org/testcontainers/couchbase/Couchbase6_5Test.java @@ -0,0 +1,14 @@ +package org.testcontainers.couchbase; + +import org.junit.Rule; + +public class Couchbase6_5Test extends BaseCouchbaseContainerFtsTest { + + @Rule + public CouchbaseContainer container = initCouchbaseContainer("couchbase:6.5.0").withFts(true); + + @Override + public CouchbaseContainer getCouchbaseContainer() { + return container; + } +}