Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove cartridge-java from dependencies
Browse files Browse the repository at this point in the history
- [breaking change] Remove io.tarantool.cartridge-driver dependency
- [breaking change] Update executeScript and executeCommand methods to execute code viva execInContainer
  (now it returns yaml string in Container.ExecResult not CompletableFuture)
- Add executeScriptDecoded and executeCommandDecoded methods to return parsed yaml not string.
- Add SslContext class
- Add withSslContext method to TarantoolContainer and TarantoolCartridgeContainer.
- Update org.yaml.snakeyaml to 2.0 version.

Closes #69
iDneprov committed Jun 16, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 046335e commit 7e6d389
Showing 29 changed files with 732 additions and 209 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ubuntu-master.yml
Original file line number Diff line number Diff line change
@@ -37,4 +37,5 @@ jobs:
TARANTOOL_SERVER_USER: root
TARANTOOL_SERVER_GROUP: root
DOWNLOAD_SDK_URI: ${{ secrets.DOWNLOAD_SDK_URI }}
SDK_VERSION: tarantool-enterprise-sdk-nogc64-2.10.7-0-r563.linux.x86_64
run: mvn -B test -P enterprise --file pom.xml
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -5,6 +5,13 @@
- Bump testcontainers to 1.18.0
- Move rocks building in build phase
- Use "addExposedPorts" instead of "withExposedPorts"
- **[breaking change]** Remove io.tarantool.cartridge-driver dependency
- **[breaking change]** Update executeScript and executeCommand methods to execute code via execInContainer
(now it returns **yaml** string in Container.ExecResult instead of CompletableFuture)
- Add executeScriptDecoded and executeCommandDecoded methods to return parsed yaml not string.
- Add SslContext class
- Add withSslContext method to TarantoolContainer and TarantoolCartridgeContainer.
- Update org.yaml.snakeyaml to 2.0 version.

