CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-testcontainers--oracle-xe

Testcontainers module for Oracle XE database - provides lightweight, throwaway instances of Oracle XE database for integration testing

Overview
Eval results
Files

r2dbc-connectivity.mddocs/

R2DBC Connectivity

Reactive database connectivity using R2DBC for non-blocking database operations. Provides factory methods and configuration options for reactive programming patterns with Oracle databases.

Capabilities

R2DBC Container Wrapper

Wraps Oracle XE containers to provide R2DBC connectivity with automatic connection factory configuration and lifecycle management delegation.

public class OracleR2DBCDatabaseContainer implements R2DBCDatabaseContainer {
    public OracleR2DBCDatabaseContainer(OracleContainer container);
    public static ConnectionFactoryOptions getOptions(OracleContainer container);
    public ConnectionFactoryOptions configure(ConnectionFactoryOptions options);
}

Parameters:

  • container (OracleContainer): Underlying Oracle container instance

Returns:

  • ConnectionFactoryOptions: Configured R2DBC connection options
  • OracleR2DBCDatabaseContainer: R2DBC wrapper instance

Usage Example:

// Create Oracle container
OracleContainer oracleContainer = new OracleContainer("gvenzl/oracle-xe:18.4.0-slim")
    .withDatabaseName("r2dbc_test")
    .withUsername("r2dbcuser")
    .withPassword("r2dbcpass");

// Wrap with R2DBC container
OracleR2DBCDatabaseContainer r2dbcContainer = 
    new OracleR2DBCDatabaseContainer(oracleContainer);

// Start container (delegated to underlying Oracle container)
r2dbcContainer.start();

// Get connection factory options
ConnectionFactoryOptions options = OracleR2DBCDatabaseContainer.getOptions(oracleContainer);

Connection Factory Configuration

Automatically configures R2DBC connection factory options with Oracle-specific driver settings, host/port mapping, and authentication credentials.

public ConnectionFactoryOptions configure(ConnectionFactoryOptions options);

Parameters:

  • options (ConnectionFactoryOptions): Base connection factory options

Returns:

  • ConnectionFactoryOptions: Configured options with Oracle container details

Usage Example:

OracleContainer container = new OracleContainer("gvenzl/oracle-xe:18.4.0-slim");
container.start();

OracleR2DBCDatabaseContainer r2dbcContainer = new OracleR2DBCDatabaseContainer(container);

// Configure connection factory options
ConnectionFactoryOptions baseOptions = ConnectionFactoryOptions.builder()
    .option(ConnectionFactoryOptions.DRIVER, "oracle")
    .build();

ConnectionFactoryOptions configuredOptions = r2dbcContainer.configure(baseOptions);

// Result includes:
// - HOST: container.getHost()
// - PORT: container.getMappedPort(OracleContainer.ORACLE_PORT)
// - DATABASE: container.getDatabaseName()
// - USER: container.getUsername()
// - PASSWORD: container.getPassword()

R2DBC Container Provider

Service Provider Interface (SPI) implementation for automatic R2DBC container discovery and creation with connection factory metadata support.

public class OracleR2DBCDatabaseContainerProvider implements R2DBCDatabaseContainerProvider {
    static final String DRIVER = "oracle";
    
    public boolean supports(ConnectionFactoryOptions options);
    public R2DBCDatabaseContainer createContainer(ConnectionFactoryOptions options);
    public ConnectionFactoryMetadata getMetadata(ConnectionFactoryOptions options);
}

Parameters:

  • options (ConnectionFactoryOptions): R2DBC connection factory options

Returns:

  • boolean: Whether provider supports the driver type
  • R2DBCDatabaseContainer: New R2DBC container instance
  • ConnectionFactoryMetadata: Connection metadata with defaults

Usage Example:

// Create connection factory options
ConnectionFactoryOptions options = ConnectionFactoryOptions.builder()
    .option(ConnectionFactoryOptions.DRIVER, "oracle")
    .option(ConnectionFactoryOptions.DATABASE, "testdb")
    .option(IMAGE_TAG_OPTION, "18.4.0-slim")
    .option(REUSABLE_OPTION, true)
    .build();

// Use provider
OracleR2DBCDatabaseContainerProvider provider = new OracleR2DBCDatabaseContainerProvider();

// Check support
boolean supports = provider.supports(options); // true for oracle driver

// Create container
R2DBCDatabaseContainer r2dbcContainer = provider.createContainer(options);

// Get metadata with defaults
ConnectionFactoryMetadata metadata = provider.getMetadata(options);
// Automatically adds default USER and PASSWORD if not specified

Lifecycle Management

R2DBC containers delegate lifecycle operations to the underlying Oracle container while implementing the Startable interface for seamless integration.

// Delegated methods from Startable interface
public void start();
public void stop();
public boolean isRunning();

Usage Example:

OracleContainer oracleContainer = new OracleContainer("gvenzl/oracle-xe:18.4.0-slim");
OracleR2DBCDatabaseContainer r2dbcContainer = new OracleR2DBCDatabaseContainer(oracleContainer);

// Lifecycle operations (delegated to Oracle container)
r2dbcContainer.start();
boolean running = r2dbcContainer.isRunning();
r2dbcContainer.stop();

// Container state is managed by underlying Oracle container
assertEquals(oracleContainer.isRunning(), r2dbcContainer.isRunning());

Integration Patterns

Spring WebFlux Integration

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
class ReactiveOracleTest {
    
    @Container
    static OracleContainer oracle = new OracleContainer("gvenzl/oracle-xe:18.4.0-slim")
        .withDatabaseName("reactive_test");
    
    @DynamicPropertySource
    static void configureProperties(DynamicPropertyRegistry registry) {
        ConnectionFactoryOptions options = OracleR2DBCDatabaseContainer.getOptions(oracle);
        
        registry.add("spring.r2dbc.url", () -> 
            "r2dbc:oracle://" + options.getRequiredValue(ConnectionFactoryOptions.HOST) +
            ":" + options.getRequiredValue(ConnectionFactoryOptions.PORT) +
            "/" + options.getRequiredValue(ConnectionFactoryOptions.DATABASE)
        );
        registry.add("spring.r2dbc.username", oracle::getUsername);
        registry.add("spring.r2dbc.password", oracle::getPassword);
    }
    
    @Autowired
    private R2dbcEntityTemplate template;
    
    @Test
    void testReactiveConnection() {
        StepVerifier.create(
            template.getDatabaseClient()
                .sql("SELECT 1 FROM DUAL")
                .map(row -> row.get(0, Integer.class))
                .one()
        )
        .expectNext(1)
        .verifyComplete();
    }
}

Direct R2DBC Usage

@Test
void testDirectR2DBCUsage() {
    OracleContainer container = new OracleContainer("gvenzl/oracle-xe:18.4.0-slim");
    container.start();
    
    // Get connection factory options
    ConnectionFactoryOptions options = OracleR2DBCDatabaseContainer.getOptions(container);
    
    // Create connection factory
    ConnectionFactory connectionFactory = ConnectionFactories.get(options);
    
    // Use reactive connection
    Mono.from(connectionFactory.create())
        .flatMap(connection -> 
            Mono.from(connection.createStatement("SELECT SYSDATE FROM DUAL")
                .execute())
                .flatMap(result -> 
                    Mono.from(result.map((row, metadata) -> 
                        row.get(0, LocalDateTime.class))))
                .doFinally(signal -> connection.close())
        )
        .as(StepVerifier::create)
        .expectNextMatches(timestamp -> timestamp != null)
        .verifyComplete();
}

Reactive Repository Pattern

@Repository
public class ReactiveUserRepository {
    
    private final R2dbcEntityTemplate template;
    
    public ReactiveUserRepository(R2dbcEntityTemplate template) {
        this.template = template;
    }
    
    public Flux<User> findAllUsers() {
        return template.select(User.class)
            .from("users")
            .all();
    }
    
    public Mono<User> saveUser(User user) {
        return template.insert(User.class)
            .using(user);
    }
    
    public Mono<User> findUserById(Long id) {
        return template.select(User.class)
            .from("users")
            .matching(query(where("id").is(id)))
            .one();
    }
}

@Test
void testReactiveRepository() {
    // Container setup
    OracleContainer container = new OracleContainer("gvenzl/oracle-xe:18.4.0-slim")
        .withInitScript("classpath:schema.sql");
    container.start();
    
    // Configure R2DBC
    ConnectionFactoryOptions options = OracleR2DBCDatabaseContainer.getOptions(container);
    ConnectionFactory connectionFactory = ConnectionFactories.get(options);
    R2dbcEntityTemplate template = new R2dbcEntityTemplate(connectionFactory);
    
    ReactiveUserRepository repository = new ReactiveUserRepository(template);
    
    // Test reactive operations
    User newUser = new User("Alice", "alice@example.com");
    
    StepVerifier.create(
        repository.saveUser(newUser)
            .then(repository.findAllUsers().collectList())
    )
    .expectNextMatches(users -> users.size() == 1)
    .verifyComplete();
}

Connection Factory Options

The R2DBC Oracle connection factory supports the following standard options:

// Standard R2DBC options
ConnectionFactoryOptions.DRIVER = "oracle"
ConnectionFactoryOptions.HOST = container.getHost()
ConnectionFactoryOptions.PORT = container.getMappedPort(OracleContainer.ORACLE_PORT)
ConnectionFactoryOptions.DATABASE = container.getDatabaseName()
ConnectionFactoryOptions.USER = container.getUsername()
ConnectionFactoryOptions.PASSWORD = container.getPassword()

// Testcontainers-specific options
IMAGE_TAG_OPTION = "18.4.0-slim" // Docker image tag
REUSABLE_OPTION = true           // Container reuse flag

Default Credentials

When connection factory options don't specify user credentials, the R2DBC provider automatically applies default values:

  • Default User: "test" (OracleContainer.APP_USER)
  • Default Password: "test" (OracleContainer.APP_USER_PASSWORD)

This ensures seamless integration even when credentials are not explicitly configured in the connection factory options.

Install with Tessl CLI

npx tessl i tessl/maven-org-testcontainers--oracle-xe

docs

container-configuration.md

index.md

jdbc-connectivity.md

r2dbc-connectivity.md

tile.json