11

I am migrating an application from using MongoDB Java driver v. 3.6.4 to v. 4.1.1

In 3.6.4 configuration is passed via MongoClientOptions

@Bean
 public MongoClientOptions mongoOptions() {
 return MongoClientOptions.builder()
 .connectTimeout(...)
 .serverSelectionTimeout(..)
 .socketTimeout(...)
 .build();
 } 

In 4.1.1 MongoClientOptions has been deprecated, and I am utilizing MongoClientSettings class http://mongodb.github.io/mongo-java-driver/4.1/apidocs/mongodb-driver-core/com/mongodb/MongoClientSettings.Builder.html

 @Bean
 public MongoClientSettings mongoOptions() {
 return MongoClientSettings.builder()
 .applyToSocketSettings(builder ->
 builder.applySettings(builder()
 .connectTimeout(config.getConnectTimeout(), MILLISECONDS).build()))
 .applyToClusterSettings(builder ->
 builder.serverSelectionTimeout(config.getServerSelectionTimeout(), MILLISECONDS).build())
 .build();
 }

However I can't find setting to configure connectTimeout (apart from supplying connection string via applyConnectionString method.

asked Dec 7, 2020 at 21:08
2

2 Answers 2

9

Yeah, took me a while to figure this out.

The connection timeout and socket timeout are now both in SocketSettings (with the latter renamed as readTimeout).

So it would look something like the following (where you can replace the 1's with your inputs):

 @Bean
 public MongoClientSettings mongoSetting() {
 return MongoClientSettings.builder()
 .applyToSocketSettings(builder -> {
 builder.connectTimeout(1, MILLISECONDS);
 builder.readTimeout(1, MILLISECONDS);
 })
 .applyToClusterSettings( builder -> builder.serverSelectionTimeout(1, MILLISECONDS))
 .applyConnectionString(new ConnectionString("<your-connection-string>"))
 .build();
 }

I found the need to set the connection string here (in addition to having it set via spring.data.mongodb.uri). Go figure.

answered Feb 26, 2021 at 5:24
Sign up to request clarification or add additional context in comments.

Comments

1

In the example below I have set the mongoClient with SSLContext using JKS Keystore connecting to a Cluster with three nodes:

@Configuration
@Slf4j
@Profile("qa")
public class MongoDBConfigurationQA extends AbstractMongoClientConfiguration {
@Value("${spring.data.mongodb.database}")
String database;
@Value("${spring.data.mongodb.user}")
String user;
@Value("${spring.data.mongodb.keystore}")
String keystore;
@Value("${spring.data.mongodb.truststore}")
String truststore;
@Value("${spring.data.mongodb.keystorePwd}")
String keystorePwd;
@Value("${spring.data.mongodb.truststorePwd}")
String truststorePwd;
@Value("${spring.data.mongodb.hosts}")
String hosts;
@Value("${spring.data.mongodb.port}")
Integer port;
@Override
protected String getDatabaseName() {
 return database;
}
@Override
public MongoClient mongoClient() {
 List<ServerAddress> listServerAddress = getServerAddresses();
 MongoCredential mongoCredential = MongoCredential.createMongoX509Credential(user);
 SSLContext sslContext = getSSLContext();
 MongoClientSettings settings = MongoClientSettings.builder()
 .retryWrites(true)
 .retryReads(true)
 .applyToConnectionPoolSettings((ConnectionPoolSettings.Builder builder) -> {
 builder.maxSize(300) //connections count
 .minSize(1)
 .maxConnectionLifeTime(0, TimeUnit.MILLISECONDS)
 .maxConnectionIdleTime(0, TimeUnit.MILLISECONDS)
 .maxWaitTime(180000, TimeUnit.MILLISECONDS);
 })
 .applyToSocketSettings(builder -> {
 builder.readTimeout(30000, TimeUnit.MILLISECONDS)
 .connectTimeout(30000, TimeUnit.MILLISECONDS);
 })
 .applyToSslSettings(builder -> {
 builder.enabled(true)
 .invalidHostNameAllowed(true)
 .context(sslContext);
 SslSettings.builder().enabled(true);
 })
 .applyToClusterSettings(builder -> builder.hosts(listServerAddress))
 .credential(mongoCredential)
 .build();
 return MongoClients.create(settings);
}
private List<ServerAddress> getServerAddresses() {
 List<ServerAddress> listServerAddress = new ArrayList<>();
 String[] parts = hosts.split(";");
 int i;
 for (i = 0; i < parts.length; i++){
 listServerAddress.add(new ServerAddress(parts[i], port));
 }
 return listServerAddress;
}
private SSLContext getSSLContext() {
 SSLContext sslContext = null;
 try (FileInputStream fis = new FileInputStream(truststore)) {
 KeyStore trustStore = KeyStore.getInstance("JKS");
 trustStore.load(fis, truststorePwd.toCharArray());
 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
 trustManagerFactory.init(trustStore);
 FileInputStream fKS = new FileInputStream(keystore);
 KeyStore keyStore = KeyStore.getInstance("JKS");
 keyStore.load(fKS, keystorePwd.toCharArray());
 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
 keyManagerFactory.init(keyStore, keystorePwd.toCharArray());
 sslContext = SSLContext.getInstance("SSL");
 sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
 } catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException | KeyManagementException e) {
 log.error(e.toString(), e);
 } catch (UnrecoverableKeyException e) {
 log.error(e.toString(), e);
 }
 return sslContext;
}

}

answered Jun 8, 2022 at 11:21

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.