Skip to content

Instantly share code, notes, and snippets.

@daschl
Created April 29, 2018 07:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daschl/8a5070a039fcf0c4af9b6d18fa6ade72 to your computer and use it in GitHub Desktop.
Save daschl/8a5070a039fcf0c4af9b6d18fa6ade72 to your computer and use it in GitHub Desktop.
package com.couchbase.testcontainers;
import org.jetbrains.annotations.NotNull;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.WaitStrategy;
import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.images.builder.dockerfile.DockerfileBuilder;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
/**
* The main {@link CouchbaseContainer} implementation.
*
* @author Michael Nitschinger
* @since 1.0.0
*/
public class CouchbaseContainer extends GenericContainer<CouchbaseContainer> {
/**
* Represents the initialized container, ever incrementing.
*
* Used to properly space out the exposed ports as well.
*/
private static final AtomicInteger CONTAINER_ID = new AtomicInteger();
private final Config config;
public CouchbaseContainer() {
this(new Config(null));
}
public CouchbaseContainer(final Config config) {
super(new ImageFromDockerfile().withDockerfileFromBuilder(buildDockerFile(config)));
this.config = config;
}
private static Consumer<DockerfileBuilder> buildDockerFile(final Config config) {
return builder -> {
builder = builder.from("couchbase:" + checkVersion(config.version));
for (Map.Entry<CouchbaseService, Integer> mapping : config.portMappings().entrySet()) {
builder = builder.run("echo '{" + mapping.getKey().configFormat() + ", " + mapping.getValue() + "}.' >> /opt/couchbase/etc/couchbase/static_config");
}
//builder = builder.run("sudo /etc/init.d/couchbase-server stop");
//builder = builder.run("sudo rm /opt/couchbase/var/lib/couchbase/config/config.dat");
//builder = builder.run("sudo /etc/init.d/couchbase-server start");
builder.build();
};
}
@Override
protected void configure() {
Collection<Integer> values = config.portMappings().values();
withExposedPorts(values.toArray(new Integer[values.size()]));
for (int port : config.portMappings().values()) {
addFixedExposedPort(port, port);
}
}
@NotNull
@Override
protected Set<Integer> getLivenessCheckPorts() {
// TODO: this doesn't work because of the SSL ports I think, so
// TODO: a real check for liveness of the server needs to be in place.
return new HashSet<>(config.portMappings().values());
}
/**
* Handle the version string passed from the user.
*
* This might be extended in the future to be more intelligent about possible version
* ranges and do the proper error handling.
*
* @param version the version to be used.
* @return the converted version string, or an error.
*/
private static String checkVersion(final String version) {
return version == null || version.isEmpty() ? "latest" : version;
}
static class Config {
private final int containerId = CONTAINER_ID.incrementAndGet();
private final String version;
private final Map<CouchbaseService, Integer> mappings = new HashMap<>();
public Config(String version) {
this.version = version;
String portBase = String.format("3%02d", containerId);
mappings.put(CouchbaseService.CONFIG, Integer.parseInt(portBase + "01"));
mappings.put(CouchbaseService.VIEW, Integer.parseInt(portBase + "02"));
mappings.put(CouchbaseService.QUERY, Integer.parseInt(portBase + "03"));
mappings.put(CouchbaseService.FTS, Integer.parseInt(portBase + "04"));
mappings.put(CouchbaseService.DATA, Integer.parseInt(portBase + "06"));
mappings.put(CouchbaseService.DATA_SSL, Integer.parseInt(portBase + "07"));
mappings.put(CouchbaseService.MOXI, Integer.parseInt(portBase + "08"));
mappings.put(CouchbaseService.CONFIG_SSL, Integer.parseInt(portBase + "09"));
mappings.put(CouchbaseService.VIEW_SSL, Integer.parseInt(portBase + "10"));
mappings.put(CouchbaseService.QUERY_SSL, Integer.parseInt(portBase + "11"));
mappings.put(CouchbaseService.FTS_SSL, Integer.parseInt(portBase + "12"));
}
public Map<CouchbaseService, Integer> portMappings() {
return mappings;
}
public String version() {
return version;
}
}
enum CouchbaseService {
CONFIG("rest_port"),
CONFIG_SSL("ssl_rest_port"),
VIEW("capi_port"),
VIEW_SSL("ssl_capi_port"),
QUERY("query_port"),
QUERY_SSL("ssl_query_port"),
FTS("fts_http_port"),
FTS_SSL("fts_ssl_port"),
DATA("memcached_port"),
DATA_SSL("memcached_ssl_port"),
MOXI("moxi_port");
private final String configFormat;
CouchbaseService(String configFormat) {
this.configFormat = configFormat;
}
public String configFormat() {
return configFormat;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment