Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[couchbase] Add support for Couchbase Analytics. #4592

Merged
merged 2 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ public class CouchbaseContainer extends GenericContainer<CouchbaseContainer> {

private static final int SEARCH_SSL_PORT = 18094;

private static final int ANALYTICS_PORT = 8095;

private static final int ANALYTICS_SSL_PORT = 18095;

private static final int KV_PORT = 11210;

private static final int KV_SSL_PORT = 11207;
Expand All @@ -84,7 +88,17 @@ public class CouchbaseContainer extends GenericContainer<CouchbaseContainer> {

private String password = "password";

private Set<CouchbaseService> enabledServices = EnumSet.allOf(CouchbaseService.class);
/**
* Enabled services does not include Analytics since most users likely do not need to test
* with it and is also a little heavy on memory and runtime requirements. Also, it is only
* available with the enterprise edition (EE).
*/
private Set<CouchbaseService> enabledServices = EnumSet.of(
CouchbaseService.KV,
CouchbaseService.QUERY,
CouchbaseService.SEARCH,
CouchbaseService.INDEX
);

private final List<BucketDefinition> buckets = new ArrayList<>();

Expand Down Expand Up @@ -144,6 +158,17 @@ public CouchbaseContainer withEnabledServices(final CouchbaseService... enabled)
return this;
}

/**
* Enables the analytics service which is not enabled by default.
*
* @return this {@link CouchbaseContainer} for chaining purposes.
*/
public CouchbaseContainer withAnalyticsService() {
checkNotRunning();
this.enabledServices.add(CouchbaseService.ANALYTICS);
return this;
}

public final String getUsername() {
return username;
}
Expand Down Expand Up @@ -177,6 +202,8 @@ protected void configure() {
QUERY_SSL_PORT,
SEARCH_PORT,
SEARCH_SSL_PORT,
ANALYTICS_PORT,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering if those should be added depending on enabled services. On the other hand, there is no harm in exposing unused ports and it simplifies the code I suppose.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that’s a good idea - I‘ll do that in a follow-up PR since it’s a different optimization

ANALYTICS_SSL_PORT,
KV_PORT,
KV_SSL_PORT
);
Expand Down Expand Up @@ -214,6 +241,16 @@ protected void configure() {
);
}

if (enabledServices.contains(CouchbaseService.ANALYTICS)) {
waitStrategy = waitStrategy.withStrategy(
new HttpWaitStrategy()
.forPath("/admin/ping")
.forPort(ANALYTICS_PORT)
.withBasicCredentials(username, password)
.forStatusCode(200)
);
}

waitingFor(waitStrategy);
}

Expand Down Expand Up @@ -262,6 +299,10 @@ private void initializeIsEnterprise() {
} catch (IOException e) {
throw new IllegalStateException("Couchbase /pools did not return valid JSON");
}

if (!isEnterprise && enabledServices.contains(CouchbaseService.ANALYTICS)) {
throw new IllegalStateException("The Analytics Service is only supported with the Enterprise version");
}
}

/**
Expand Down Expand Up @@ -349,6 +390,11 @@ private void configureExternalPorts() {
builder.add("ftsSSL", Integer.toString(getMappedPort(SEARCH_SSL_PORT)));
}

if (enabledServices.contains(CouchbaseService.ANALYTICS)) {
builder.add("cbas", Integer.toString(getMappedPort(ANALYTICS_PORT)));
builder.add("cbasSSL", Integer.toString(getMappedPort(ANALYTICS_SSL_PORT)));
}

@Cleanup Response response = doHttpRequest(
MGMT_PORT,
"/node/controller/setupAlternateAddresses/external",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ public enum CouchbaseService {
/**
* Indexing service (needed if QUERY is also used!).
*/
INDEX("index");
INDEX("index"),

/**
* Analytics service.
*/
ANALYTICS("cbas");

private final String identifier;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.couchbase.client.java.Collection;
import com.couchbase.client.java.json.JsonObject;
import org.junit.Test;
import org.testcontainers.containers.ContainerLaunchException;
import org.testcontainers.utility.DockerImageName;

import java.time.Duration;
Expand All @@ -29,6 +30,7 @@
import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;

public class CouchbaseContainerTest {

Expand Down Expand Up @@ -111,6 +113,20 @@ public void testBucketIsFlushableIfEnabled() {
}
}

/**
* Make sure that the code fails fast if the Analytics service is enabled on the community
* edition which is not supported.
*/
@Test
public void testFailureIfCommunityUsedWithAnalytics() {
try (
CouchbaseContainer container = new CouchbaseContainer(COUCHBASE_IMAGE_COMMUNITY)
.withEnabledServices(CouchbaseService.KV, CouchbaseService.ANALYTICS)
) {
assertThrows(ContainerLaunchException.class, () -> setUpClient(container, cluster -> {}));
}
}

private void setUpClient(CouchbaseContainer container, Consumer<Cluster> consumer) {
container.start();

Expand Down