Skip to content

Commit f4b6274

Browse files
committed
Default to TlsChannelStreamFactoryFactory in async
when running on Java 8+ and SSL is enabled JAVA-3038
1 parent 9ddafeb commit f4b6274

File tree

2 files changed

+95
-24
lines changed

2 files changed

+95
-24
lines changed

driver-async/src/main/com/mongodb/async/client/MongoClients.java

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
package com.mongodb.async.client;
1818

1919
import com.mongodb.ConnectionString;
20+
import com.mongodb.MongoClientException;
2021
import com.mongodb.MongoDriverInformation;
21-
import com.mongodb.connection.AsynchronousSocketChannelStreamFactory;
22+
import com.mongodb.MongoInternalException;
23+
import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory;
2224
import com.mongodb.connection.Cluster;
2325
import com.mongodb.connection.DefaultClusterFactory;
24-
import com.mongodb.connection.SocketSettings;
2526
import com.mongodb.connection.StreamFactory;
2627
import com.mongodb.connection.StreamFactoryFactory;
28+
import com.mongodb.connection.TlsChannelStreamFactoryFactory;
2729
import com.mongodb.lang.Nullable;
2830
import org.bson.codecs.configuration.CodecRegistry;
2931

@@ -38,7 +40,6 @@
3840
* @since 3.0
3941
* @deprecated Prefer the Reactive Streams-based asynchronous driver (mongodb-driver-reactivestreams artifactId)
4042
*/
41-
@SuppressWarnings("deprecation")
4243
@Deprecated
4344
public final class MongoClients {
4445

@@ -129,7 +130,6 @@ public static MongoClient create(final MongoClientSettings settings, @Nullable f
129130
* @throws IllegalArgumentException if the connection string's stream type is not one of "netty" or "nio2"
130131
* @see MongoClients#create(ConnectionString)
131132
*/
132-
@SuppressWarnings("deprecation")
133133
public static MongoClient create(final ConnectionString connectionString,
134134
@Nullable final MongoDriverInformation mongoDriverInformation) {
135135

@@ -158,34 +158,40 @@ public static MongoClient create(final com.mongodb.MongoClientSettings settings)
158158
* @return the client
159159
* @since 3.7
160160
*/
161-
@SuppressWarnings("deprecation")
162161
public static MongoClient create(final com.mongodb.MongoClientSettings settings,
163162
@Nullable final MongoDriverInformation mongoDriverInformation) {
164163
return create(MongoClientSettings.createFromClientSettings(settings), mongoDriverInformation, null);
165164
}
166165

167-
@SuppressWarnings("deprecation")
168166
private static MongoClient create(final MongoClientSettings settings,
169167
@Nullable final MongoDriverInformation mongoDriverInformation,
170168
@Nullable final String requestedStreamType) {
171169
String streamType = getStreamType(requestedStreamType);
172-
if (isNetty(streamType) && settings.getStreamFactoryFactory() == null) {
173-
return NettyMongoClients.create(settings, mongoDriverInformation);
170+
if (settings.getStreamFactoryFactory() == null) {
171+
if (isNetty(streamType)) {
172+
return NettyMongoClients.create(settings, mongoDriverInformation);
173+
} else if (isNio(streamType)) {
174+
if (settings.getSslSettings().isEnabled()) {
175+
return createWithTlsChannel(settings, mongoDriverInformation);
176+
} else {
177+
return createWithAsynchronousSocketChannel(settings, mongoDriverInformation);
178+
}
179+
} else {
180+
throw new IllegalArgumentException("Unsupported stream type: " + streamType);
181+
}
174182
} else {
175-
return new MongoClientImpl(settings, createCluster(settings, mongoDriverInformation,
176-
getStreamFactory(settings, streamType, false), getStreamFactory(settings, streamType, true)), (Closeable) null);
183+
return createMongoClient(settings, mongoDriverInformation, getStreamFactory(settings, false),
184+
getStreamFactory(settings, true), null);
177185
}
178186
}
179187

180-
@SuppressWarnings("deprecation")
181188
static MongoClient createMongoClient(final MongoClientSettings settings, @Nullable final MongoDriverInformation mongoDriverInformation,
182189
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory,
183190
@Nullable final Closeable externalResourceCloser) {
184191
return new MongoClientImpl(settings, createCluster(settings, mongoDriverInformation, streamFactory, heartbeatStreamFactory),
185192
externalResourceCloser);
186193
}
187194

188-
@SuppressWarnings("deprecation")
189195
private static Cluster createCluster(final MongoClientSettings settings, @Nullable final MongoDriverInformation mongoDriverInformation,
190196
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory) {
191197
notNull("settings", settings);
@@ -218,25 +224,57 @@ public static CodecRegistry getDefaultCodecRegistry() {
218224
return com.mongodb.MongoClientSettings.getDefaultCodecRegistry();
219225
}
220226

221-
@SuppressWarnings("deprecation")
222-
private static StreamFactory getStreamFactory(final MongoClientSettings settings, final String streamType,
223-
final boolean isHeartbeat) {
227+
228+
private static MongoClient createWithTlsChannel(final MongoClientSettings settings,
229+
@Nullable final MongoDriverInformation mongoDriverInformation) {
230+
if (!isJava8()) {
231+
throw new MongoClientException("TLS is only supported natively with Java 8 and above. Please use Netty instead");
232+
}
233+
final TlsChannelStreamFactoryFactory streamFactoryFactory = new TlsChannelStreamFactoryFactory();
234+
StreamFactory streamFactory = streamFactoryFactory.create(settings.getSocketSettings(), settings.getSslSettings());
235+
StreamFactory heartbeatStreamFactory = streamFactoryFactory.create(settings.getHeartbeatSocketSettings(),
236+
settings.getSslSettings());
237+
return createMongoClient(settings, mongoDriverInformation, streamFactory, heartbeatStreamFactory,
238+
new Closeable() {
239+
@Override
240+
public void close() {
241+
streamFactoryFactory.close();
242+
}
243+
});
244+
}
245+
246+
private static boolean isJava8() {
247+
try {
248+
Class.forName("java.time.Instant");
249+
return true;
250+
} catch (ClassNotFoundException e) {
251+
return false;
252+
}
253+
}
254+
255+
private static MongoClient createWithAsynchronousSocketChannel(final MongoClientSettings settings,
256+
@Nullable final MongoDriverInformation mongoDriverInformation) {
257+
StreamFactoryFactory streamFactoryFactory = new AsynchronousSocketChannelStreamFactoryFactory();
258+
StreamFactory streamFactory = streamFactoryFactory.create(settings.getSocketSettings(), settings.getSslSettings());
259+
StreamFactory heartbeatStreamFactory = streamFactoryFactory.create(settings.getHeartbeatSocketSettings(),
260+
settings.getSslSettings());
261+
return createMongoClient(settings, mongoDriverInformation, streamFactory, heartbeatStreamFactory, null);
262+
}
263+
264+
private static StreamFactory getStreamFactory(final MongoClientSettings settings, final boolean isHeartbeat) {
224265
StreamFactoryFactory streamFactoryFactory = settings.getStreamFactoryFactory();
225-
SocketSettings socketSettings = isHeartbeat ? settings.getHeartbeatSocketSettings() : settings.getSocketSettings();
226-
if (streamFactoryFactory != null) {
227-
return streamFactoryFactory.create(socketSettings, settings.getSslSettings());
228-
} else if (isNio2(streamType)) {
229-
return new AsynchronousSocketChannelStreamFactory(socketSettings, settings.getSslSettings());
230-
} else {
231-
throw new IllegalArgumentException("Unsupported stream type: " + streamType);
266+
if (streamFactoryFactory == null) {
267+
throw new MongoInternalException("should not happen");
232268
}
269+
return streamFactoryFactory.create(isHeartbeat ? settings.getHeartbeatSocketSettings() : settings.getSocketSettings(),
270+
settings.getSslSettings());
233271
}
234272

235273
private static boolean isNetty(final String streamType) {
236274
return streamType.toLowerCase().equals("netty");
237275
}
238276

239-
private static boolean isNio2(final String streamType) {
277+
private static boolean isNio(final String streamType) {
240278
return streamType.toLowerCase().equals("nio2");
241279
}
242280

driver-async/src/test/functional/com/mongodb/async/client/MongoClientsSpecification.groovy

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@ package com.mongodb.async.client
1818

1919
import com.mongodb.MongoCompressor
2020
import com.mongodb.MongoCredential
21+
import com.mongodb.MongoDriverInformation
2122
import com.mongodb.ReadConcern
2223
import com.mongodb.ServerAddress
2324
import com.mongodb.WriteConcern
24-
import com.mongodb.MongoDriverInformation
25+
import com.mongodb.async.FutureResultCallback
2526
import org.bson.Document
2627
import spock.lang.IgnoreIf
2728
import spock.lang.Unroll
2829

30+
import static com.mongodb.ClusterFixture.connectionString
31+
import static com.mongodb.ClusterFixture.getCredentialList
32+
import static com.mongodb.ClusterFixture.getSslSettings
33+
import static com.mongodb.ClusterFixture.isNotAtLeastJava8
2934
import static com.mongodb.ClusterFixture.isStandalone
3035
import static com.mongodb.ClusterFixture.serverVersionAtLeast
3136
import static com.mongodb.ReadPreference.primary
@@ -36,6 +41,34 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS
3641

3742
class MongoClientsSpecification extends FunctionalSpecification {
3843

44+
@IgnoreIf({ isNotAtLeastJava8() })
45+
def 'should connect'() {
46+
given:
47+
def connectionString = 'mongodb://'
48+
if (!getCredentialList().isEmpty()) {
49+
connectionString += (getCredentialList()[0].getUserName() + ':' + String.valueOf(getCredentialList()[0].getPassword()) + '@')
50+
}
51+
connectionString += getConnectionString().getHosts()[0] + '/?'
52+
connectionString += 'ssl=' + getSslSettings().isEnabled() + '&'
53+
connectionString += 'sslInvalidHostNameAllowed=' + getSslSettings().isInvalidHostNameAllowed() + '&'
54+
connectionString += 'streamType=' + streamType
55+
56+
when:
57+
def client = MongoClients.create(connectionString)
58+
def callback = new FutureResultCallback()
59+
client.getDatabase('admin').runCommand(new Document('ping', 1), callback)
60+
callback.get()
61+
62+
then:
63+
noExceptionThrown()
64+
65+
cleanup:
66+
client?.close()
67+
68+
where:
69+
streamType << ['netty', 'nio2']
70+
}
71+
3972
def 'should apply connection string to cluster settings'() {
4073
when:
4174
def client = MongoClients.create('mongodb://localhost,localhost:27018/')

0 commit comments

Comments
 (0)