Skip to content

enable database custom alias configuration #4#2294

Closed
SaschaJohn wants to merge 3 commits into
testcontainers:masterfrom
SaschaJohn:master
Closed

enable database custom alias configuration #4#2294
SaschaJohn wants to merge 3 commits into
testcontainers:masterfrom
SaschaJohn:master

Conversation

@SaschaJohn

Copy link
Copy Markdown

@bsideup @rnorth
my approach so solve #4
I also added documenttaion and testcases.
Looking forward for feedback.

Regards

Sascha

import com.zaxxer.hikari.HikariDataSource;

@RunWith(Parameterized.class)
public class JDBCDriverAliasPropertiesTest {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class should be a unit test. We should test that aliases map to the right db type/image, there is no need to actually start the DB

Properties p = new Properties();
p.put("jdbc.alias.mysqlserver.type", "sqlserver");
p.put("jdbc.alias.mysqlserver.image", "mcr.microsoft.com/mssql/server");
ContainerDatabaseDriver.clearJBDCAliasProperties();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should use the configuration mock, see other configuration-sensitive tests (e.g. tests for the reusable mode)

import com.zaxxer.hikari.HikariDataSource;

@RunWith(Parameterized.class)
public class JDBCDriverAliasTest {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should also be a unit test

}

private void performSimpleTest(HikariDataSource dataSource) throws SQLException {
protected void performSimpleTest(HikariDataSource dataSource) throws SQLException {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated?

@@ -1,2 +1,3 @@
mcr.microsoft.com/mssql/server:2017-CU12
mcmoe/mssqldocker:latest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove after converting into a unit test, we should not accept licenses of 3rd party images

private Driver delegate;
private static final Map<String, Set<Connection>> containerConnections = new HashMap<>();
private static final Map<String, JdbcDatabaseContainer> jdbcUrlContainerCache = new HashMap<>();
private static final Map<String, Map<String, String>> jdbcAliasMap = new HashMap<String, Map<String,String>>();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make Map's value a type, not just Map<String, String>

*/
public ContainerDatabaseDriver() {
super();
mapJBDCAliasProperties(TestcontainersConfiguration.getInstance().getProperties());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why cached? You can get the property when you encounter an alias

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bsideup we don't know the aliases without reading the configuration at instanciation.
IMHO it's the easiest way to implement it here, otherwise we won't be able to find candiate containers with the alias and have to see if the name is an alias afterwards...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but you don't need it at instantiation time.

The algorithm should be something like:

  1. get the type from the JDBC URL
  2. try to get alias by it
  3. if not found, fallback to the default one (the behaviour before this PR)


String queryString = connectionUrl.getQueryString().orElse("");
String queryString = connectionUrl.getQueryString().orElse("");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please fix the formatting

*/
private String getAliasTag(Map<String, String> aliasMap, JdbcDatabaseContainer container) {
String tag = aliasMap.get("tag");
if (tag == null) { // no tag was set, so use the default one

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong formatting

container = candidateContainerType.newInstance(connectionUrl);

if (wasAlias) { //overwrite image and tag
container.setDockerImageName(aliasMap.get("image")+":"+getAliasTag(aliasMap, container));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not feel like the right place to do it. Consider handling aliases in JdbcDatabaseContainerProvider#newInstance. We may also need to introduce a new API there to handle new instance creation with custom image

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bsideup
newInstance() is overridden in implementing modules, I didn't want to touch existing modules.
For me it's the smartest way to overwrite the imageName right after instance creation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is why I was talking about introducing a new API. setDockerImageName here is a bit hacky and we should expose first-class support for creating JDBC containers from a custom image

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bsideup the Container is created according to the property DockerImageName. The property as a public setter isn't that an API ;-)

* @param type driver type of the alias specified e.g. "mysql", "sqlserver", ...
* @param image string that represents the docker image e.g. "mysql", "customregistry/image name"
*/
public static void registerAlias(String alias, String type, String image) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we discourage the use of :latest, we should not provide any tag-less API

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bsideup
this will not fallback to latest but to the tag, that was specified by the module maintainer in the underlying specific container class.
The usecase here is when you host your own proxy registry, but want to use the tag, that was specified already. Somewhat related to feture request in #2100 at least for the db containers

@bsideup bsideup left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation looks a bit over-engineered.
Also, it feels that a new API is required.

@SaschaJohn you can proceed if you feel confident, otherwise we can pick up your progress :)

@SaschaJohn

SaschaJohn commented Jan 31, 2020

Copy link
Copy Markdown
Author

@binkley, without specifying image tag the tag from the original implementing class is used,
for your example default the version, from the Postgres Container class.
With image tag, the code will use your explicit tag configuration. But you're right. Both examples in the doc are the same. I'll fix that

@stale

stale Bot commented Apr 30, 2020

Copy link
Copy Markdown

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe this is a mistake, please reply to this comment to keep it open. If there isn't one already, a PR to fix or at least reproduce the problem in a test case will always help us get back on track to tackle this.

@stale stale Bot added the stale label Apr 30, 2020
@rnorth

rnorth commented May 1, 2020

Copy link
Copy Markdown
Member

@bsideup I know you were grappling with a more difficult version of this problem for r2dbc support. Would you like to take over / replace this PR?

@stale stale Bot removed the stale label May 1, 2020
@stale

stale Bot commented Aug 1, 2020

Copy link
Copy Markdown

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe this is a mistake, please reply to this comment to keep it open. If there isn't one already, a PR to fix or at least reproduce the problem in a test case will always help us get back on track to tackle this.

@stale stale Bot added the stale label Aug 1, 2020
@stale

stale Bot commented Aug 15, 2020

Copy link
Copy Markdown

This issue has been automatically closed due to inactivity. We apologise if this is still an active problem for you, and would ask you to re-open the issue if this is the case.

@stale stale Bot closed this Aug 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants