micronaut-sql icon indicating copy to clipboard operation
micronaut-sql copied to clipboard

Expose Hikari DataSources in Beans to support password rotation

Open napsta32 opened this issue 6 months ago • 1 comments

Feature description

Problem

Currently the DataSource's are encapsulated inside the DatasourceFactory class (see https://github.com/micronaut-projects/micronaut-sql/blob/5.7.x/jdbc-hikari/src/main/java/io/micronaut/configuration/jdbc/hikari/DatasourceFactory.java). This makes it impossible to access the datasource without reflection.

I would like to access the DataSource instances to rotate passwords without affecting the service availability.

Feature idea

Ideally I would like to simply get the "DataSource" and change things directly in there:

// I would use either DataSource.class or HikariDataSource.class
HikariDataSource dataSource = applicationContext.getBean(DataSource.class, Qualifiers.ofName("datasourceName"));
dataSource.setPassword(newPassword);
dataSource.getHikariPoolMXBean().softEvictConnections(); // Refresh connections

Workaround (using reflection)

As an alternative I am working with the following workaround (using reflection):

    private void updateDataSourcePassword() throws NoSuchFieldException, IllegalAccessException {
        DatasourceFactory datasourceFactory = applicationContext.getBean(DatasourceFactory.class);
        Field dataSourcesField = DatasourceFactory.class.getDeclaredField("dataSources");
        dataSourcesField.setAccessible(true);

        List<HikariDataSource> dataSources = (List<HikariDataSource>) dataSourcesField.get(datasourceFactory);
        for (HikariDataSource dataSource : dataSources) {
            dataSource.setPassword(newPassword);
            dataSource.getHikariPoolMXBean().softEvictConnections(); // Refresh connections
        }
    }

Please let me know if there is a better workaround.

How does Spring work (probably the best solution)

This is something kindof supported by Spring:

  • https://blog.jdriven.com/2021/06/configure-hikari-connection-pool-when-using-rds-iam/
  • https://stackoverflow.com/questions/73793784/how-to-ensure-hikari-connections-are-spawn-with-latest-credentials

Basically you can override the HikariUrlDataSource class with any custom classname using the application.properties. This is something that is not supported either by Micronaut. It is quite a clean solution with the disadvantage that getPassword is called for each connection. It could be worked around using a memory cache or lazy variables.

napsta32 avatar Aug 12 '24 02:08 napsta32