Reputation: 5232
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.
Upvotes: 11
Views: 9637
Reputation: 4209
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;
}
}
Upvotes: 1
Reputation: 4578
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.
Upvotes: 9