From e3798c4c1ba25949f2dac151d12f85f0c509a03c Mon Sep 17 00:00:00 2001 From: robfrank Date: Sat, 16 Feb 2019 20:28:33 +0100 Subject: [PATCH 1/7] initial commit for OrientDB container support module --- modules/orientdb/build.gradle | 8 + .../containers/OrientDBContainer.java | 167 ++++++++++++++++++ .../containers/OrientDBContainerTest.java | 59 +++++++ .../src/test/resources/initscript.osql | 6 + 4 files changed, 240 insertions(+) create mode 100644 modules/orientdb/build.gradle create mode 100644 modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java create mode 100644 modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java create mode 100644 modules/orientdb/src/test/resources/initscript.osql diff --git a/modules/orientdb/build.gradle b/modules/orientdb/build.gradle new file mode 100644 index 00000000000..6d721d7a9ce --- /dev/null +++ b/modules/orientdb/build.gradle @@ -0,0 +1,8 @@ +description = "TestContainers :: Neo4j" + +dependencies { + compile project(":testcontainers") + + compile "com.orientechnologies:orientdb-client:3.0.15" + testCompile 'org.assertj:assertj-core:3.12.0' +} diff --git a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java new file mode 100644 index 00000000000..de72cfe41fb --- /dev/null +++ b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java @@ -0,0 +1,167 @@ +package org.testcontainers.containers; + +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.orientechnologies.orient.core.db.ODatabaseSession; +import com.orientechnologies.orient.core.db.ODatabaseType; +import com.orientechnologies.orient.core.db.OrientDB; +import com.orientechnologies.orient.core.db.OrientDBConfig; +import lombok.NonNull; +import org.apache.commons.io.IOUtils; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.containers.wait.strategy.WaitAllStrategy; +import org.testcontainers.containers.wait.strategy.WaitStrategy; + +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Optional; + +import static java.net.HttpURLConnection.HTTP_OK; + +public class OrientDBContainer> extends GenericContainer { + + public static final String DEFAULT_IMAGE_NAME = "orientdb"; + public static final String DEFAULT_TAG = "3.0.15"; + public static final String DEFAULT_USERNAME = "admin"; + public static final String DEFAULT_PASSWORD = "admin"; + public static final String DEFAULT_DATABASE_NAME = "testcontainers"; + + public static final int DEFAULT_BINARY_PORT = 2424; + public static final int DEFAULT_HTTP_PORT = 2480; + private static final Logger LOGGER = LoggerFactory.getLogger(OrientDBContainer.class); + private static final String DOCKER_IMAGE_NAME = DEFAULT_IMAGE_NAME + ":" + DEFAULT_TAG; + private String databaseName; + private String username; + private String password; + + private ODatabaseSession session; + private OrientDB orientDB; + private Optional scriptPath = Optional.empty(); + + + public OrientDBContainer() { + this(DOCKER_IMAGE_NAME); + } + + public OrientDBContainer(@NonNull String dockerImageName) { + super(dockerImageName); + + username = DEFAULT_USERNAME; + password = DEFAULT_PASSWORD; + databaseName = DEFAULT_DATABASE_NAME; + + WaitStrategy waitForHttp = new HttpWaitStrategy() + .forPort(DEFAULT_HTTP_PORT) + .forStatusCodeMatching(response -> response == HTTP_OK); + + waitStrategy = new WaitAllStrategy() + .withStrategy(Wait.forListeningPort()) + .withStrategy(waitForHttp) + .withStartupTimeout(Duration.ofMinutes(2)); + } + + @Override + protected void configure() { + + addExposedPorts(DEFAULT_BINARY_PORT, DEFAULT_HTTP_PORT); + addEnv("ORIENTDB_ROOT_PASSWORD", "root"); + } + + + public String getDatabaseName() { + return databaseName; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getTestQueryString() { + return "SELECT FROM V"; + } + + public SELF withDatabaseName(final String databaseName) { + this.databaseName = databaseName; + return self(); + } + + public SELF withUsername(final String username) { + this.username = username; + return self(); + } + + public SELF withPassword(final String password) { + this.password = password; + return self(); + } + + @Override + protected void containerIsStarted(InspectContainerResponse containerInfo) { + + orientDB = new OrientDB(getServerUrl(), "root", "root", OrientDBConfig.defaultConfig()); + + } + + @NotNull + public String getServerUrl() { + return "remote:" + getContainerIpAddress() + ":" + getMappedPort(2424); + } + + public String getDbUrl() { + return getServerUrl() + "/" + databaseName; + } + + public ODatabaseSession getSession() { + + orientDB.createIfNotExists(databaseName, ODatabaseType.PLOCAL); + + if (session == null) + session = orientDB.open(databaseName, username, password); + + scriptPath.ifPresent(path -> loadScript(path, session)); + + return session; + } + + + private void loadScript(String path, ODatabaseSession session) { + try { + URL resource = getClass().getClassLoader().getResource(path); + + if (resource == null) { + LOGGER.warn("Could not load classpath init script: {}", scriptPath); + throw new RuntimeException("Could not load classpath init script: " + scriptPath + ". Resource not found."); + } + + String script = IOUtils.toString(resource, StandardCharsets.UTF_8); + + session.execute("sql", script); + } catch (IOException e) { + LOGGER.warn("Could not load classpath init script: {}", scriptPath); + throw new RuntimeException("Could not load classpath init script: " + scriptPath, e); + } catch (UnsupportedOperationException e) { + LOGGER.error("Error while executing init script: {}", scriptPath, e); + throw new RuntimeException("Error while executing init script: " + scriptPath, e); + } + + } + + public OrientDB getOrientDB() { + return orientDB; + } + + public SELF withScriptPath(String scriptPath) { + + this.scriptPath = Optional.of(scriptPath); + return self(); + } +} diff --git a/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java b/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java new file mode 100644 index 00000000000..1b2c1bccfab --- /dev/null +++ b/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java @@ -0,0 +1,59 @@ +package org.testcontainers.containers; + +import com.orientechnologies.orient.core.db.ODatabaseSession; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class OrientDBContainerTest { + + + @Test + public void shouldReturnTheSameSession() { + OrientDBContainer container = new OrientDBContainer(); + container.start(); + + final ODatabaseSession session = container.getSession(); + final ODatabaseSession session2 = container.getSession(); + + assertThat(session).isSameAs(session2); + } + + @Test + public void shouldInitializeWithCommands() { + + OrientDBContainer container = new OrientDBContainer(); + container.start(); + + final ODatabaseSession session = container.getSession(); + + session.command("CREATE CLASS Person EXTENDS V"); + session.command("INSERT INTO Person set name='john'"); + session.command("INSERT INTO Person set name='jane'"); + + assertThat(session.query("SELECT FROM Person").stream()).hasSize(2); + + container.stop(); + + } + + @Test + public void shouldInitializeDatabaseFromScript() { + + OrientDBContainer container = new OrientDBContainer() + .withScriptPath("initscript.osql") + .withDatabaseName("persons"); + + container.start(); + + assertThat(container.getDbUrl()) + .isEqualTo("remote:" + container.getContainerIpAddress() + ":" + container.getMappedPort(2424) + "/persons"); + + final ODatabaseSession session = container.getSession(); + + assertThat(session.query("SELECT FROM Person").stream()).hasSize(4); + + container.stop(); + + } +} diff --git a/modules/orientdb/src/test/resources/initscript.osql b/modules/orientdb/src/test/resources/initscript.osql new file mode 100644 index 00000000000..e1ba22bbb3e --- /dev/null +++ b/modules/orientdb/src/test/resources/initscript.osql @@ -0,0 +1,6 @@ +CREATE CLASS Person EXTENDS V; + +INSERT INTO Person set name="john"; +INSERT INTO Person set name="paul"; +INSERT INTO Person set name="luke"; +INSERT INTO Person set name="albert"; From 1aa36064f934db40d3d5d9262aa8d19f595e71c3 Mon Sep 17 00:00:00 2001 From: robfrank Date: Sun, 17 Feb 2019 09:18:20 +0100 Subject: [PATCH 2/7] log configuration for test added --- .../src/test/resources/logback-test.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 modules/orientdb/src/test/resources/logback-test.xml diff --git a/modules/orientdb/src/test/resources/logback-test.xml b/modules/orientdb/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..7bd6a94d827 --- /dev/null +++ b/modules/orientdb/src/test/resources/logback-test.xml @@ -0,0 +1,18 @@ + + + + + + %d{HH:mm:ss.SSS} %-5level %logger - %msg%n + + + + + + + + + + + \ No newline at end of file From 806de50e02225af01f942f3137f5d3ce7c1d73b2 Mon Sep 17 00:00:00 2001 From: robfrank Date: Sun, 17 Feb 2019 09:21:08 +0100 Subject: [PATCH 3/7] code cleanup --- .../containers/OrientDBContainer.java | 58 ++++++++++++------- .../containers/OrientDBContainerTest.java | 4 ++ 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java index de72cfe41fb..5624cc55e7b 100644 --- a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java +++ b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java @@ -7,7 +7,6 @@ import com.orientechnologies.orient.core.db.OrientDBConfig; import lombok.NonNull; import org.apache.commons.io.IOUtils; -import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; @@ -23,24 +22,39 @@ import static java.net.HttpURLConnection.HTTP_OK; +/** + * @author robfrank + */ public class OrientDBContainer> extends GenericContainer { - public static final String DEFAULT_IMAGE_NAME = "orientdb"; - public static final String DEFAULT_TAG = "3.0.15"; - public static final String DEFAULT_USERNAME = "admin"; - public static final String DEFAULT_PASSWORD = "admin"; - public static final String DEFAULT_DATABASE_NAME = "testcontainers"; + private static final String DEFAULT_IMAGE_NAME = "orientdb"; + + private static final String DEFAULT_TAG = "3.0.15"; + + private static final String DEFAULT_USERNAME = "admin"; + + private static final String DEFAULT_PASSWORD = "admin"; + + private static final String DEFAULT_DATABASE_NAME = "testcontainers"; + + private static final int DEFAULT_BINARY_PORT = 2424; + + private static final int DEFAULT_HTTP_PORT = 2480; - public static final int DEFAULT_BINARY_PORT = 2424; - public static final int DEFAULT_HTTP_PORT = 2480; private static final Logger LOGGER = LoggerFactory.getLogger(OrientDBContainer.class); + private static final String DOCKER_IMAGE_NAME = DEFAULT_IMAGE_NAME + ":" + DEFAULT_TAG; + private String databaseName; + private String username; + private String password; - private ODatabaseSession session; private OrientDB orientDB; + + private ODatabaseSession session; + private Optional scriptPath = Optional.empty(); @@ -104,14 +118,22 @@ public SELF withPassword(final String password) { return self(); } + public SELF withScriptPath(String scriptPath) { + + this.scriptPath = Optional.of(scriptPath); + return self(); + } + + @Override protected void containerIsStarted(InspectContainerResponse containerInfo) { - orientDB = new OrientDB(getServerUrl(), "root", "root", OrientDBConfig.defaultConfig()); + } + public OrientDB getOrientDB() { + return orientDB; } - @NotNull public String getServerUrl() { return "remote:" + getContainerIpAddress() + ":" + getMappedPort(2424); } @@ -124,11 +146,11 @@ public ODatabaseSession getSession() { orientDB.createIfNotExists(databaseName, ODatabaseType.PLOCAL); - if (session == null) + if (session == null) { session = orientDB.open(databaseName, username, password); - scriptPath.ifPresent(path -> loadScript(path, session)); - + scriptPath.ifPresent(path -> loadScript(path, session)); + } return session; } @@ -155,13 +177,5 @@ private void loadScript(String path, ODatabaseSession session) { } - public OrientDB getOrientDB() { - return orientDB; - } - - public SELF withScriptPath(String scriptPath) { - this.scriptPath = Optional.of(scriptPath); - return self(); - } } diff --git a/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java b/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java index 1b2c1bccfab..2545a44053a 100644 --- a/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java +++ b/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java @@ -5,6 +5,10 @@ import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author robfrank + */ public class OrientDBContainerTest { From fab67ec9b373ddaa5a4b18fe22895ce53755e464 Mon Sep 17 00:00:00 2001 From: robfrank Date: Sun, 17 Feb 2019 14:23:56 +0100 Subject: [PATCH 4/7] removes SELF as per code review --- .../testcontainers/containers/OrientDBContainer.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java index 5624cc55e7b..b01d80d53ca 100644 --- a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java +++ b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java @@ -25,7 +25,7 @@ /** * @author robfrank */ -public class OrientDBContainer> extends GenericContainer { +public class OrientDBContainer extends GenericContainer { private static final String DEFAULT_IMAGE_NAME = "orientdb"; @@ -103,22 +103,22 @@ public String getTestQueryString() { return "SELECT FROM V"; } - public SELF withDatabaseName(final String databaseName) { + public OrientDBContainer withDatabaseName(final String databaseName) { this.databaseName = databaseName; return self(); } - public SELF withUsername(final String username) { + public OrientDBContainer withUsername(final String username) { this.username = username; return self(); } - public SELF withPassword(final String password) { + public OrientDBContainer withPassword(final String password) { this.password = password; return self(); } - public SELF withScriptPath(String scriptPath) { + public OrientDBContainer withScriptPath(String scriptPath) { this.scriptPath = Optional.of(scriptPath); return self(); From 01208f757a9414025bf8e1e57ef1cf458e81f3a2 Mon Sep 17 00:00:00 2001 From: robfrank Date: Tue, 26 Mar 2019 09:25:25 +0100 Subject: [PATCH 5/7] adds orientdb module documentation bumps orientdb version to 3.0.17 --- docs/modules/databases/orientdb.md | 74 ++++++++++++++++++++++++++++++ modules/orientdb/build.gradle | 4 +- 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 docs/modules/databases/orientdb.md diff --git a/docs/modules/databases/orientdb.md b/docs/modules/databases/orientdb.md new file mode 100644 index 00000000000..36ce9696893 --- /dev/null +++ b/docs/modules/databases/orientdb.md @@ -0,0 +1,74 @@ +# OrientDB Module + +This module helps running [OrientDB](https://orientdb.org/download) using Testcontainers. + +Note that it's based on the [official Docker image](https://hub.docker.com/_/orientdb/) provided by OrientDB. + +## Usage example + +Declare your Testcontainer as a `@ClassRule` or `@Rule` in a JUnit 4 test or as static or member attribute of a JUnit 5 test annotated with `@Container` as you would with other Testcontainers. +You can call `getDbUrl()` OrientDB container and build the `ODatabaseSession` by your own, but a more useful `getSession()` method is provided. +On the JVM you would most likely use the [Java driver](https://github.com/). + +The following example uses the JUnit 5 extension `@Testcontainers` and demonstrates both the usage of the Java Client: + +```java tab="JUnit 5 example" +@Testcontainers +public class ExampleTest { + + @Container + private static OrientDBContainer container = new OrientDBContainer(); + + @Test + void testDbCreation() { + + final ODatabaseSession session = container.getSession(); + + session.command("CREATE CLASS Person EXTENDS V"); + session.command("INSERT INTO Person set name='john'"); + session.command("INSERT INTO Person set name='jane'"); + + assertThat(session.query("SELECT FROM Person").stream()).hasSize(2); + } + +} +``` + +You are not limited to Unit tests and can of course use an instance of the OrientDB Testcontainer in vanilla Java code as well. + + +## Adding this module to your project dependencies + +Add the following dependency to your `pom.xml`/`build.gradle` file: + +```groovy tab='Gradle' +testCompile "org.testcontainers:orientdb:{{latest_version}}" +``` + +```xml tab='Maven' + + org.testcontainers + orientdb + {{latest_version}} + test + +``` + +!!! hint + Add the OrientDB Java client if you plan to access the Testcontainer: + + ```groovy tab='Gradle' + compile "com.orientechnologies:orientdb-client:3.0.17" + ``` + + ```xml tab='Maven' + + com.orientechnologies + orientdb-client + 3.0.17 + + ``` + + + + diff --git a/modules/orientdb/build.gradle b/modules/orientdb/build.gradle index 6d721d7a9ce..249c3dde1dd 100644 --- a/modules/orientdb/build.gradle +++ b/modules/orientdb/build.gradle @@ -1,8 +1,8 @@ -description = "TestContainers :: Neo4j" +description = "TestContainers :: Orientdb" dependencies { compile project(":testcontainers") - compile "com.orientechnologies:orientdb-client:3.0.15" + compile "com.orientechnologies:orientdb-client:3.0.17" testCompile 'org.assertj:assertj-core:3.12.0' } From 0c0b2e0131f18557573bbd9de28453f09a5dbde6 Mon Sep 17 00:00:00 2001 From: robfrank Date: Sat, 6 Jun 2020 15:56:05 +0200 Subject: [PATCH 6/7] update to OrientDB 3.1.0 --- docs/modules/databases/orientdb.md | 4 ++-- modules/orientdb/build.gradle | 2 +- .../java/org/testcontainers/containers/OrientDBContainer.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/modules/databases/orientdb.md b/docs/modules/databases/orientdb.md index 80ed96f9548..cd05812e57f 100644 --- a/docs/modules/databases/orientdb.md +++ b/docs/modules/databases/orientdb.md @@ -62,14 +62,14 @@ testCompile "org.testcontainers:orientdb:{{latest_version}}" Add the OrientDB Java client if you plan to access the Testcontainer: ```groovy tab='Gradle' - compile "com.orientechnologies:orientdb-client:3.0.24" + compile "com.orientechnologies:orientdb-client:3.1.0" ``` ```xml tab='Maven' com.orientechnologies orientdb-client - 3.0.24 + 3.1.0 ``` diff --git a/modules/orientdb/build.gradle b/modules/orientdb/build.gradle index ffa1350172a..cc94e3080a4 100644 --- a/modules/orientdb/build.gradle +++ b/modules/orientdb/build.gradle @@ -3,7 +3,7 @@ description = "TestContainers :: Orientdb" dependencies { compile project(":testcontainers") - compile "com.orientechnologies:orientdb-client:3.0.24" + compile "com.orientechnologies:orientdb-client:3.1.0" testCompile 'org.assertj:assertj-core:3.12.0' testCompile 'org.apache.tinkerpop:gremlin-driver:3.3.4' diff --git a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java index b7fcc85573a..6e491ad7c4b 100644 --- a/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java +++ b/modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java @@ -29,7 +29,7 @@ public class OrientDBContainer extends GenericContainer { private static final Logger LOGGER = LoggerFactory.getLogger(OrientDBContainer.class); private static final String DEFAULT_IMAGE_NAME = "orientdb"; - private static final String DEFAULT_TAG = "3.0.24-tp3"; + private static final String DEFAULT_TAG = "3.1.0-tp3"; private static final String DOCKER_IMAGE_NAME = DEFAULT_IMAGE_NAME + ":" + DEFAULT_TAG; private static final String DEFAULT_USERNAME = "admin"; From b03e4854b142ee7cab4f4ccac75c73515cf0f6f4 Mon Sep 17 00:00:00 2001 From: robfrank Date: Sat, 6 Jun 2020 16:12:27 +0200 Subject: [PATCH 7/7] remove test of Gremlin script: Gremlin is not enabled by default since 3.0.28 release note: https://github.com/orientechnologies/orientdb/wiki/OrientDB-3.0-Release-Notes#3028---5-february-2020 --- .../containers/OrientDBContainerTest.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java b/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java index 54b0661cae2..860e1f841a4 100644 --- a/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java +++ b/modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java @@ -37,23 +37,6 @@ public void shouldInitializeWithCommands() { } } - @Test - public void shouldQueryWithGremlin() { - - try (OrientDBContainer container = new OrientDBContainer()) { - container.start(); - - final ODatabaseSession session = container.getSession("admin", "admin"); - - session.command("CREATE CLASS Person EXTENDS V"); - session.command("INSERT INTO Person set name='john'"); - session.command("INSERT INTO Person set name='jane'"); - - assertThat(session.execute("gremlin", - "g.V().hasLabel('Person')").stream()).hasSize(2); - } - } - @Test public void shouldInitializeDatabaseFromScript() { try (OrientDBContainer container = new OrientDBContainer()