Commit b7f60c2d authored by Stephane Nicoll's avatar Stephane Nicoll

Configure NettyStreamFactoryFactory by default if available

Closes gh-11526
Closes gh-10961
parent 2b38ee9d
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.nio.channels.SocketChannel;
import java.util.List; import java.util.List;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import com.mongodb.async.client.MongoClientSettings; import com.mongodb.async.client.MongoClientSettings;
import com.mongodb.connection.netty.NettyStreamFactoryFactory;
import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClient;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
...@@ -30,6 +32,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean ...@@ -30,6 +32,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
/** /**
...@@ -46,16 +50,10 @@ public class MongoReactiveAutoConfiguration { ...@@ -46,16 +50,10 @@ public class MongoReactiveAutoConfiguration {
private final MongoClientSettings settings; private final MongoClientSettings settings;
private final ReactiveMongoClientFactory factory;
private MongoClient mongo; private MongoClient mongo;
public MongoReactiveAutoConfiguration(MongoProperties properties, public MongoReactiveAutoConfiguration(ObjectProvider<MongoClientSettings> settings) {
ObjectProvider<MongoClientSettings> settings, Environment environment,
ObjectProvider<List<MongoClientSettingsBuilderCustomizer>> builderCustomizers) {
this.settings = settings.getIfAvailable(); this.settings = settings.getIfAvailable();
this.factory = new ReactiveMongoClientFactory(properties, environment,
builderCustomizers.getIfAvailable());
} }
@PreDestroy @PreDestroy
...@@ -67,9 +65,35 @@ public class MongoReactiveAutoConfiguration { ...@@ -67,9 +65,35 @@ public class MongoReactiveAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public MongoClient reactiveStreamsMongoClient() { public MongoClient reactiveStreamsMongoClient(MongoProperties properties,
this.mongo = this.factory.createMongoClient(this.settings); Environment environment,
ObjectProvider<List<MongoClientSettingsBuilderCustomizer>> builderCustomizers) {
ReactiveMongoClientFactory factory = new ReactiveMongoClientFactory(properties,
environment, builderCustomizers.getIfAvailable());
this.mongo = factory.createMongoClient(this.settings);
return this.mongo; return this.mongo;
} }
@Configuration
@ConditionalOnClass(SocketChannel.class)
static class NettyDriverConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public MongoClientSettingsBuilderCustomizer nettyDriverCustomizer(
ObjectProvider<MongoClientSettings> settings) {
return (builder) -> {
if (!isStreamFactoryFactoryDefined(settings.getIfAvailable())) {
builder.streamFactoryFactory(
NettyStreamFactoryFactory.builder().build());
}
};
}
private boolean isStreamFactoryFactoryDefined(MongoClientSettings settings) {
return settings != null && settings.getStreamFactoryFactory() != null;
}
}
} }
/* /*
* Copyright 2012-2017 the original author or authors. * Copyright 2012-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -20,9 +20,11 @@ import java.util.concurrent.TimeUnit; ...@@ -20,9 +20,11 @@ import java.util.concurrent.TimeUnit;
import com.mongodb.ReadPreference; import com.mongodb.ReadPreference;
import com.mongodb.async.client.MongoClientSettings; import com.mongodb.async.client.MongoClientSettings;
import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory;
import com.mongodb.connection.SocketSettings; import com.mongodb.connection.SocketSettings;
import com.mongodb.connection.StreamFactory; import com.mongodb.connection.StreamFactory;
import com.mongodb.connection.StreamFactoryFactory; import com.mongodb.connection.StreamFactoryFactory;
import com.mongodb.connection.netty.NettyStreamFactoryFactory;
import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClient;
import org.junit.Test; import org.junit.Test;
...@@ -86,6 +88,16 @@ public class MongoReactiveAutoConfigurationTests { ...@@ -86,6 +88,16 @@ public class MongoReactiveAutoConfigurationTests {
}); });
} }
@Test
public void nettyStreamFactoryFactoryIsConfiguredAutomatically() {
this.contextRunner.run((context) -> {
assertThat(context).hasSingleBean(MongoClient.class);
assertThat(context.getBean(MongoClient.class).getSettings()
.getStreamFactoryFactory())
.isInstanceOf(NettyStreamFactoryFactory.class);
});
}
@Test @Test
public void customizerOverridesAutoConfig() { public void customizerOverridesAutoConfig() {
this.contextRunner this.contextRunner
...@@ -95,6 +107,8 @@ public class MongoReactiveAutoConfigurationTests { ...@@ -95,6 +107,8 @@ public class MongoReactiveAutoConfigurationTests {
MongoClient client = context.getBean(MongoClient.class); MongoClient client = context.getBean(MongoClient.class);
assertThat(client.getSettings().getApplicationName()) assertThat(client.getSettings().getApplicationName())
.isEqualTo("overridden-name"); .isEqualTo("overridden-name");
assertThat(client.getSettings().getStreamFactoryFactory())
.isEqualTo(SimpleCustomizerConfig.streamFactoryFactory);
}); });
} }
...@@ -133,10 +147,14 @@ public class MongoReactiveAutoConfigurationTests { ...@@ -133,10 +147,14 @@ public class MongoReactiveAutoConfigurationTests {
@Configuration @Configuration
static class SimpleCustomizerConfig { static class SimpleCustomizerConfig {
private static final StreamFactoryFactory streamFactoryFactory =
new AsynchronousSocketChannelStreamFactoryFactory();
@Bean @Bean
public MongoClientSettingsBuilderCustomizer customizer() { public MongoClientSettingsBuilderCustomizer customizer() {
return (clientSettingsBuilder) -> clientSettingsBuilder return (clientSettingsBuilder) -> clientSettingsBuilder
.applicationName("overridden-name"); .applicationName("overridden-name")
.streamFactoryFactory(streamFactoryFactory);
} }
} }
......
...@@ -3660,7 +3660,9 @@ instead of using `MongoDbFactory`. If you want to take complete control of estab ...@@ -3660,7 +3660,9 @@ instead of using `MongoDbFactory`. If you want to take complete control of estab
the MongoDB connection, you can also declare your own `MongoDbFactory` or `MongoClient` the MongoDB connection, you can also declare your own `MongoDbFactory` or `MongoClient`
bean. bean.
NOTE: If you are using the reactive driver, Netty is required for SSL. The
auto-configuration configures this factory automatically if Netty is available and the
factory to use hasn't been customized already.
[[boot-features-mongo-template]] [[boot-features-mongo-template]]
==== MongoTemplate ==== MongoTemplate
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment