Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Srinivasa Vasu <srinivasan.surprise@gmail.com>
- Loading branch information
1 parent
ef921c3
commit a4b6e20
Showing
15 changed files
with
789 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# YugabyteDB Module | ||
|
||
See [Database containers](./index.md) for documentation and usage that is common to all database container types. | ||
|
||
YugabyteDB supports two APIs. | ||
- Yugabyte Structured Query Language [YSQL](https://docs.yugabyte.com/latest/api/ysql/) is a fully-relational API that is built by the PostgreSQL code | ||
- Yugabyte Cloud Query Language [YCQL](https://docs.yugabyte.com/latest/api/ycql/) is a semi-relational SQL API that has its roots in the Cassandra Query Language | ||
|
||
## Usage example | ||
|
||
### YSQL API | ||
|
||
```java | ||
public class YugabyteDBTest { | ||
|
||
@Rule | ||
public YugabyteYSQLContainer container = new YugabyteYSQLContainer("yugabytedb/yugabyte:2.7.2.0-b216"); | ||
|
||
@Test | ||
public void method() { | ||
String url = container.getJdbcUrl(); | ||
|
||
... create a connection and run the tests as usual. It also depends on the frameworks being used. | ||
``` | ||
|
||
#### JDBC URL | ||
|
||
`jdbc:tc:yugabyte:2.7.2.0-b216:///yugabyte` | ||
|
||
### YCQL API | ||
|
||
```java | ||
public class YugabyteDBTest { | ||
|
||
@Rule | ||
public YugabyteYCQLContainer container = new YugabyteYCQLContainer("yugabytedb/yugabyte:2.7.2.0-b216"); | ||
|
||
@Test | ||
public void method() { | ||
Session session = container.getSession(); | ||
|
||
... create a connection and run the tests as usual. It also depends on the frameworks being used. | ||
``` | ||
|
||
## Adding this module to your project dependencies | ||
[[TODO]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
description = "Testcontainers :: JDBC :: YugabyteDB" | ||
|
||
dependencies { | ||
api project(':jdbc') | ||
testImplementation project(':jdbc-test') | ||
// YCQL driver | ||
implementation 'com.yugabyte:java-driver-core:4.6.0-yb-6' | ||
// YSQL driver | ||
testImplementation 'com.yugabyte:jdbc-yugabytedb:42.2.7-yb-5-beta.2' | ||
} |
42 changes: 42 additions & 0 deletions
42
...es/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteContainerConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.testcontainers.containers; | ||
|
||
import org.testcontainers.utility.DockerImageName; | ||
|
||
/** | ||
* Constants used in both YCQL and YSQL APIs | ||
* | ||
* @author srinivasa-vasu | ||
*/ | ||
public interface YugabyteContainerConstants { | ||
|
||
DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("yugabytedb/yugabyte"); | ||
|
||
String DEFAULT_TAG = "2.7.2.0-b216"; | ||
|
||
String NAME = "yugabyte"; | ||
|
||
Integer YSQL_PORT = 5433; | ||
|
||
Integer YCQL_PORT = 9042; | ||
|
||
Integer MASTER_DASHBOARD_PORT = 7000; | ||
|
||
Integer TSERVER_DASHBOARD_PORT = 9000; | ||
|
||
String JDBC_DRIVER_CLASS = "org.postgresql.Driver"; | ||
|
||
String JDBC_CONNECT_PREFIX = "jdbc:postgresql"; | ||
|
||
String ENTRYPOINT = "bin/yugabyted start --daemon=false"; | ||
|
||
String LOCAL_DC = "datacenter1"; | ||
|
||
String USER_PARAM = "user"; | ||
|
||
String PASSWORD_PARAM = "password"; | ||
|
||
String YSQL_TEST_QUERY = "SELECT 1"; | ||
|
||
String YCQL_TEST_QUERY = "SELECT release_version FROM system.local"; | ||
|
||
} |
160 changes: 160 additions & 0 deletions
160
modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteYCQLContainer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package org.testcontainers.containers; | ||
|
||
import java.net.InetSocketAddress; | ||
import java.time.Duration; | ||
|
||
import com.datastax.oss.driver.api.core.CqlSession; | ||
import com.datastax.oss.driver.api.core.CqlSessionBuilder; | ||
import com.github.dockerjava.api.command.InspectContainerResponse; | ||
import org.testcontainers.containers.delegate.YugabyteYCQLDelegate; | ||
import org.testcontainers.containers.strategy.YugabyteYCQLWaitStrategy; | ||
import org.testcontainers.ext.ScriptUtils; | ||
import org.testcontainers.utility.DockerImageName; | ||
|
||
import static org.testcontainers.containers.YugabyteContainerConstants.DEFAULT_IMAGE_NAME; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.ENTRYPOINT; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.LOCAL_DC; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.MASTER_DASHBOARD_PORT; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.TSERVER_DASHBOARD_PORT; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.YCQL_PORT; | ||
|
||
/** | ||
* YugabyteDB YCQL (Cloud Query Language) API container | ||
* | ||
* @author srinivasa-vasu | ||
* @see <a href="https://docs.yugabyte.com/latest/api/ycql/">YCQL API</a> | ||
*/ | ||
public class YugabyteYCQLContainer extends GenericContainer<YugabyteYCQLContainer> { | ||
|
||
private String keyspace; | ||
|
||
private String username; | ||
|
||
private String password; | ||
|
||
private String initScript; | ||
|
||
/** | ||
* @param imageName image name | ||
*/ | ||
public YugabyteYCQLContainer(final String imageName) { | ||
this(DockerImageName.parse(imageName)); | ||
} | ||
|
||
/** | ||
* @param imageName image name | ||
*/ | ||
public YugabyteYCQLContainer(final DockerImageName imageName) { | ||
super(imageName); | ||
imageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); | ||
withExposedPorts(YCQL_PORT, MASTER_DASHBOARD_PORT, TSERVER_DASHBOARD_PORT); | ||
waitingFor(new YugabyteYCQLWaitStrategy(this).withStartupTimeout(Duration.ofSeconds(60))); | ||
withCommand(ENTRYPOINT); | ||
} | ||
|
||
/** | ||
* Configures the environment variables. Setting up these variables would create the | ||
* custom objects. Setting {@link #withKeyspaceName(String)}, | ||
* {@link #withUsername(String)}, {@link #withPassword(String)} these parameters will | ||
* initilaize the database with those custom values | ||
*/ | ||
@Override | ||
protected void configure() { | ||
addEnv("YCQL_KEYSPACE", keyspace); | ||
addEnv("YCQL_USER", username); | ||
addEnv("YCQL_PASSWORD", password); | ||
} | ||
|
||
/** | ||
* @param initScript path of the initialization script file | ||
* @return {@link YugabyteYCQLContainer} instance | ||
*/ | ||
public YugabyteYCQLContainer withInitScript(String initScript) { | ||
this.initScript = initScript; | ||
return this; | ||
} | ||
|
||
/** | ||
* Setting this would create the keyspace | ||
* @param keyspace keyspace | ||
* @return {@link YugabyteYCQLContainer} instance | ||
*/ | ||
public YugabyteYCQLContainer withKeyspaceName(final String keyspace) { | ||
this.keyspace = keyspace; | ||
return this; | ||
} | ||
|
||
/** | ||
* Setting this would create the custom user role | ||
* @param username user name | ||
* @return {@link YugabyteYCQLContainer} instance | ||
*/ | ||
public YugabyteYCQLContainer withUsername(final String username) { | ||
this.username = username; | ||
return this; | ||
} | ||
|
||
/** | ||
* Setting this along with {@link #withUsername(String)} would enable authentication | ||
* @param password password | ||
* @return {@link YugabyteYCQLContainer} instance | ||
*/ | ||
public YugabyteYCQLContainer withPassword(final String password) { | ||
this.password = password; | ||
return this; | ||
} | ||
|
||
/** | ||
* Executes the initilization script | ||
* @param containerInfo containerInfo | ||
*/ | ||
@Override | ||
protected void containerIsStarted(InspectContainerResponse containerInfo) { | ||
if (initScript != null) { | ||
ScriptUtils.runInitScript(new YugabyteYCQLDelegate(getSessionBuilder()), initScript); | ||
} | ||
} | ||
|
||
/** | ||
* Builds a {@link CqlSession} instance | ||
* @return {@link CqlSession} instance | ||
*/ | ||
public CqlSession getSession() { | ||
return getSessionBuilder().build(); | ||
} | ||
|
||
/** | ||
* Builder method for {#com.datastax.oss.driver.api.core.CqlSession} | ||
* @return {@link CqlSessionBuilder} | ||
*/ | ||
public CqlSessionBuilder getSessionBuilder() { | ||
return CqlSession.builder().withLocalDatacenter(LOCAL_DC).withKeyspace(this.getKeyspace()) | ||
.withAuthCredentials(this.getUsername(), this.getPassword()) | ||
.addContactPoint(new InetSocketAddress(this.getHost(), this.getMappedPort(YCQL_PORT))); | ||
} | ||
|
||
/** | ||
* Username getter method | ||
* @return username | ||
*/ | ||
public String getUsername() { | ||
return username; | ||
} | ||
|
||
/** | ||
* Password getter method | ||
* @return password | ||
*/ | ||
public String getPassword() { | ||
return password; | ||
} | ||
|
||
/** | ||
* Keyspace getter method | ||
* @return keyspace | ||
*/ | ||
public String getKeyspace() { | ||
return keyspace; | ||
} | ||
|
||
} |
137 changes: 137 additions & 0 deletions
137
modules/yugabytedb/src/main/java/org/testcontainers/containers/YugabyteYSQLContainer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package org.testcontainers.containers; | ||
|
||
import java.time.Duration; | ||
import java.util.Set; | ||
|
||
import org.testcontainers.containers.strategy.YugabyteYSQLWaitStrategy; | ||
import org.testcontainers.utility.DockerImageName; | ||
|
||
import static java.util.Collections.singleton; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.DEFAULT_IMAGE_NAME; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.ENTRYPOINT; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.JDBC_CONNECT_PREFIX; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.JDBC_DRIVER_CLASS; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.MASTER_DASHBOARD_PORT; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.TSERVER_DASHBOARD_PORT; | ||
import static org.testcontainers.containers.YugabyteContainerConstants.YSQL_PORT; | ||
|
||
/** | ||
* YugabyteDB YSQL (Structured Query Language) API container | ||
* | ||
* @author srinivasa-vasu | ||
* @see <a href="https://docs.yugabyte.com/latest/api/ysql/">YSQL API</a> | ||
*/ | ||
|
||
public class YugabyteYSQLContainer extends JdbcDatabaseContainer<YugabyteYSQLContainer> { | ||
|
||
private String database = "yugabyte"; | ||
|
||
private String username = "yugabyte"; | ||
|
||
private String password = "yugabyte"; | ||
|
||
/** | ||
* @param imageName image name | ||
*/ | ||
public YugabyteYSQLContainer(final String imageName) { | ||
this(DockerImageName.parse(imageName)); | ||
} | ||
|
||
/** | ||
* @param imageName image name | ||
*/ | ||
public YugabyteYSQLContainer(final DockerImageName imageName) { | ||
super(imageName); | ||
imageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); | ||
withExposedPorts(YSQL_PORT, MASTER_DASHBOARD_PORT, TSERVER_DASHBOARD_PORT); | ||
waitingFor(new YugabyteYSQLWaitStrategy(this).withStartupTimeout(Duration.ofSeconds(60))); | ||
withCommand(ENTRYPOINT); | ||
} | ||
|
||
@Override | ||
public Set<Integer> getLivenessCheckPortNumbers() { | ||
return singleton(getMappedPort(YSQL_PORT)); | ||
} | ||
|
||
/** | ||
* Configures the environment variables. Setting up these variables would create the | ||
* custom objects. Setting {@link #withDatabaseName(String)}, | ||
* {@link #withUsername(String)}, {@link #withPassword(String)} these parameters will | ||
* initilaize the database with those custom values | ||
*/ | ||
|
||
@Override | ||
protected void configure() { | ||
addEnv("YSQL_DB", database); | ||
addEnv("YSQL_USER", username); | ||
addEnv("YSQL_PASSWORD", password); | ||
} | ||
|
||
@Override | ||
public String getDriverClassName() { | ||
return JDBC_DRIVER_CLASS; | ||
} | ||
|
||
@Override | ||
public String getJdbcUrl() { | ||
return JDBC_CONNECT_PREFIX + "://" + getHost() + ":" + getMappedPort(YSQL_PORT) + "/" + database | ||
+ constructUrlParameters("?", "&"); | ||
} | ||
|
||
@Override | ||
public String getDatabaseName() { | ||
return database; | ||
} | ||
|
||
@Override | ||
public String getUsername() { | ||
return username; | ||
} | ||
|
||
@Override | ||
public String getPassword() { | ||
return password; | ||
} | ||
|
||
@Override | ||
public String getTestQueryString() { | ||
return "SELECT 1"; | ||
} | ||
|
||
/** | ||
* Setting this would create the keyspace | ||
* @param database database name | ||
* @return {@link YugabyteYSQLContainer} instance | ||
*/ | ||
|
||
@Override | ||
public YugabyteYSQLContainer withDatabaseName(final String database) { | ||
this.database = database; | ||
return this; | ||
} | ||
|
||
/** | ||
* Setting this would create the custom user role | ||
* @param username user name | ||
* @return {@link YugabyteYSQLContainer} instance | ||
*/ | ||
|
||
@Override | ||
public YugabyteYSQLContainer withUsername(final String username) { | ||
this.username = username; | ||
return this; | ||
} | ||
|
||
/** | ||
* Setting this along with {@link #withUsername(String)} would enable authentication | ||
* @param password password | ||
* @return {@link YugabyteYSQLContainer} instance | ||
*/ | ||
|
||
@Override | ||
public YugabyteYSQLContainer withPassword(final String password) { | ||
this.password = password; | ||
return this; | ||
} | ||
|
||
} |
Oops, something went wrong.