Configure Spring Boot to connect to MongoDB Atlas with SSL

While playing around with some new frameworks I’ve tried to connect my Spring Boot application to a MongoDB Atlas replicaset.
In order to do so the MongoDB Reactive Streams Java Driver needs to connect using SSL. This didn’t seem to work out of the box as I’ve got the following exception:

1
2
3
4
5
6
7
8
9
10
11
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'reactiveStreamsMongoClient'
defined in class path resource
[org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfiguration.class]:
Bean instantiation via factory method failed;
nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [com.mongodb.reactivestreams.client.MongoClient]:
Factory method 'reactiveStreamsMongoClient' threw exception;
nested exception is java.lang.UnsupportedOperationException:
No SSL support in java.nio.channels.AsynchronousSocketChannel.
For SSL support use com.mongodb.connection.netty.NettyStreamFactoryFactory

According to the documentation the “streamType=netty” option needs to be added to the connection URL. This however dit not make the error go away.
I’ve managed to fix the problem by setting the streamFactoryFactory to Netty using a MongoClientSettingsBuilderCustomizer.

Using Kotlin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@SpringBootApplication
class Application {
val eventLoopGroup = NioEventLoopGroup()
@Bean
fun mongoSettingsNettyConnectionFactoy() = MongoClientSettingsBuilderCustomizer {
it.sslSettings(SslSettings.builder()
.enabled(true)
.invalidHostNameAllowed(true)
.build())
.streamFactoryFactory(NettyStreamFactoryFactory.builder()
.eventLoopGroup(eventLoopGroup).build())
}
@PreDestroy
fun shutDownEventLoopGroup() {
eventLoopGroup.shutdownGracefully()
}
}
fun main(args: Array<String>) {
runApplication<Application>(*args)
}

Using Java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@SpringBootApplication
public class Application {
private NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
public static void main(String[] args) {
SpringApplication.run(SpringReactiveExampleApplication.class, args);
}
@Bean
public MongoClientSettingsBuilderCustomizer sslCustomizer() {
return clientSettingsBuilder -> clientSettingsBuilder
.sslSettings(SslSettings.builder()
.enabled(true)
.invalidHostNameAllowed(true)
.build())
.streamFactoryFactory(NettyStreamFactoryFactory.builder()
.eventLoopGroup(eventLoopGroup).build());
}
@PreDestroy
public void shutDownEventLoopGroup() {
eventLoopGroup.shutdownGracefully();
}
}