Want to run Oracle REST Data Services (ORDS) for integration tests, local experiments, or prototyping? This sample combines ORDS and Oracle AI Database Free in a disposable test environment with Testcontainers and one Maven command.
If you want to skip straight to the code, the full sample is here: ords-testcontainers sample on GitHub
The module exercises three useful things in one place:
- Start Oracle AI Database Free in a JUnit test with Testcontainers.
- Start ORDS in a second container on the same Docker network and enable schemas during startup.
- Verify both a normal ORDS HTTP endpoint and MongoDB CRUD over ORDS’s MongoDB API.

Prerequisites
You only need a few things:
- Java 21+
- Maven
- A Docker-compatible container runtime
- Access to
container-registry.oracle.com/database/ords:latest
Run it locally
From the module root, run:
mvn testThe test verifies ORDS startup, the ORDS Database Admin API, and MongoDB CRUD via ORDS.
The source for this module is here: ords-testcontainers sample on GitHub
How the sample works
An Oracle AI Database Free container is initialized with the following users:
ordsuserfor the ORDS Database API examplemongouserfor the MongoDB CRUD example
Then an ORDS container starts, points it at the database container, and REST-enables both schemas.
That the test then verifies:
- ORDS over HTTP on port
8080 - ORDS’s MongoDB API on port
27017
The custom ORDS container
The key piece is the OrdsContainer class. This class extends Testcontainer’s GenericContainer to bundle ORDS as a reusable container type:
public class OrdsContainer extends GenericContainer<OrdsContainer> {
public static final String DEFAULT_IMAGE = "container-registry.oracle.com/database/ords:latest";
public static final int HTTP_PORT = 8080;
public static final int HTTPS_PORT = 8443;
public static final int MONGODB_API_PORT = 27017;
public OrdsContainer withDatabaseConnectionString(String connectionString) {
return withEnv("CONN_STRING", connectionString);
}
public OrdsContainer withOraclePassword(String oraclePassword) {
return withEnv("ORACLE_PWD", oraclePassword);
}
public OrdsContainer withSchema(String username, String password, String connectDescriptor) {
schemas.add(new SchemaConfiguration(username, password, connectDescriptor));
return self();
}
}
// ... class methodsOn startup, the class waits for ORDS over HTTP and runs ORDS.ENABLE_SCHEMA for each configured schema.
See the full container class: src/main/java/com/example/ords/OrdsContainer.java
Combining Oracle AI Database Free and ORDS containers as a test component
The test uses a shared Testcontainers network so ORDS can reach Oracle AI Database Free by a container alias:
private static final Network NETWORK = Network.newNetwork();
private static final OracleContainer oracleContainer = new OracleContainer(DATABASE_IMAGE)
.withStartupTimeout(Duration.ofMinutes(5))
.withPassword(ADMIN_PASSWORD)
.withNetwork(NETWORK)
.withNetworkAliases(DATABASE_ALIAS);
private static final OrdsContainer ordsContainer = new OrdsContainer()
.withNetwork(NETWORK)
.withDatabaseConnectionString(DATABASE_CONNECTION)
.withOraclePassword(ADMIN_PASSWORD)
.withSchema(DB_API_ADMIN_USERNAME, DB_API_ADMIN_PASSWORD, SCHEMA_CONNECTION)
.withSchema(MONGO_USERNAME, MONGO_PASSWORD, SCHEMA_CONNECTION);
@BeforeAll
static void startContainers() throws IOException, InterruptedException {
oracleContainer.start();
initializeDatabase();
ordsContainer.start();
}
// ...test methodsThat startup sequence works like this:
- Start Oracle AI Database Free.
- Run a SQL initialization script.
- Start ORDS against that database.
See the full test here: src/test/java/com/example/ords/OrdsContainerIntegrationTest.java
Database Admin API and MongoDB users
The SQL setup script creates users for the ORDS APIs; a Database Admin API user, and a MongoDB API user:
ALTER SESSION SET CONTAINER = freepdb1;
CREATE USER ordsuser IDENTIFIED BY ordsuserpwd QUOTA UNLIMITED ON users;
GRANT connect, pdb_dba TO ordsuser;
CREATE USER mongouser IDENTIFIED BY mongouserpwd QUOTA UNLIMITED ON users;
GRANT create session, create table, soda_app TO mongouser;The ordsuser account is used to test the ORDS Database Admin API. The mongouser account is used to test CRUD operations through the MongoDB translation API.
See the init script: src/test/resources/ords_init.sql
Verifying the ORDS Database API
We run a simple HTTP request to test the ORDS Database Admin API:
HttpResponse<String> response = HTTP_CLIENT.send(
HttpRequest.newBuilder(URI.create(ordsDatabaseApiUrl("database/version")))
.header("Authorization", basicAuth(DB_API_ADMIN_USERNAME, DB_API_ADMIN_PASSWORD))
.GET()
.timeout(Duration.ofSeconds(30))
.build(),
HttpResponse.BodyHandlers.ofString()
);
assertEquals(200, response.statusCode());This is would be awkward to test with mocks, but straightforward with disposable containers. You get a real ORDS instance, a real HTTP response, and a real JSON payload back from the database admin API.
The MongoDB part is the fun part
The most interesting part of the test sample is that it uses the MongoDB Java driver to talk to ORDS:
ConnectionString connectionString = new ConnectionString(
"mongodb://%s:%s@%s:%d/%s?authMechanism=PLAIN&authSource=%%24external&tls=true&retryWrites=false&loadBalanced=true"
.formatted(
MONGO_USERNAME,
MONGO_PASSWORD,
ordsContainer.getHost(),
ordsContainer.getMongoDbApiPort(),
MONGO_USERNAME
)
);
return MongoClientSettings.builder()
.applyConnectionString(connectionString)
.applyToSslSettings(builder -> builder
.enabled(true)
.invalidHostNameAllowed(true)
.context(INSECURE_TLS_CONTEXT))
.build();That’s standard mongodb-driver-sync code, nothing Oracle-specific. The test then does a straightforward CRUD cycle:
collection.insertOne(originalDocument);
Document insertedDocument = collection.find(Filters.eq("_id", documentId)).first();
collection.updateOne(
Filters.eq("_id", documentId),
Updates.set("credits", 15)
);
collection.deleteOne(Filters.eq("_id", documentId));If you’ve used the MongoDB Java driver, this should look familiar: ORDS provides a translation layer for MongoDB HTTP calls while your application code can use the same MongoDB clients.
See the full MongoDB setup and CRUD test: src/test/java/com/example/ords/OrdsContainerIntegrationTest.java
Note: the sample trusts the ORDS certificate for convenience in a local test. This is a test-only shortcut. Usually, you’d supply ORDS with a trusted certificate and configure the client accordingly.
Why this is a good local developer workflow
This sample keeps the barrier to entry low:
- run everything locally, using free-tier versions
- the stack is disposable
- the code stays close to plain JUnit and Testcontainers
- the ORDS example is not limited to simple HTTP checks
- the MongoDB example shows a capability that many developers will immediately understand
This is a great resource for devs evaluating ORDS, testing ORDS-backed application code, or exploring Oracle AI Database Free.
Next steps
If you want to keep going after this sample, the best next move is to explore the source directly. This sample can be adapted to work with Testcontainers in other languages, like Typescript, Python, or Go. If you attempt this, let me know!

Leave a Reply