Skip to content

[Not ready to merge yet] Support datasource password change in runtime #1599

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

Open
wants to merge 15 commits into
base: 6.2.x
Choose a base branch
from

Conversation

radovanradic
Copy link
Contributor

This PR adds support for changing datasource password without need to restart the app. It might address some reported issues like this one.
The idea is that users publish event with datasource name and changed password so listeners would be able to update datasource passwords. Current connections created with old password are validated (tested with hikari and ucp) and only when connection expires and being recreated then new password will be used.
@sdelamo Suggested using bean refresh, but don't know how it would work - tried refreshing DataSourceConfiguration but that didn't have effect since DataSource beans are already created and injected with the old password and refreshing DataSourceConfiguration won't rebuild existing datasources. Or maybe I was not aware how it could be done.

@@ -22,5 +22,6 @@
@MicronautTest(transactional = false)
@Property(name = "jpa.default.properties.hibernate.connection.db-type", value = "mysql")
@Property(name = "jpa.default.reactive", value = "true")
@Property(name = "test-resources.containers.mysql.image-name", value = "mysql:8.4.5")
Copy link
Contributor Author

@radovanradic radovanradic May 8, 2025

Choose a reason for hiding this comment

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

Unrelated to this PR, mysql:latest docker image was failing to start in tests so needed to update it to 8.x

}
return dbcpDataSourcePoolMetadata;
}

@Override
public void onApplicationEvent(DataSourcePasswordChangedEvent event) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think instead of a new event you should extend RefreshEventListener and override getObservedConfigurationPrefixes() to get the data which will make it work in other contexts like the refresh endpoint and periodic monitoring.

For UCP you should call:

public void reconfigureDataSource(Properties configuration) throws SQLException {

For Hikari you should call:

hikariDataSource.getHikariConfigMXBean().setPassword("newPassword");
hikariDataSource.getHikariPoolMXBean().softEvictConnections();

For DBCP:

// set the properties
// and then call
pool.evict();

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wasn't sure if I am able to populate all Properties for UCP or can only set password to properties?
Btw, I think this is not needed, since existing connections will have old password and it should work until connections are evicted by the pool and then regenerated with the new password.

As for the event, I thought this will be more convenient because users might have their own logic/events for password change and this might be simpler and more straightforward.

Copy link
Contributor

Choose a reason for hiding this comment

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

it isn't about being easier it is because this change won't work from the refresh management endpoint or wither periodic config refresh mechanisms

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I guess will wait this PR micronaut-projects/micronaut-core#11798 to be merged and then for which drivers needed listen to refresh event and I suppose datasources.*.password and extract datasource name and update password if needed.

@dstepanov
Copy link
Contributor

dstepanov commented May 9, 2025

Can we test this with two datasource and validate that rerouting works?
Nevermind, I see we only support password change

@radovanradic
Copy link
Contributor Author

radovanradic commented May 9, 2025

Can we test this with two datasource and validate that rerouting works? Nevermind, I see we only support password change

I have updates tests for DBCP, Hikari and Tomcat by altering default user in the test and then executing query. Something is not working as expected for UCP, investigating now.

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
59.1% Coverage on New Code (required ≥ 70%)

See analysis details on SonarQube Cloud

@radovanradic radovanradic added the type: improvement A minor improvement to an existing feature label May 13, 2025
@radovanradic
Copy link
Contributor Author

Need to wait this PR micronaut-projects/micronaut-core#11798 and micronaut-core version with it be propagated before can merge this

@radovanradic radovanradic changed the title Support datasource password change in runtime [Not ready to merge yet] Support datasource password change in runtime May 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: improvement A minor improvement to an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants