Closed heyarny closed 4 years ago
Thanks for the report.
Right now I'm kinda forced to create my own MongoClient bean to inject custom settings which will break all auto configuration.
You should be able to create your own MongoClientSettings
bean. It will be consumed by MongoAutoConfiguration
and used to create the auto-configured MongoClient
. The only benefit of the builder customizer approach over this is that it allows customisations from multiple sources to be applied. That's useful on the reactive side where we have some Netty customizations to apply. There are no such customizations on the blocking side so the builder customizer isn't strictly necessary.
With that said, I can see how the current arrangement is confusing as there's nothing to indicate that the builder customizer only applies to the reactive driver. When the feature was first introduced in Spring Boot 2.0, the type that was customized, com.mongodb.async.client.MongoClientSettings.Builder
, was specific to Mongo's reactive driver. This changed to com.mongodb.MongoClientSettings.Builder
in Spring Boot 2.1 but we didn't take the opportunity to make the customization available with the blocking driver as well.
Even just in the interests of consistency, it is tempting to support the builder customizer with the blocking driver. Failing that, we should at least update its javadoc to make it clear that it's specific to the reactive driver.
@mp911de if you have an opinion here one way or the other, please let us know.
@wilkinsona well, I'd expect auto configuration to make its best choices for the settings and give me the opportunity to make additional modifications.
Serving a closed MongoClientSettings
would probably mean I'd have to take care over the 'best choises' part, which I'd rather love to hand over to spring boot.
Edit: oh, and of course I'd have to take care of all the properties set via application as well.
There's no MongoClientSettings
bean by default so providing one won't result in you losing anything. If you provide one, a Builder
is created from those settings, otherwise a plain Builder
is created. Either way Spring Boot's configuration and properties are applied to the Builder
before it's used to create the client.
Put another way, you only need to provide a MongoClient
bean if you want to take complete control of the client's configuration. Creating a MongoClientSettings
bean will allow you to fine-tune Boot's opinions.
If you'd like to see how this is implemented, please take a look at the source for MongoClientFactory
which is used by MongoAutoConfiguration
to create the MongoClient
bean.
@wilkinsona Ok, sounds fine to me. I'll give it a try then.
Thanks! Have a great weekend :)
@wilkinsona are you sure this bean is used by non-reactive configuration as well?
It doesn't seem to work and I can't find any indication within the spring boot source which shows me the MongoClientSettings
bean usage for non-reative auto configuration.
Ok, I found the problem and it is totally confusing, again.
It's MongoClientOptions
which is being used as bean, not MongoClientSettings
.
MongoClientOptions is deprecated and should be replaced by MongoClientSettings
or at least check for both and fallback to MongoClientOptions
.
Hope this helps to fix this.
@wilkinsona by the way. I just saw that part with 'best choises' coming across. The default MongoClientSettings/MongoClientOptions is prefilled with codecs which I'd like to extend instead of replacing them. So I don't really see a way to get and extend them. So this is exactly why getting access to the builder would solve this.
Thanks for your time.
Sorry for the confusion. We’ve switched to MongoClientSettings
in 2.3. It is, as you have noted, MongoClientOptions
in earlier versions.
The issue is rooted in the fact that MongoDB ships two drivers, the synchronous and the async/reactive one. Both had in version 3.x/1.x different approaches to configuration using different API.
With the MongoDB 4.x driver, the configuration was fully unified into MongoClientSettings
. MongoDB Driver 3.7/Reactive MongoDB Driver 1.8 introduced already support for MongoClientSettings
but back then, we were past the 2.0 release and didn't consider breaking existing code a good idea, especially that MongoClientOptions
still existed. Such a change would silently not apply configuration which would be even more harmful.
@mp911de Yes, I understand. Still would be nice to have access to the builder in future releases for both reactive/async and sync. As of now I'll have to find another way on how to extend the default settings.
We have an issue for 2.3.0 (#20019) to bring the auto-configuration for the reactive/async and sync MongoDB into closer alignment, and to reduce the code duplication there, now that the MongoDB drivers provide similar configuration.
Superseded by #19960 and #20019 for Spring Boot 2.3.0.
Hi @wilkinsona ,
I find the question raised in this issue very pertinent. As this issue is resolved, the reference documentation could be updated to indicate how one can customize options while retaining the auto configuration behaviour. As the getting started guide focuses on the data persistence aspects, the section 4.12.2 of the reference guide seems to the correct location for these details.
After searching various javadocs, such customization seems to be possible as per below:
@Configuration
public class MongodbConfig {
@Bean
public MongoClientSettingsBuilderCustomizer mongoDBDefaultSettings() {
return builder -> {
builder.applyToSslSettings( blockBuilder -> {
blockBuilder.enabled(true).invalidHostNameAllowed(true);
});
};
}
}
@adelinor Thanks for the suggestion. I've opened https://github.com/spring-projects/spring-boot/issues/21696.
@wilkinsona would it be possible to also update https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes#mongodb-client-customization ?
@agarcia-te What sort of update do you have in mind? Unlike the reference documentation prior to #21696 being fixed, the release notes already mention the settings builder customizer.
@wilkinsona It doesn't warn that it only applies for reactive though, it makes it sound like that's the recommended way to do it in general.
Second @agarcia-te here. I have also been bitten by the same issue and wasted hours debugging it.
I've made some updates to the release notes. It's worth noting, though, that all currently supported versions of Spring Boot (2.3.x and later) apply settings builder customizers with both the reactive and imperative drivers (https://github.com/spring-projects/spring-boot/issues/20019). If you're being bitten by this now then I suspect you're using an unsupported version and would recommend upgrading at your earliest convenience.
Thanks @wilkinsona. Appreciate the update!
First off, I'm not using reactive driver. There are examples using a
MongoClientSettingsBuilderCustomizer
bean to access the settings builder for modifications. But they don't seem to work with synchronous drivers, which is very confusing, even though they share the same settings.Right now I'm kinda forced to create my own MongoClient bean to inject custom settings which will break all auto configuration.
I'm trying to register default codec for pojos, because I need them for some special cases.
Would appreciate any workaround for this, if this is not supported yet.