## [0.5.4] - 2023-03-31
- Use tarantool image as base instead of centos in cartridge container
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -52,9 +52,9 @@ public class SomeTest {
@BeforeAll
public void setUp() {
// Run some setup commands
container.executeCommand("return 1, 2").get();
container.executeCommand("return 1, 2");
// Or execute a script
container.executeScript("org/testcontainers/containers/test.lua").get();
container.executeScript("org/testcontainers/containers/test.lua");
}

@Test
@@ -72,7 +72,7 @@ public class SomeTest {
...

// Execute some commands in Tarantool instance for verification
List<Object> result = container.executeCommand("return 1, 2").get();
List<Object> result = container.executeCommand("return 1, 2");
...
}
...
@@ -181,7 +181,7 @@ public class SomeOtherTest {
// Use the created container in tests
public void testFoo() {
// Execute Lua commands in the router instance
List<Object> result = container.executeCommand("return profile_get(...)", 1).get();
List<Object> result = container.executeCommand("return profile_get(1)");

// Instantiate a client connected to the router node
TarantoolCredentials credentials = new SimpleTarantoolCredentials(getRouterUsername(), getRouterPassword());
7 changes: 1 addition & 6 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -81,15 +81,10 @@
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
</dependency>
<dependency>
<groupId>io.tarantool</groupId>
<artifactId>cartridge-driver</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
30 changes: 30 additions & 0 deletions src/main/java/org/testcontainers/containers/SslContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.testcontainers.containers;

public class SslContext {
private String keyFile;
private String certFile;

private SslContext() {
}

private SslContext(String keyFile, String certFile) {
this.keyFile = keyFile;
this.certFile = certFile;
}

public static SslContext getSslContext(){
return new SslContext();
}

public static SslContext getSslContext(String keyFile, String certFile){
return new SslContext(keyFile, certFile);
}

String getKeyFile() {
return this.keyFile;
}

String getCertFile() {
return this.certFile;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.testcontainers.containers;

import com.github.dockerjava.api.command.InspectContainerResponse;
import io.tarantool.driver.exceptions.TarantoolConnectionException;

import org.testcontainers.containers.exceptions.CartridgeTopologyException;
import org.testcontainers.images.builder.ImageFromDockerfile;
@@ -13,7 +12,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
@@ -83,6 +81,9 @@
* specified in the http_port options, will be exposed.
*
* @author Alexey Kuzin
* @author Artyom Dubinin
* @author Ivan Dneprov
*
*/
public class TarantoolCartridgeContainer extends GenericContainer<TarantoolCartridgeContainer>
implements TarantoolContainerOperations<TarantoolCartridgeContainer> {
@@ -120,6 +121,7 @@ public class TarantoolCartridgeContainer extends GenericContainer<TarantoolCartr
private String directoryResourcePath = SCRIPT_RESOURCE_DIRECTORY;
private String instanceDir = INSTANCE_DIR;
private String topologyConfigurationFile;
private SslContext sslContext;

/**
* Create a container with default image and specified instances file from the classpath resources. Assumes that
@@ -344,6 +346,11 @@ public String getInstanceDir() {
return instanceDir;
}

@Override
public int getInternalPort() {
return routerPort;
}

/**
* Get Cartridge router HTTP API hostname
*
@@ -491,7 +498,7 @@ private boolean setupTopology() {
.substring(topologyConfigurationFile.lastIndexOf('/') + 1);

try {
Container.ExecResult result = execInContainer("cartridge",
ExecResult result = execInContainer("cartridge",
"replicasets",
"--run-dir=" + TARANTOOL_RUN_DIR,
"--file=" + replicasetsFileName, "setup", "--bootstrap-vshard");
@@ -505,7 +512,7 @@ private boolean setupTopology() {

} else {
try {
List<?> res = executeScript(topologyConfigurationFile).get();
List<?> res = executeScriptDecoded(topologyConfigurationFile);
if (res.size() >= 2 && res.get(1) != null && res.get(1) instanceof Map) {
HashMap<?, ?> error = ((HashMap<?, ?>) res.get(1));
// that means topology already exists
@@ -517,10 +524,6 @@ private boolean setupTopology() {
if (e.getCause() instanceof TimeoutException) {
return true;
// Do nothing, the cluster is reloading
} else if (e.getCause() instanceof TarantoolConnectionException) {
// Probably cluster is not ready
logger().error("Failed to setup topology: {}", e.getMessage());
return false;
}
} else {
throw new CartridgeTopologyException(e);
@@ -546,7 +549,7 @@ private void retryingSetupTopology() {

private void bootstrapVshard() {
try {
executeCommand(VSHARD_BOOTSTRAP_COMMAND).get();
executeCommand(VSHARD_BOOTSTRAP_COMMAND);
} catch (Exception e) {
logger().error("Failed to bootstrap vshard cluster", e);
throw new RuntimeException(e);
@@ -594,10 +597,10 @@ private void waitUntilTrue(int secondsToWait, Supplier<Boolean> waitFunc) {

private boolean routerIsUp() {
String healthyCmd = " local cartridge = package.loaded['cartridge']" +
" return assert(cartridge ~= nil)";
" return cartridge ~= nil";
try {
List<?> result = executeCommand(healthyCmd).get();
return (Boolean) result.get(0);
List<?> result = executeCommandDecoded(healthyCmd);
return result.get(0).getClass() == Boolean.class && (Boolean) result.get(0);
} catch (Exception e) {
logger().warn("Error while waiting for router instance to be up: " + e.getMessage());
return false;
@@ -606,23 +609,33 @@ private boolean routerIsUp() {

private boolean isCartridgeHealthy() {
String healthyCmd = " local cartridge = package.loaded['cartridge']" +
" return assert(cartridge) and assert(cartridge.is_healthy())";
" return cartridge ~= nil and cartridge.is_healthy()";
try {
List<?> result = executeCommand(healthyCmd).get();
return (Boolean) result.get(0);
List<?> result = executeCommandDecoded(healthyCmd);
return result.get(0).getClass() == Boolean.class && (Boolean) result.get(0);
} catch (Exception e) {
logger().warn("Error while waiting for cartridge healthy state: " + e.getMessage());
return false;
}
}

@Override
public CompletableFuture<List<?>> executeScript(String scriptResourcePath) throws Exception {
return clientHelper.executeScript(scriptResourcePath);
public ExecResult executeScript(String scriptResourcePath) throws Exception {
return clientHelper.executeScript(scriptResourcePath, this.sslContext);
}

@Override
public <T> T executeScriptDecoded(String scriptResourcePath) throws Exception {
return clientHelper.executeScriptDecoded(scriptResourcePath, this.sslContext);
}

@Override
public ExecResult executeCommand(String command) throws Exception {
return clientHelper.executeCommand(command, this.sslContext);
}

@Override
public CompletableFuture<List<?>> executeCommand(String command, Object... arguments) throws Exception {
return clientHelper.executeCommand(command, arguments);
public <T> T executeCommandDecoded(String command) throws Exception {
return clientHelper.executeCommandDecoded(command, this.sslContext);
}
}
91 changes: 37 additions & 54 deletions src/main/java/org/testcontainers/containers/TarantoolContainer.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package org.testcontainers.containers;

import com.github.dockerjava.api.command.InspectContainerResponse;
import io.tarantool.driver.api.TarantoolClientBuilder;
import org.testcontainers.containers.wait.strategy.Wait;

import java.net.URL;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

import static org.testcontainers.containers.PathUtils.normalizePath;
@@ -16,6 +13,7 @@
* Sets up a Tarantool instance and provides API for configuring it.
*
* @author Alexey Kuzin
* @author Ivan Dneprov
*/
public class TarantoolContainer extends GenericContainer<TarantoolContainer>
implements TarantoolContainerOperations<TarantoolContainer> {
@@ -45,6 +43,7 @@ public class TarantoolContainer extends GenericContainer<TarantoolContainer>
private String scriptFileName = SCRIPT_FILENAME;
private String instanceDir = INSTANCE_DIR;
private boolean useFixedPorts = false;
private SslContext sslContext;

private final TarantoolContainerClientHelper clientHelper;

@@ -55,15 +54,6 @@ public TarantoolContainer() {
this(String.format("%s:%s", TARANTOOL_IMAGE, DEFAULT_IMAGE_VERSION));
}

/**
* Constructor for {@link TarantoolContainer}
*
* @param clientBuilder client builder with custom client settings for setting up container
*/
public TarantoolContainer(TarantoolClientBuilder clientBuilder) {
this(String.format("%s:%s", TARANTOOL_IMAGE, DEFAULT_IMAGE_VERSION), clientBuilder);
}

/**
* Constructor for {@link TarantoolContainer}
*
@@ -74,18 +64,6 @@ public TarantoolContainer(String dockerImageName) {
clientHelper = new TarantoolContainerClientHelper(this);
}

/**
* Constructor for {@link TarantoolContainer}
*
* @param dockerImageName docker image name for container creating
* @param clientBuilder client builder with custom client settings for setting up container
*/
public TarantoolContainer(String dockerImageName,
TarantoolClientBuilder clientBuilder) {
super(dockerImageName);
clientHelper = new TarantoolContainerClientHelper(this, clientBuilder);
}

/**
* Constructor for {@link TarantoolContainer}
*
@@ -96,18 +74,6 @@ public TarantoolContainer(TarantoolImageParams tarantoolImageParams) {
clientHelper = new TarantoolContainerClientHelper(this);
}

/**
* Constructor for {@link TarantoolContainer}
*
* @param tarantoolImageParams params for cached image creating
* @param clientBuilder client builder with custom client settings for setting up container
*/
public TarantoolContainer(TarantoolImageParams tarantoolImageParams,
TarantoolClientBuilder clientBuilder) {
super(TarantoolContainerImageHelper.getImage(tarantoolImageParams));
clientHelper = new TarantoolContainerClientHelper(this, clientBuilder);
}

/**
* Constructor for {@link TarantoolContainer}
*
@@ -118,18 +84,6 @@ public TarantoolContainer(Future<String> image) {
clientHelper = new TarantoolContainerClientHelper(this);
}

/**
* Constructor for {@link TarantoolContainer}
*
* @param image future with image name
* @param clientBuilder client builder with custom client settings for setting up container
*/
public TarantoolContainer(Future<String> image,
TarantoolClientBuilder clientBuilder) {
super(image);
clientHelper = new TarantoolContainerClientHelper(this, clientBuilder);
}

/**
* Use fixed ports binding.
* Defaults to false.
@@ -223,6 +177,20 @@ public TarantoolContainer withPassword(String password) {
return this;
}


/**
* Specify SSL as connection transport and path to key and cert files inside your container for mTLS connection.
* Warning! SSL must be set as the default transport in your Tarantool cluster.
* Supported only in Tarantool Enterprise.
*
* @return this container instance
*/
public TarantoolContainer withSslContext(SslContext sslContext) {
checkNotRunning();
this.sslContext = sslContext;
return this;
}

/**
* Change the log_level setting on the Tarantool instance
*
@@ -233,7 +201,7 @@ public TarantoolContainer withLogLevel(TarantoolLogLevel logLevel) {
this.logLevel = logLevel;
if (isRunning()) {
try {
executeCommand(logLevel.toCommand()).get();
executeCommand(logLevel.toCommand());
} catch (Exception e) {
logger().error(String.format("Failed to set log_level to %s", logLevel.toString()), e);
throw new RuntimeException(e);
@@ -256,7 +224,7 @@ public TarantoolContainer withMemtxMemory(Integer memtxMemory) {
this.memtxMemory = memtxMemory;
if (isRunning()) {
try {
executeCommand(String.format("box.cfg{memtx_memory=%d}", memtxMemory)).get();
executeCommand(String.format("box.cfg{memtx_memory=%d}", memtxMemory));
} catch (Exception e) {
logger().error(String.format("Failed to set memtx_memory to %d", memtxMemory), e);
throw new RuntimeException(e);
@@ -300,6 +268,11 @@ public String getInstanceDir() {
return instanceDir;
}

@Override
public int getInternalPort() {
return port;
}

/**
* Specify the server init script file name
*
@@ -390,12 +363,22 @@ protected void containerIsStopping(InspectContainerResponse containerInfo) {
}

@Override
public CompletableFuture<List<?>> executeScript(String scriptResourcePath) throws Exception {
return clientHelper.executeScript(scriptResourcePath);
public Container.ExecResult executeScript(String scriptResourcePath) throws Exception {
return clientHelper.executeScript(scriptResourcePath, this.sslContext);
}

@Override
public <T> T executeScriptDecoded(String scriptResourcePath) throws Exception {
return clientHelper.executeScriptDecoded(scriptResourcePath, this.sslContext);
}

@Override
public Container.ExecResult executeCommand(String command) throws Exception {
return clientHelper.executeCommand(command, this.sslContext);
}

@Override
public CompletableFuture<List<?>> executeCommand(String command, Object... arguments) throws Exception {
return clientHelper.executeCommand(command, arguments);
public <T> T executeCommandDecoded(String command) throws Exception {
return clientHelper.executeCommandDecoded(command, this.sslContext);
}
}
Original file line number Diff line number Diff line change
@@ -1,88 +1,138 @@
package org.testcontainers.containers;

import io.tarantool.driver.api.TarantoolClient;
import io.tarantool.driver.api.TarantoolClientBuilder;
import io.tarantool.driver.api.TarantoolClientFactory;
import io.tarantool.driver.api.TarantoolResult;
import io.tarantool.driver.api.retry.TarantoolRequestRetryPolicies;
import io.tarantool.driver.api.tuple.TarantoolTuple;
import org.testcontainers.utility.MountableFile;
import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.ExecutionException;

import static org.testcontainers.containers.PathUtils.normalizePath;

/**
* Provides a wrapper around a Tarantool client with helper methods
*
* @author Alexey Kuzin
* @author Artyom Dubinin
* @author Ivan Dneprov
*/
public final class TarantoolContainerClientHelper {

private static final String TMP_DIR = "/tmp";
private static final Yaml yaml = new Yaml();

private final TarantoolContainerOperations<? extends Container<?>> container;
private final AtomicReference<TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>>> clientHolder =
new AtomicReference<>();
private final TarantoolClientBuilder clientBuilder;
private final String EXECUTE_SCRIPT_ERROR_TEMPLATE =
"Executed script %s with exit code %d, stderr: \"%s\", stdout: \"%s\"";
private static final String EXECUTE_COMMAND_ERROR_TEMPLATE =
"Executed command \"%s\" with exit code %d, stderr: \"%s\", stdout: \"%s\"";
private static final String MTLS_COMMAND_TEMPLATE =
"echo \" " +
" print(require('yaml').encode( " +
" {require('net.box').connect( " +
" { uri='%s:%d', params = { transport='ssl', ssl_key_file = '%s', ssl_cert_file = '%s' }}, " +
" { user = '%s', password = '%s' } " +
" ):eval('%s')}) " +
" ); " +
" os.exit(); " +
"\" | tarantool";
private static final String SSL_COMMAND_TEMPLATE =
"echo \" " +
" print(require('yaml').encode( " +
" {require('net.box').connect( " +
" { uri='%s:%d', params = { transport='ssl' }}, " +
" { user = '%s', password = '%s' } " +
" ):eval('%s')}) " +
" ); " +
" os.exit(); " +
"\" | tarantool";
private static final String COMMAND_TEMPLATE = "echo \" " +
" print(require('yaml').encode( " +
" {require('net.box').connect( " +
" { uri='%s:%d' }, " +
" { user = '%s', password = '%s' } " +
" ):eval('%s')}) " +
" ); " +
" os.exit(); " +
"\" | tarantool";

TarantoolContainerClientHelper(TarantoolContainerOperations<? extends Container<?>> container) {
this.container = container;
this.clientBuilder = TarantoolClientFactory.createClient()
.withRequestTimeout(5000)
.withRetryingByNumberOfAttempts(15,
TarantoolRequestRetryPolicies.retryNetworkErrors(),
b -> b.withDelay(100));
}

public Container.ExecResult executeScript(String scriptResourcePath, SslContext sslContext) throws IOException, InterruptedException {
if (!container.isRunning()) {
throw new IllegalStateException("Cannot execute scripts in stopped container");
}

TarantoolContainerClientHelper(TarantoolContainerOperations<? extends Container<?>> container,
TarantoolClientBuilder clientBuilder) {
this.container = container;
this.clientBuilder = clientBuilder;
String scriptName = Paths.get(scriptResourcePath).getFileName().toString();
String containerPath = normalizePath(Paths.get(TMP_DIR, scriptName));
container.copyFileToContainer(MountableFile.forClasspathResource(scriptResourcePath), containerPath);
return executeCommand(String.format("return dofile('%s')", containerPath), sslContext);
}

private TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>> createClient() {
return clientBuilder
.withCredentials(container.getUsername(), container.getPassword())
.withAddress(container.getHost(), container.getPort())
.build();
}
public <T> T executeScriptDecoded(String scriptResourcePath, SslContext sslContext) throws IOException, InterruptedException, ExecutionException {
Container.ExecResult result = executeScript(scriptResourcePath, sslContext);

/**
* Configure or return an already configured client connected to a Cartridge router
*
* @return a configured client
*/
public TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>> getClient() {
if (!container.isRunning()) {
throw new IllegalStateException("Cannot connect to Tarantool instance in a stopped container");
}
if (clientHolder.get() == null) {
clientHolder.compareAndSet(null, createClient());
if (result.getExitCode() != 0) {

if (result.getExitCode() == 3 || result.getExitCode() == 1) {
throw new ExecutionException(String.format(EXECUTE_SCRIPT_ERROR_TEMPLATE,
scriptResourcePath, result.getExitCode(),
result.getStderr(), result.getStdout()),
new Throwable());
}

throw new IllegalStateException(String.format(EXECUTE_SCRIPT_ERROR_TEMPLATE,
scriptResourcePath, result.getExitCode(),
result.getStderr(), result.getStdout()));
}
return clientHolder.get();

return yaml.load(result.getStdout());
}

public CompletableFuture<List<?>> executeScript(String scriptResourcePath) {
public Container.ExecResult executeCommand(String command, SslContext sslContext) throws IOException, InterruptedException {
if (!container.isRunning()) {
throw new IllegalStateException("Cannot execute scripts in stopped container");
throw new IllegalStateException("Cannot execute commands in stopped container");
}

String scriptName = Paths.get(scriptResourcePath).getFileName().toString();
String containerPath = normalizePath(Paths.get(TMP_DIR, scriptName));
container.copyFileToContainer(MountableFile.forClasspathResource(scriptResourcePath), containerPath);
return executeCommand(String.format("return dofile('%s')", containerPath));
command = command.replace("\"", "\\\"");
command = command.replace("\'", "\\\'");

String bashCommand;
if (sslContext == null) { // No SSL
bashCommand = String.format(COMMAND_TEMPLATE,
container.getHost(), container.getInternalPort(),
container.getUsername(), container.getPassword(),
command
);
} else if (sslContext.getKeyFile() != null && sslContext.getCertFile() != null) { // mTLS
bashCommand = String.format(MTLS_COMMAND_TEMPLATE,
container.getHost(), container.getInternalPort(),
sslContext.getKeyFile(), sslContext.getCertFile(),
container.getUsername(), container.getPassword(),
command
);
} else { // SSL
bashCommand = String.format(SSL_COMMAND_TEMPLATE,
container.getHost(), container.getInternalPort(),
container.getUsername(), container.getPassword(),
command
);
}

return container.execInContainer("sh", "-c", bashCommand);
}

public CompletableFuture<List<?>> executeCommand(String command, Object... arguments) {
if (!container.isRunning()) {
throw new IllegalStateException("Cannot execute commands in stopped container");
public <T> T executeCommandDecoded(String command, SslContext sslContext) throws IOException, InterruptedException {
Container.ExecResult result = executeCommand(command, sslContext);

if (result.getExitCode() != 0) {
throw new IllegalStateException(String.format(EXECUTE_COMMAND_ERROR_TEMPLATE,
command, result.getExitCode(), result.getStderr(), result.getStdout()));
}

return getClient().eval(command, Arrays.asList(arguments));
return yaml.load(result.getStdout());
}

}
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
* Represents operations available on a Tarantool Container
*
* @author Alexey Kuzin
* @author Ivan Dneprov
*/
public interface TarantoolContainerOperations<T extends Container<T>> extends Container<T> {
/**
@@ -44,6 +45,13 @@ public interface TarantoolContainerOperations<T extends Container<T>> extends Co
*/
String getInstanceDir();

/**
* Get the Tarantool server internal port for client connections
*
* @return a port
*/
int getInternalPort();

/**
* Execute a local script in the Tarantool instance. The path must be classpath-relative.
* `dofile()` function is executed internally, so possible exceptions will be caught as the client exceptions.
@@ -52,15 +60,33 @@ public interface TarantoolContainerOperations<T extends Container<T>> extends Co
* @return script execution result
* @throws Exception if failed to connect to the instance or execution fails
*/
CompletableFuture<List<?>> executeScript(String scriptResourcePath) throws Exception;
Container.ExecResult executeScript(String scriptResourcePath) throws Exception;

/**
* Execute a local script in the Tarantool instance. The path must be classpath-relative.
* `dofile()` function is executed internally, so possible exceptions will be caught as the client exceptions.
*
* @param scriptResourcePath the classpath resource path to a script
* @return script execution result in {@link Container.ExecResult}
* @throws Exception if failed to connect to the instance or execution fails
*/
<T> T executeScriptDecoded(String scriptResourcePath) throws Exception;

/**
* Execute a command in the Tarantool instance. Example of a command: `return 1 + 2, 'foo'`
*
* @param command a valid Lua command or a sequence of Lua commands
* @param arguments command arguments
* @return command execution result
* @throws Exception if failed to connect to the instance or execution fails
*/
CompletableFuture<List<?>> executeCommand(String command, Object... arguments) throws Exception;
Container.ExecResult executeCommand(String command) throws Exception;

/**
* Execute a command in the Tarantool instance. Example of a command: `return 1 + 2, 'foo'`
*
* @param command a valid Lua command or a sequence of Lua commands
* @return command execution result in {@link Container.ExecResult}
* @throws Exception if failed to connect to the instance or execution fails
*/
<T> T executeCommandDecoded(String command) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.testcontainers.containers;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertEquals;

/**
* @author Vladimir Rogach
* @author Ivan Dneprov
*/
public class CartridgeContainerTestUtils {

@@ -15,9 +15,9 @@ private CartridgeContainerTestUtils() {

static public void executeProfileReplaceSmokeTest(TarantoolCartridgeContainer container) throws Exception {
container.executeCommand(
"return profile_replace(...)", Arrays.asList(1, "Ivanov Ivan Ivanovich", 33, 100500)).get();
"return profile_replace({1, \"Ivanov Ivan Ivanovich\", 33, 100500})");

List<?> result = container.executeCommand("return profile_get(...)", 1).get();
List<?> result = container.executeCommandDecoded("return profile_get(1)");
assertEquals(1, result.size());
assertEquals(33, ((List<?>) result.get(0)).get(3));
}
Original file line number Diff line number Diff line change
@@ -5,15 +5,16 @@
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.MountableFile;
import org.testcontainers.containers.Container.ExecResult;

import java.time.Duration;
import java.util.List;

import static org.junit.Assert.assertEquals;

/**
* @author Alexey Kuzin
* @author Valdimir Rogach
* @author Ivan Dneprov
*/
@Testcontainers
public class TarantoolCartridgeBootstrapFromYamlTest {
@@ -37,7 +38,10 @@ public void test_StaticClusterContainer_StartsSuccessfully_ifFilesAreCopied() th

@Test
public void test_migrator_executesOk() throws Exception {
List<?> result = container.executeCommand("return require('migrator').up()").get();
assertEquals("001_ddl.lua", ((List<?>)result.get(0)).get(0));
ExecResult result = container.executeCommand("return require('migrator').up()");
assertEquals("---\n" +
"- ['001_ddl.lua']\n" +
"...\n" +
"\n", result.getStdout());
}
}
Original file line number Diff line number Diff line change
@@ -7,16 +7,16 @@

/**
* @author Alexey Kuzin
* @author Ivan Dneprov
*/
class TarantoolContainerTest {

@Test
public void testExecuteScript() throws Exception {
try (TarantoolContainer container = new TarantoolContainer()) {
container.start();

container.executeScript("org/testcontainers/containers/test.lua").get();
List<?> result = container.executeCommand("return user_function_no_param()").get();
container.executeScript("org/testcontainers/containers/test.lua");
List<?> result = container.executeCommandDecoded("return user_function_no_param()");
assertEquals(1, result.size());
assertEquals(5, result.get(0));
}
@@ -34,15 +34,15 @@ public void testContainerWithParameters() throws Exception {
.withLogLevel(TarantoolLogLevel.INFO)) {
container.start();

List<?> result = container.executeCommand("return box.cfg.memtx_memory").get();
List<?> result = container.executeCommandDecoded("return box.cfg.memtx_memory");
assertEquals(1, result.size());
assertEquals(memory, result.get(0));

result = container.executeCommand("return box.cfg.log_level").get();
result = container.executeCommandDecoded("return box.cfg.log_level");
assertEquals(1, result.size());
assertEquals(5, result.get(0));

result = container.executeCommand("return user_function_no_param()").get();
result = container.executeCommandDecoded("return user_function_no_param()");
assertEquals(result.size(), 1);
assertEquals(result.get(0), 5);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@

/**
* @author Alexey Kuzin
* @author Oleg Kuznetsov
* @author Ivan Dneprov
*/
@Testcontainers
public class TarantoolStaticContainerTest {
@@ -19,25 +21,23 @@ public class TarantoolStaticContainerTest {

@Test
public void testExecuteCommand() throws Exception {
List<?> result = container.executeCommand("return 1, 2").get();
List<?> result = container.executeCommandDecoded("return 1, 2");
assertEquals(2, result.size());
assertEquals(1, result.get(0));
}

@Test
public void testExecuteCommandWithArguments() throws Exception {
List<?> result = container.executeCommand(
"return require('fun').iter({...}):reduce(function(x, acc) return acc+x end, 0)",
1, 2, 3)
.get();
List<?> result = container.executeCommandDecoded(
"return require('fun').iter({1, 2, 3}):reduce(function(x, acc) return acc+x end, 0)");
assertEquals(1, result.size());
assertEquals(6, result.get(0));
}

@Test
public void testSetLogLevel() throws Exception {
container.withLogLevel(TarantoolLogLevel.INFO);
List<?> result = container.executeCommand("return box.cfg.log_level").get();
List<?> result = container.executeCommandDecoded("return box.cfg.log_level");
assertEquals(1, result.size());
assertEquals(5, result.get(0));
}
@@ -46,7 +46,7 @@ public void testSetLogLevel() throws Exception {
public void testSetMemtxMemory() throws Exception {
int memory = 256 * 1024 * 1024;
container.withMemtxMemory(memory);
List<?> result = container.executeCommand("return box.cfg.memtx_memory").get();
List<?> result = container.executeCommandDecoded("return box.cfg.memtx_memory");
assertEquals(1, result.size());
assertEquals(memory, result.get(0));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.testcontainers.containers.enterprise;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.SslContext;
import org.testcontainers.containers.TarantoolContainer;
import org.testcontainers.containers.TarantoolImageParams;
import org.testcontainers.containers.output.Slf4jLogConsumer;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
* @author Ivan Dneprov
*/
public class TarantoolMTlsContainerTestEnterprise {

private static final Logger log = LoggerFactory.getLogger(TarantoolMTlsContainerTestEnterprise.class);

private static TarantoolContainer containerWithSsl;

@BeforeAll
public static void setUp() throws Exception {
final File dockerfile = new File(
TarantoolMTlsContainerTestEnterprise.class.getClassLoader()
.getResource("enterprise/Dockerfile").toURI()
);
final Map<String, String> buildArgs = new HashMap<>();
buildArgs.put("DOWNLOAD_SDK_URI", System.getenv("DOWNLOAD_SDK_URI"));
buildArgs.put("SDK_VERSION", System.getenv("SDK_VERSION"));

containerWithSsl = new TarantoolContainer(
new TarantoolImageParams("tarantool-enterprise", dockerfile, buildArgs))
.withScriptFileName("mtls_server.lua")
.withUsername("api_user")
.withPassword("secret")
.withMemtxMemory(256 * 1024 * 1024)
.withDirectoryBinding("enterprise/ssl/mtls")
.withSslContext(SslContext.getSslContext("/app/ca.key", "/app/ca.crt"))
.withLogConsumer(new Slf4jLogConsumer(log));

if (!containerWithSsl.isRunning()) {
containerWithSsl.start();
}
}

@Test
public void test_clientWithSsl_shouldWork() throws Exception {
List<HashMap> resultList = containerWithSsl.executeCommandDecoded("return box.cfg.listen");
HashMap<String, HashMap> result = resultList.get(0);
HashMap<String, String> params = result.get("params");
assertEquals("ssl", params.get("transport"));
assertEquals("server.key", params.get("ssl_key_file"));
assertEquals("server.crt", params.get("ssl_cert_file"));
assertEquals("ca.crt", params.get("ssl_ca_file"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.testcontainers.containers.enterprise;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.TarantoolContainer;
import org.testcontainers.containers.TarantoolImageParams;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author Oleg Kuznetsov
* @author Ivan Dneprov
*/
public class TarantoolSdkContainerTestEnterprise {


@Test
void test_should_createTarantoolContainerFromSdk() throws Exception {
final File dockerfile = new File(
TarantoolSdkContainerTestEnterprise.class.getClassLoader().getResource("enterprise/Dockerfile").toURI()
);
final Map<String, String> buildArgs = new HashMap<>();
buildArgs.put("DOWNLOAD_SDK_URI", System.getenv("DOWNLOAD_SDK_URI"));
buildArgs.put("SDK_VERSION", System.getenv("SDK_VERSION"));

try (final TarantoolContainer tarantoolContainer = new TarantoolContainer(
new TarantoolImageParams("tarantool-enterprise-bundle:latest", dockerfile, buildArgs))
.withDirectoryBinding("enterprise")) {

tarantoolContainer.start();

List<String> result = tarantoolContainer.executeCommandDecoded("return 'test'");
List<String> versionAnswer = tarantoolContainer.executeCommandDecoded("return _TARANTOOL");

Assertions.assertEquals("test", result.get(0));
Assertions.assertEquals("tarantool-enterprise-sdk-nogc64-2.10.7-0-r563.linux.x86_64", versionAnswer.get(0));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.testcontainers.containers.enterprise;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.SslContext;
import org.testcontainers.containers.TarantoolContainer;
import org.testcontainers.containers.TarantoolImageParams;
import org.testcontainers.containers.output.Slf4jLogConsumer;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
* @author Ivan Dneprov
*/
public class TarantoolSslContainerTestEnterprise {

private static final Logger log = LoggerFactory.getLogger(TarantoolSslContainerTestEnterprise.class);

private static TarantoolContainer containerWithSsl;

@BeforeAll
public static void setUp() throws Exception {
final File dockerfile = new File(
TarantoolSslContainerTestEnterprise.class.getClassLoader()
.getResource("enterprise/Dockerfile").toURI()
);
final Map<String, String> buildArgs = new HashMap<>();
buildArgs.put("DOWNLOAD_SDK_URI", System.getenv("DOWNLOAD_SDK_URI"));
buildArgs.put("SDK_VERSION", System.getenv("SDK_VERSION"));

containerWithSsl = new TarantoolContainer(
new TarantoolImageParams("tarantool-enterprise", dockerfile, buildArgs))
.withScriptFileName("ssl_server.lua")
.withUsername("api_user")
.withPassword("secret")
.withMemtxMemory(256 * 1024 * 1024)
.withDirectoryBinding("enterprise/ssl")
.withSslContext(SslContext.getSslContext())
.withLogConsumer(new Slf4jLogConsumer(log));

if (!containerWithSsl.isRunning()) {
containerWithSsl.start();
}
}

@Test
public void test_clientWithSsl_shouldWork() throws Exception {
List<HashMap> resultList = containerWithSsl.executeCommandDecoded("return box.cfg.listen");
HashMap<String, HashMap> result = resultList.get(0);
HashMap<String, String> params = result.get("params");
assertEquals("ssl", params.get("transport"));
assertEquals("key.pem", params.get("ssl_key_file"));
assertEquals("certificate.crt", params.get("ssl_cert_file"));
}
}
File renamed without changes.
File renamed without changes.
21 changes: 21 additions & 0 deletions src/test/resources/enterprise/ssl/certificate.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDhDCCAmwCCQCbVZGkNwxnRzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMC
UlUxDzANBgNVBAgMBk1vc2NvdzEPMA0GA1UEBwwGTW9zY293MQswCQYDVQQKDAJW
SzESMBAGA1UECwwJVGFyYW50b29sMRIwEAYDVQQDDAlUYXJhbnRvb2wxHTAbBgkq
hkiG9w0BCQEWDnRlc3RAdGVzdC50ZXN0MB4XDTIyMDQwNzE2MDU1NFoXDTIzMDQw
NzE2MDU1NFowgYMxCzAJBgNVBAYTAlJVMQ8wDQYDVQQIDAZNb3Njb3cxDzANBgNV
BAcMBk1vc2NvdzELMAkGA1UECgwCVksxEjAQBgNVBAsMCVRhcmFudG9vbDESMBAG
A1UEAwwJVGFyYW50b29sMR0wGwYJKoZIhvcNAQkBFg50ZXN0QHRlc3QudGVzdDCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM/3KMHSybroxV5nR8tm19kg
uVlWoFzd7IXGcVbeVCdu30wBLeDQ2XvsnjYYMkHUDPWLkVosZO4de0D+vyS2CmgE
zeurAjCrUEs4Sc/Aa+CTSRuI17EkJjPpDQNSCmp3KJfPGGAypYNT7kH2Va+HvNBR
HHsSk3xuyXujX02DwsuUnf5XqYuuZ39S5jRZ3qvmQytmVXrOtSeNyhWz50XISTER
ErczPVfKOIFYEZWj+9cKaTZssYZp95MCbkagKh9ZQ6E/T3TGTMEHrqYuXQC4mHI8
PEISqnY3Vo4lpe+SBWxpJBOK5YWSTUWdPygyt71xEPkyss+C87bMsdQaY8r4TrkC
AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAj2xf7QdcSbG0nF783TGnqFK7/pBrrdDb
zlT3NReHP70FjxPIK5alMkQBM+kn/+j1RDnjJhQQa5NKadhEHqpaRd7R2Iv9a2h8
xQ78jB1GGygFnc5rGx3h5kOFSLjQlFcm9HYafTlasKYAjvhM4SiBQU/jgG2bHrIb
KrElFswBsfV2VvmvyYyhwDqrtZzKayS3BMD6fls95W+hUlMtcQXFZCVlIkJj6BVc
okM2tvkM/6ShokidAIkrq34dg4IJf3ZBXrXdiqtznMdaHAqb++Z4w3DY+hB+82qy
rUzOXligeS/xxzhiZRuIiGgMg4WbGAv7yexRgqv2wyJiGZfIfBrEdw==
-----END CERTIFICATE-----
61 changes: 61 additions & 0 deletions src/test/resources/enterprise/ssl/gen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash

HOST=tarantool.io
NEW_KEY_ARG=rsa:4096
DAYS_ARG=36500
CYPHER="PBE-SHA1-RC2-40"

gen_ca() {
local ca="${1}"
openssl req \
-new \
-nodes \
-newkey "${NEW_KEY_ARG}" \
-keyout "${ca}.key" \
-days "${DAYS_ARG}" \
-x509 \
-subj "/OU=Unknown/O=Unknown/L=Unknown/ST=unknown/C=AU" \
-out "${ca}.crt"

}

gen_cert() {
local cert="${1}"
local ca="${2}"

openssl req \
-new \
-nodes \
-newkey "${NEW_KEY_ARG}" \
-subj "/CN=${HOST}/OU=Unknown/O=Unknown/L=Unknown/ST=unknown/C=AU" \
-keyout "${cert}.key" \
-out "${cert}.csr"

openssl x509 \
-req \
-days "${DAYS_ARG}" \
-CAcreateserial \
-CA "${ca}.crt" \
-CAkey "${ca}.key" \
-in "${cert}.csr" \
-out "${cert}.crt"

rm -f "${cert}.csr"
rm -f "${ca}.srl"
}

secure_key() {
local file="${1}"
local pass="${2}"
openssl pkcs8 \
-topk8 \
-v1 ${CYPHER} \
-in ${file}.key \
-out ${file}.pkcs8.key \
-passout "pass:${pass}"
}

gen_ca ca
gen_cert server ca
gen_cert client ca
secure_key client 1q2w3e
28 changes: 28 additions & 0 deletions src/test/resources/enterprise/ssl/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDP9yjB0sm66MVe
Z0fLZtfZILlZVqBc3eyFxnFW3lQnbt9MAS3g0Nl77J42GDJB1Az1i5FaLGTuHXtA
/r8ktgpoBM3rqwIwq1BLOEnPwGvgk0kbiNexJCYz6Q0DUgpqdyiXzxhgMqWDU+5B
9lWvh7zQURx7EpN8bsl7o19Ng8LLlJ3+V6mLrmd/UuY0Wd6r5kMrZlV6zrUnjcoV
s+dFyEkxERK3Mz1XyjiBWBGVo/vXCmk2bLGGafeTAm5GoCofWUOhP090xkzBB66m
Ll0AuJhyPDxCEqp2N1aOJaXvkgVsaSQTiuWFkk1FnT8oMre9cRD5MrLPgvO2zLHU
GmPK+E65AgMBAAECggEAVpNrOT1aU+Bhggp2/ftjcnXIE6QXgHG27H4PYv2NhRkI
BqkbA1OOpqN7vcNW8MapWnNu4F5I6kQFsqoawtqx/Fm7rBd2AvLeq2HUgJN3lXdb
YQYX3RvSd5vWmgJGacoPcRt651lORBzlvDojs75LYWHS/H1gPtYUNM9vdmKa7orA
wWL1SITeR3gla0euaPItBUUNEyH4wepqG22ERqk/A7u54KRSvXp0mXRYcoDah6Y/
nmuWwWfPbqCHgopiT3IBOsqklWIkCzLNx24OhOEXXAfgH5pw85NiPP/ZJN3moNYg
2Tj3VUt9Po3TnmKX+Az8gG4tNQ9R2F4YbnKm2wxFAQKBgQD1B2guaee/wUR16foX
pgOW+9TnDwTpBwHFaymzLHG2Gs3Zb0fR5HAGfV9Oxnde8Jw4bprRa5IZYzwgKgKY
jD9Qa8u+WsYKKOObmyBPTzpJevp0cQ9pxIgR/PSj98LL5Wvitcc82fGQAbA4KK02
6VnaSfCrW2YDrl4Wk2NBFQACGQKBgQDZRuuD2Cn1dbCPuroQmYE4Pl++ke4mDl7F
xcOL7syu3uBbep/JwMB/ujruhtY9qBdKdLYjIO11xFtdQWhi7sMhhp3hlv8OGhR4
b2Po3XnNZJ16/gSu4UqgSJ8ZQA8luNNMA0jUFW8Ki15O6vhvFDS/HIcLot+l3Lna
B71+l+CFoQKBgQCCtUDOAZCuqdprTDUtCFJB6HTaDRkBdctsFI5aFgtSqVnF86bM
QJ/B1n9Q9m4XJyMut1G/BTMad+VLAx3/YlEkBVzaXnHmWYmRKF9D72+YYxHXq7gd
I8myTs3x6ejv+6Jhfbaar2g8+amXS5ua/z//QhIwVsFElW97e4Qm45ztgQKBgEBB
JeL+qSHq5QUMTnwcOUedwojD9S6R71sDahnWy/cm+Ch1cg2jEAp103m4rGDddc3S
CA8JbM/3+qDwd+NSAqjGe6g8FD9iXQ1ku6Ig5SVljODTgCULgRs3fr1j4VbherMv
AXmewRDYOFKUUFXhHtwpnpJFX2hYhynAQjzOw1ohAoGBAIGypNhAgnhc2hyeqYC9
Sg5JA06PFjuvrpymdcO3pfx9K7fHpU+wH17uYmzscMkFd5KrXVtqkziqMNV78hB4
+x5qgabXlrZj4lVaTJLB5nPWt1VBZXcAwSDw5QAVhZtiXmsqKHgvVzR4hNnOWILq
1sQlocjdaPKH0EEbP84Ae2a7
-----END PRIVATE KEY-----
32 changes: 32 additions & 0 deletions src/test/resources/enterprise/ssl/mtls/ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFjTCCA3WgAwIBAgIUD0mJoUjJsB4mrsSsBlAorJwmgcUwDQYJKoZIhvcNAQEL
BQAwVTEQMA4GA1UECwwHVW5rbm93bjEQMA4GA1UECgwHVW5rbm93bjEQMA4GA1UE
BwwHVW5rbm93bjEQMA4GA1UECAwHdW5rbm93bjELMAkGA1UEBhMCQVUwIBcNMjIw
NTMxMjEwNTA2WhgPMjEyMjA1MDcyMTA1MDZaMFUxEDAOBgNVBAsMB1Vua25vd24x
EDAOBgNVBAoMB1Vua25vd24xEDAOBgNVBAcMB1Vua25vd24xEDAOBgNVBAgMB3Vu
a25vd24xCzAJBgNVBAYTAkFVMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
AgEAtpV9sxa6KPfTP4r5IJAHML0SlIUX9rSzEwKnbsMuyEKUwmcZVQ1aUWrmTQ0J
UGboOuVMBaNqmWaeqgJBTXns60/MrKSBQmOUwm1/FIBt6KQF2WZZUM13yq+UN5i/
MHtAzHxSrecHNmzpvL9y48QJFs4ruoCzVsnLz9EmYChQCrFj1JsfLVvSpcDTFgdV
bTHJIBF9rHFKB92qMbhDJjrSmvPKNqyaLnWP0WttNIMtE5djrqwGbHolX5JrFIKr
9LDV2jJiMA7tFVl2cgg+uEcrxqOz421S9VYD0hl5hFF81rpdg/q7MEBHPYD2cCyl
92mxUYqz7r9OdK7KeMlLD/sjL34IXsT4TbcbMLYcfBdBmDRAbaAlON3spU9EPUxd
Yvhd3qKDlOP3oCXDE5MKQujz7gR3XQpX3Zdd5zxdcp/GiE9RivoKstm5/JznN+ns
BaBzw6d4gBTzIPMmiAmUTrnWD5UEhsG/kHzk+K2WXJS8/05CIZThLgILl/vfgrMX
3OBUsw1ePXj2Jmp1HLExtpX8U1NKA8UtU97QRX40eWvMuLGz7sKMS/VZiA9eNkMI
hQhkjMt0JPo9gfMggVMBOjQbLV4Ni4XZeMzurtGOmlD61s7GECySKHy5pYZtXisO
VpKABYTEyTIPPjuwN5W90h+/NI2h8xW2Z9xsE7K0flGtA1cCAwEAAaNTMFEwHQYD
VR0OBBYEFKA+WAfH0GT8G4aM4RTplY4ECcQDMB8GA1UdIwQYMBaAFKA+WAfH0GT8
G4aM4RTplY4ECcQDMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
AG++VdNo894uxESkzjVEC6hSLdcER6EbQOM34H13MzseMIjlv/4ely/Vsh79QEXA
fnAadrdVk/0r3BpBaO/iOLdMquePLBi/IYxfLaY8z2nwaocbMKUVmVjFuOgm+oXq
atyc/yzVG5yyaxoC1jHIgjn81fesI0f17opqda13u+4hXTcdAbpOY7yZY8YmP2o+
SCCfGco1BBSyKIteHLzQzpG8pZnKM0seAitZ9jD5CF9jw0tzJCWkDIhJ2dgjpigz
Go5WBxY3FMyKQPOIP5a+5AWRV+fVWENdZu9EwEWpLqc/GxQrvhbXhJ/L2ZiYRNd8
SNTBL7H0Sw65jHRWWSfz7osVntL+LYRPh30sF9LYTpUnp3gr4VTXLo6jaxwhvsIy
CacNhLpgco0sM6RLcHaSxYMUtO3EttDbkcBmIyP1KHEq1mzcVcXSetS7g9efxToh
G7NH1zVP1a8qJF5qKjXgRBASIXke9AHeAOYDI7om7qQtGuqI7nI3eg5E0qUM1gqH
kTKXJcXn/pwCkJL8TvRZWlYNJMG2YEwdA4KFgywHGn3GaM2quNqbZosMF84vlvnp
lrzJbrg2nD/wwQWdljJPVp5WReoPI9t08UqopR2P+zFcDh75X+3SXL8mMRIXMvFU
eTU7QSXhc9Q6l+skY2cRgvYl++fIooebBXpCYY9uDht9
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions src/test/resources/enterprise/ssl/mtls/ca.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
YfB9GdaUnR0F648bsknruMJrFjfZFbo=
-----END PRIVATE KEY-----
12 changes: 12 additions & 0 deletions src/test/resources/enterprise/ssl/mtls/mtls_server.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
box.cfg { listen = {
uri = 3301,
params = {
transport = 'ssl',
ssl_key_file = 'server.key',
ssl_cert_file = 'server.crt',
ssl_ca_file = 'ca.crt'
}
} }

box.schema.user.create('api_user', { password = 'secret', if_not_exists = true })
box.schema.user.grant('api_user', 'read, write, execute', 'universe', nil, { if_not_exists = true })
31 changes: 31 additions & 0 deletions src/test/resources/enterprise/ssl/mtls/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFSjCCAzICFAGDWf+4nbv3f7+QrRbP8Q3YhzOaMA0GCSqGSIb3DQEBCwUAMFUx
EDAOBgNVBAsMB1Vua25vd24xEDAOBgNVBAoMB1Vua25vd24xEDAOBgNVBAcMB1Vu
a25vd24xEDAOBgNVBAgMB3Vua25vd24xCzAJBgNVBAYTAkFVMCAXDTIyMDUzMTIx
MDUwOVoYDzIxMjIwNTA3MjEwNTA5WjBsMRUwEwYDVQQDDAx0YXJhbnRvb2wuaW8x
EDAOBgNVBAsMB1Vua25vd24xEDAOBgNVBAoMB1Vua25vd24xEDAOBgNVBAcMB1Vu
a25vd24xEDAOBgNVBAgMB3Vua25vd24xCzAJBgNVBAYTAkFVMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAy8ClyS3WZlJwycdRM1Nteke6adcgScUz0hVn
yhZJpZo4crReCTtCzOWNstlA5nnzlDT56YbnmzAwDNG6pPP00t2jVUU5wxMJSDGy
SkDk0nxq4Rd20EDV3+GIxJ+aEEPYwMcY4RcGErG+5yrSVbWniDLcvKeMjLjODzUr
vzSuBsRgtMt8Z6vQUaBxIdT3XupLFSZb4k883TkQE8wXjqbLmmOPoQAu1WZVAKEV
uvxXKonYlgC00Rl7HsaEMw8zUL7P1e+qtn6GaXkdI55Lk2y/yk0UKhBWR43mDoTx
VWyWrVnL7rFLt7Doz6F8Q5tiekjz3WpVhm2z7aGMZ/n3FE3etNVbnZg1/wqXjini
VXCgaUKryEYKR1kgPxUJB7EHjSLIGIn1Ix6toMK6ntr+WySMUfSt0A5jsQ3WM1TY
8YOdFuFbeiPpTD9Qq7hDPW1AyGOkh31eecqVwBJQlajRrkZBBZ8EacbR6aDgBfm4
n3gtoUuZZYf1aW1HzlWjaVp6M5gJCbbvuGjcfpVAbq71PTM6PYHvfe2wlbfJR02V
H7kGUUbE3A1JIGSys44FLaitY3Gy+X/Tj+bEH1uid/Q6ykcCcU/ICDoaXBQ9jbSv
56CfIjoSUY2JXpDG/Ahli/b6pwvP9CkLGTDc0VWpuG4sB3sbzjhYyijDac48/JuJ
HVk1mMcCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEARGdetChBKbDNaxGA+NHAtDGe
2lVISV21j5L1EkWQhrp39bx1YsFmvV+wibYuTDTlk/XSh+MpuRvTmc8xWXIIe30Y
PQXQPCrRd8vNjHt6i0MpW4kCe0QU/PTGOOBpD1VnJuAuebqmLuvdwCHb5uCacbVJ
Gt9voyM3yQQNZ0A3jYcm7Y6PAEL/gxq0+F30+LwvZqaAGO6hqC7WJuiyoE9No9ri
+0vZG0F0l1ZiVWaIi5m38KfYGuhd8tAEKkTUZ2cL0Td/KOavCgJ1D8s4co3wyDZG
qrIVKHYvl8G2YivQdXpMuh32QAog/34zI909pM0E2IzxRl6YBjP9UaAUW6LWWuWZ
1pso3pL/+WynAUC9gsWFcnsv3Ji4ZH24nA7BemBwo5JT/5WTtMTAA4phQDH340x4
VnHPigcvyu3eh/PDS7ZdiUSGuNcibSTrhn4bluCv5vzzmw+Atp9eccF81LxfERJY
4H94Kw70/8LBLR/7McL/aobJ5mSpAK1nnsRdr1xE46uGpkmK4pgHfD5xkcn9AFxE
vsCnwynYp4RNPfiLUHNzez0T4JWnJqPtSNtR2jTO3iVz04SUbUj/cltXOLzyPfyM
VouEL2VnAmC1WCN5KC6NnzyKVLbQ7EAi4x+61lJWWkRugxrXeaVdNbgQlA1yvAlF
cA8F69eVyPJnFsdWSq0=
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions src/test/resources/enterprise/ssl/mtls/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
jE5s8iIxjb4IkPziVOzgev4epyIs
-----END PRIVATE KEY-----
Binary file not shown.
11 changes: 11 additions & 0 deletions src/test/resources/enterprise/ssl/ssl_server.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
box.cfg { listen = {
uri = 3301,
params = {
transport = 'ssl',
ssl_key_file = 'key.pem',
ssl_cert_file = 'certificate.crt'
}
} }

box.schema.user.create('api_user', { password = 'secret', if_not_exists = true })
box.schema.user.grant('api_user', 'read, write, execute', 'universe', nil, { if_not_exists = true })

0 comments on commit 7e6d389

Please sign in to comment.