0

The ask is to modify the password of a mongodb connection at runtime in a spring boot project. For example let's assume a mongodb connection is established while starting the application with password 'xyz'.I would like to modify the password at runtime by lets say hitting an api. I have tried following solutions so far to tackle this issue:

  • Replacing mongoTemplate bean at runtime: Tried creating a new mongoTemplate Bean with new password at runtime and replaced it in the context using the methods given in following link. The issue with this approach is that the bean is getting refreshed only once. Ideally it should work everytime when the api to update password is being called.
  • Updating password in mongoCredentials: One of the obvious approach is to update the password directly in mongoCredentials since mongoTemplate uses mongoCredential class to store the credentials information.But the issue is that the password field in MongoCredentials class is 'final static' so we cannot update it even with reflections. Even though there are some tricks to update the final static fields but i'm looking for a more acceptable solution.

1 Answers1

0

There is @RefreshScope in Spring Cloud project exactly for your purpose. Here is Spring's documentation about how it works: https://cloud.spring.io/spring-cloud-static/spring-cloud.html#_refresh_scope.

So all you need to do is update Environment and call org.springframework.cloud.context.scope.refresh.RefreshScope#refresh or org.springframework.cloud.context.scope.refresh.RefreshScope#refreshAll when you need to refresh your context.

geobreze
  • 2,274
  • 1
  • 10
  • 15
  • This is a great solution. But in my specific case i'm generating the mongoTemplate bean at runtime through BeanDefinitionRegistry, so i cannot add the @RefreshScope annotation directly. Is there a way to annotate the dynamic bean with 'RefreshScope' annotation? – Vinay Singh Jun 01 '21 at 19:58
  • You should set the scope value to `refresh` for your bean definition – geobreze Jun 01 '21 at 21:44
  • I was able to create beans with "refresh" scope. Just one issue, In the case of @RefreshScope,@Bean annotated methods after calling refresh(beanName) method, new bean will be created and registered in context with updated configurations. But in my case as i said earlier i'm generating beans dynamically through beanRegistry. After calling refresh(beanName) method, new bean is not getting generated, i.e flow is not coming to postProcessBeanDefinitionRegistry. Any ideas? – Vinay Singh Jun 02 '21 at 17:44
  • `@RefreshScope` is managed by `org.springframework.cloud.context.scope.refresh.RefreshScope` which is also `BeanDefinitionRegistryPostProcessor` with order `Ordered.LOWEST_PRECEDENCE - 100`. Try making your post processor running before this one. Now I'm just guessing, but this may work – geobreze Jun 02 '21 at 20:26