Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow consumption of a relational database testcontainer through R2DBC #1003

Open
mp911de opened this issue Dec 3, 2018 · 1 comment

Comments

@mp911de
Copy link

@mp911de mp911de commented Dec 3, 2018

R2DBC is an initiative to establish a reactive API for relational database integration. It would be great to additionally consume a test container with a relational database through R2DBC by exposing the connection through a preconfigured ConnectionFactory.

ConnectionFactory is in R2DBC what a DataSource is in JDBC. R2DBC drivers are available for:

More to come eventually.

Right now I can think of the following consumption scenarios:

  • Pure JDBC (available today)
  • JDBC and R2DBC (would make a lot of sense for testing as JDBC can help to prevent additional synchronization in cases where fixtures are prepared via JDBC and the actual application consumes data using reactive APIs)
  • R2DBC-only (useful in pure reactive environments)
@mp911de

This comment has been minimized.

Copy link
Author

@mp911de mp911de commented Aug 16, 2019

I took a look at how R2DBC could be implemented and found that a suitable implementation might be hard to achieve because of the way how containers are organized.

Here are my thoughts:

SQL databases are assumed to be JDBC containers and not Database containers. Adding a getR2dbcConnectionUrl() would provide a pre-constructed URL for R2DBC usage on specific containers. At the same time, it would make sense to have a common interface for database I/O. What would be the right place for such an interface?

Ideally, database containers are represented as subclass of DatabaseContainer or SqlDatabaseContainer where DatabaseContainer exposes several methods that are now defined on JdbcDatabaseContainer (such as getUsername, getPassword, getTestQueryString, withInitScript, withConnectTimeoutSeconds).

JdbcDatabaseContainer could potentially survive as a general-purpose container. The actual container implementations (MySQLContainer, PostgreSQLContainer) would extend DatabaseContainer and implement a JDBC-specific interface. Containers, which are also available with R2DBC access, would implement an R2DBC-specific interface.

This brings us ultimately to ContainerDatabaseDriver: ContainerDatabaseDriver holds references to started containers. Now, if we would like to provide a similar feature for R2DBC, then we would need to replicate what happens in ContainerDatabaseDriver.

If a test wants to use JDBC and R2DBC using URL-based container bootstrapping, then potentially, we would end up with two container instances. But what we rather want to achieve is a test setup where both integration technologies (JDBC and R2DBC) point to the same database (jdbc:tc:mysql:5.6.23://somehostname:someport/databasename and r2dbc:tc:mysql:5.6.23://somehostname:someport/databasename). This is because typical bootstrapping use-cases (schema and data setup) fully synchronous cases whereas running application code would use R2DBC technology.

That being said, a potential design could be:

  • Rename jdbc module to database
  • Introduce database abstraction for containers
  • Refactor ContainerDatabaseDriver to extract the running container registry to a shared class
  • DatabaseDelegate could probably stay as-is
  • Introduce ConnectionFactoryProvider/ConnectionFactory for R2DBC Connection URL container bootstrapping
  • Introduce JDBC and R2DBC interfaces. Existing JDBC functionality can be encapsulated with default methods and package-private implementations
  • Update SQL databases with appropriate interfaces

This way, containers can be consumed without pulling R2DBC API and are appropriately segregated by access technology.

Let me know what you think, whether that is something worth pursuing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.