diff --git a/build.gradle b/build.gradle index 10add6b07ab..bfe22c87c9b 100644 --- a/build.gradle +++ b/build.gradle @@ -186,7 +186,7 @@ configure(javaMainProjects) { options.encoding = 'ISO-8859-1' options.fork = true options.debug = true - options.compilerArgs = ['-Xlint:all'] + options.compilerArgs = ['-Xlint:all', '-Xlint:-deprecation'] } } diff --git a/driver-core/src/main/com/mongodb/MongoClientSettings.java b/driver-core/src/main/com/mongodb/MongoClientSettings.java index 95bd04296b6..579a030cb75 100644 --- a/driver-core/src/main/com/mongodb/MongoClientSettings.java +++ b/driver-core/src/main/com/mongodb/MongoClientSettings.java @@ -27,6 +27,7 @@ import com.mongodb.connection.SocketSettings; import com.mongodb.connection.SslSettings; import com.mongodb.connection.StreamFactoryFactory; +import com.mongodb.connection.TransportSettings; import com.mongodb.event.CommandListener; import com.mongodb.lang.Nullable; import com.mongodb.spi.dns.DnsClient; @@ -62,6 +63,7 @@ * * @since 3.7 */ +@SuppressWarnings("deprecation") @Immutable public final class MongoClientSettings { private static final CodecRegistry DEFAULT_CODEC_REGISTRY = @@ -89,6 +91,7 @@ public final class MongoClientSettings { private final boolean retryReads; private final ReadConcern readConcern; private final MongoCredential credential; + private final TransportSettings transportSettings; private final StreamFactoryFactory streamFactoryFactory; private final List commandListeners; private final CodecRegistry codecRegistry; @@ -209,6 +212,7 @@ public static final class Builder { private boolean retryReads = true; private ReadConcern readConcern = ReadConcern.DEFAULT; private CodecRegistry codecRegistry = MongoClientSettings.getDefaultCodecRegistry(); + private TransportSettings transportSettings; private StreamFactoryFactory streamFactoryFactory; private List commandListeners = new ArrayList<>(); @@ -252,6 +256,7 @@ private Builder(final MongoClientSettings settings) { serverApi = settings.getServerApi(); dnsClient = settings.getDnsClient(); inetAddressResolver = settings.getInetAddressResolver(); + transportSettings = settings.getTransportSettings(); streamFactoryFactory = settings.getStreamFactoryFactory(); autoEncryptionSettings = settings.getAutoEncryptionSettings(); contextProvider = settings.getContextProvider(); @@ -490,12 +495,30 @@ public Builder codecRegistry(final CodecRegistry codecRegistry) { * @param streamFactoryFactory the stream factory factory * @return this * @see #getStreamFactoryFactory() + * @deprecated Prefer {@link #transportSettings(TransportSettings)} */ + @Deprecated public Builder streamFactoryFactory(final StreamFactoryFactory streamFactoryFactory) { this.streamFactoryFactory = notNull("streamFactoryFactory", streamFactoryFactory); return this; } + /** + * Sets the {@link TransportSettings} to apply. + * + *

+ * If transport settings are applied, application of {@link #streamFactoryFactory} is ignored. + *

+ * + * @param transportSettings the transport settings + * @return this + * @see #getTransportSettings() + */ + public Builder transportSettings(final TransportSettings transportSettings) { + this.transportSettings = notNull("transportSettings", transportSettings); + return this; + } + /** * Adds the given command listener. * @@ -771,12 +794,27 @@ public CodecRegistry getCodecRegistry() { * * @return the stream factory factory * @see Builder#streamFactoryFactory(StreamFactoryFactory) + * @deprecated Prefer {@link #getTransportSettings()} */ + @Deprecated @Nullable public StreamFactoryFactory getStreamFactoryFactory() { return streamFactoryFactory; } + /** + * Gets the settings for the underlying transport implementation + * + * @return the settings for the underlying transport implementation + * + * @since 4.11 + * @see Builder#transportSettings(TransportSettings) + */ + @Nullable + public TransportSettings getTransportSettings() { + return transportSettings; + } + /** * Gets the list of added {@code CommandListener}. * @@ -978,6 +1016,7 @@ public boolean equals(final Object o) { && Objects.equals(writeConcern, that.writeConcern) && Objects.equals(readConcern, that.readConcern) && Objects.equals(credential, that.credential) + && Objects.equals(transportSettings, that.transportSettings) && Objects.equals(streamFactoryFactory, that.streamFactoryFactory) && Objects.equals(commandListeners, that.commandListeners) && Objects.equals(codecRegistry, that.codecRegistry) @@ -1000,11 +1039,11 @@ public boolean equals(final Object o) { @Override public int hashCode() { - return Objects.hash(readPreference, writeConcern, retryWrites, retryReads, readConcern, credential, streamFactoryFactory, - commandListeners, codecRegistry, loggerSettings, clusterSettings, socketSettings, heartbeatSocketSettings, - connectionPoolSettings, serverSettings, sslSettings, applicationName, compressorList, uuidRepresentation, serverApi, - autoEncryptionSettings, heartbeatSocketTimeoutSetExplicitly, heartbeatConnectTimeoutSetExplicitly, dnsClient, - inetAddressResolver, contextProvider); + return Objects.hash(readPreference, writeConcern, retryWrites, retryReads, readConcern, credential, transportSettings, + streamFactoryFactory, commandListeners, codecRegistry, loggerSettings, clusterSettings, socketSettings, + heartbeatSocketSettings, connectionPoolSettings, serverSettings, sslSettings, applicationName, compressorList, + uuidRepresentation, serverApi, autoEncryptionSettings, heartbeatSocketTimeoutSetExplicitly, + heartbeatConnectTimeoutSetExplicitly, dnsClient, inetAddressResolver, contextProvider); } @Override @@ -1016,6 +1055,7 @@ public String toString() { + ", retryReads=" + retryReads + ", readConcern=" + readConcern + ", credential=" + credential + + ", transportSettings=" + transportSettings + ", streamFactoryFactory=" + streamFactoryFactory + ", commandListeners=" + commandListeners + ", codecRegistry=" + codecRegistry @@ -1044,6 +1084,7 @@ private MongoClientSettings(final Builder builder) { retryReads = builder.retryReads; readConcern = builder.readConcern; credential = builder.credential; + transportSettings = builder.transportSettings; streamFactoryFactory = builder.streamFactoryFactory; codecRegistry = builder.codecRegistry; commandListeners = builder.commandListeners; diff --git a/driver-core/src/main/com/mongodb/annotations/Evolving.java b/driver-core/src/main/com/mongodb/annotations/Evolving.java index c6d58e3d4c2..ba9d8825dc6 100644 --- a/driver-core/src/main/com/mongodb/annotations/Evolving.java +++ b/driver-core/src/main/com/mongodb/annotations/Evolving.java @@ -18,7 +18,7 @@ package com.mongodb.annotations; -import com.mongodb.connection.StreamFactoryFactory; +import org.bson.codecs.Codec; import org.bson.conversions.Bson; import java.lang.annotation.Documented; @@ -52,7 +52,7 @@ * * * Doing so allows customizing API behavior. - * {@link StreamFactoryFactory} + * {@link Codec} * Not applicable. * * diff --git a/driver-core/src/main/com/mongodb/connection/AsynchronousSocketChannelStreamFactory.java b/driver-core/src/main/com/mongodb/connection/AsynchronousSocketChannelStreamFactory.java index e1fabf72597..f67c71ac90b 100644 --- a/driver-core/src/main/com/mongodb/connection/AsynchronousSocketChannelStreamFactory.java +++ b/driver-core/src/main/com/mongodb/connection/AsynchronousSocketChannelStreamFactory.java @@ -29,7 +29,9 @@ * Factory to create a Stream that's an AsynchronousSocketChannelStream. Throws an exception if SSL is enabled. * * @since 3.0 + * @deprecated There is no replacement for this class. */ +@Deprecated public class AsynchronousSocketChannelStreamFactory implements StreamFactory { private final PowerOfTwoBufferPool bufferProvider = PowerOfTwoBufferPool.DEFAULT; private final SocketSettings settings; diff --git a/driver-core/src/main/com/mongodb/connection/AsynchronousSocketChannelStreamFactoryFactory.java b/driver-core/src/main/com/mongodb/connection/AsynchronousSocketChannelStreamFactoryFactory.java index a566fd8285f..4dc7f437362 100644 --- a/driver-core/src/main/com/mongodb/connection/AsynchronousSocketChannelStreamFactoryFactory.java +++ b/driver-core/src/main/com/mongodb/connection/AsynchronousSocketChannelStreamFactoryFactory.java @@ -23,7 +23,9 @@ * * @see java.nio.channels.AsynchronousSocketChannel * @since 3.1 + * @deprecated There is no replacement for this class. */ +@Deprecated public final class AsynchronousSocketChannelStreamFactoryFactory implements StreamFactoryFactory { private final AsynchronousChannelGroup group; diff --git a/driver-core/src/main/com/mongodb/connection/BufferProvider.java b/driver-core/src/main/com/mongodb/connection/BufferProvider.java index 4f0fd0daa5b..6a904c4ffd5 100644 --- a/driver-core/src/main/com/mongodb/connection/BufferProvider.java +++ b/driver-core/src/main/com/mongodb/connection/BufferProvider.java @@ -23,7 +23,9 @@ * A provider of instances of ByteBuf. * * @since 3.0 + * @deprecated There is no replacement for this interface. */ +@Deprecated @ThreadSafe public interface BufferProvider { /** diff --git a/driver-core/src/main/com/mongodb/connection/NettyTransportSettings.java b/driver-core/src/main/com/mongodb/connection/NettyTransportSettings.java new file mode 100644 index 00000000000..d1e5beb940d --- /dev/null +++ b/driver-core/src/main/com/mongodb/connection/NettyTransportSettings.java @@ -0,0 +1,208 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.connection; + +import com.mongodb.annotations.Immutable; +import com.mongodb.lang.Nullable; +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.ssl.ReferenceCountedOpenSslClientContext; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.SslProvider; + +import java.security.Security; + +import static com.mongodb.assertions.Assertions.isTrueArgument; +import static com.mongodb.assertions.Assertions.notNull; + +/** + * {@code TransportSettings} for a Netty-based transport implementation. + * + * @since 4.11 + */ +@Immutable +public final class NettyTransportSettings extends TransportSettings { + + private final EventLoopGroup eventLoopGroup; + private final Class socketChannelClass; + private final ByteBufAllocator allocator; + private final SslContext sslContext; + + static Builder builder() { + return new Builder(); + } + + /** + * A builder for an instance of {@link NettyTransportSettings}. + */ + public static final class Builder { + private ByteBufAllocator allocator; + private Class socketChannelClass; + private EventLoopGroup eventLoopGroup; + private SslContext sslContext; + + private Builder() { + } + + /** + * Sets the allocator. + * + * @param allocator the allocator to use for ByteBuf instances + * @return this + * @see #getAllocator() + */ + public Builder allocator(final ByteBufAllocator allocator) { + this.allocator = notNull("allocator", allocator); + return this; + } + + /** + * Sets the socket channel class + * + * @param socketChannelClass the socket channel class + * @return this + * @see #getSocketChannelClass() + */ + public Builder socketChannelClass(final Class socketChannelClass) { + this.socketChannelClass = notNull("socketChannelClass", socketChannelClass); + return this; + } + + /** + * Sets the event loop group. + * + *

It is highly recommended to supply your own event loop group and manage its shutdown. Otherwise, the event + * loop group created by default will not be shutdown properly.

+ * + * @param eventLoopGroup the event loop group that all channels created by this factory will be a part of + * @return this + * @see #getEventLoopGroup() + */ + public Builder eventLoopGroup(final EventLoopGroup eventLoopGroup) { + this.eventLoopGroup = notNull("eventLoopGroup", eventLoopGroup); + return this; + } + + /** + * Sets a {@linkplain SslContextBuilder#forClient() client-side} {@link SslContext io.netty.handler.ssl.SslContext}, + * which overrides the standard {@link SslSettings#getContext()}. + * By default, it is {@code null} and {@link SslSettings#getContext()} is at play. + *

+ * This option may be used as a convenient way to utilize + * OpenSSL as an alternative to the TLS/SSL protocol implementation in a JDK. + * To achieve this, specify {@link SslProvider#OPENSSL} TLS/SSL protocol provider via + * {@link SslContextBuilder#sslProvider(SslProvider)}. Note that doing so adds a runtime dependency on + * netty-tcnative, which you must satisfy. + *

+ * Notes: + *

+ * + * @param sslContext The Netty {@link SslContext}, which must be created via {@linkplain SslContextBuilder#forClient()}. + * @return {@code this}. + * @see #getSslContext() + */ + public Builder sslContext(final SslContext sslContext) { + this.sslContext = notNull("sslContext", sslContext); + isTrueArgument("sslContext must be client-side", sslContext.isClient()); + isTrueArgument("sslContext must use either SslProvider.JDK or SslProvider.OPENSSL TLS/SSL protocol provider", + !(sslContext instanceof ReferenceCountedOpenSslClientContext)); + + return this; + } + + /** + * Build an instance of {@code NettyTransportSettings}. + * + * @return factory for {@code NettyTransportSettings} + */ + public NettyTransportSettings build() { + return new NettyTransportSettings(this); + } + } + + /** + * Gets the event loop group. + * + * @return the event loop group + * @see Builder#eventLoopGroup(EventLoopGroup) + */ + @Nullable + public EventLoopGroup getEventLoopGroup() { + return eventLoopGroup; + } + + /** + * Gets the socket channel class. + * + * @return the socket channel class + * @see Builder#socketChannelClass(Class) + */ + @Nullable + public Class getSocketChannelClass() { + return socketChannelClass; + } + + /** + * Gets the allocator. + * + * @return the allocator + * @see Builder#allocator(ByteBufAllocator) + */ + @Nullable + public ByteBufAllocator getAllocator() { + return allocator; + } + + /** + * Gets the SSL Context. + * + * @return the SSL context + * @see Builder#sslContext(SslContext) + */ + @Nullable + public SslContext getSslContext() { + return sslContext; + } + + @Override + public String toString() { + return "NettyTransportSettings{" + + "eventLoopGroup=" + eventLoopGroup + + ", socketChannelClass=" + socketChannelClass + + ", allocator=" + allocator + + ", sslContext=" + sslContext + + '}'; + } + + private NettyTransportSettings(final Builder builder) { + allocator = builder.allocator; + socketChannelClass = builder.socketChannelClass; + eventLoopGroup = builder.eventLoopGroup; + sslContext = builder.sslContext; + } +} diff --git a/driver-core/src/main/com/mongodb/connection/SocketStreamFactory.java b/driver-core/src/main/com/mongodb/connection/SocketStreamFactory.java index 71c49e52671..4bf1fcfd9da 100644 --- a/driver-core/src/main/com/mongodb/connection/SocketStreamFactory.java +++ b/driver-core/src/main/com/mongodb/connection/SocketStreamFactory.java @@ -35,7 +35,9 @@ * Factory for creating instances of {@code SocketStream}. * * @since 3.0 + * @deprecated There is no replacement for this class. */ +@Deprecated public class SocketStreamFactory implements StreamFactory { private final SocketSettings settings; private final SslSettings sslSettings; diff --git a/driver-core/src/main/com/mongodb/connection/Stream.java b/driver-core/src/main/com/mongodb/connection/Stream.java index f75143bd045..9c8a3a03d20 100644 --- a/driver-core/src/main/com/mongodb/connection/Stream.java +++ b/driver-core/src/main/com/mongodb/connection/Stream.java @@ -26,7 +26,9 @@ * A full duplex stream of bytes. * * @since 3.0 + * @deprecated There is no replacement for this interface. */ +@Deprecated public interface Stream extends BufferProvider{ /** diff --git a/driver-core/src/main/com/mongodb/connection/StreamFactory.java b/driver-core/src/main/com/mongodb/connection/StreamFactory.java index 0f97a44efe1..7974b4d6f74 100644 --- a/driver-core/src/main/com/mongodb/connection/StreamFactory.java +++ b/driver-core/src/main/com/mongodb/connection/StreamFactory.java @@ -22,7 +22,9 @@ * A factory for streams. * * @since 3.0 + * @deprecated There is no replacement for this interface. */ +@Deprecated public interface StreamFactory { /** * Create a Stream to the given address diff --git a/driver-core/src/main/com/mongodb/connection/StreamFactoryFactory.java b/driver-core/src/main/com/mongodb/connection/StreamFactoryFactory.java index 7b8f4ffc72c..8c81ef96fde 100644 --- a/driver-core/src/main/com/mongodb/connection/StreamFactoryFactory.java +++ b/driver-core/src/main/com/mongodb/connection/StreamFactoryFactory.java @@ -20,7 +20,9 @@ * A factory of {@code StreamFactory} instances. * * @since 3.1 + * @deprecated There is no replacement for this interface. */ +@Deprecated public interface StreamFactoryFactory { /** diff --git a/driver-core/src/main/com/mongodb/connection/TlsChannelStreamFactoryFactory.java b/driver-core/src/main/com/mongodb/connection/TlsChannelStreamFactoryFactory.java index 37436d55f57..90bc987272f 100644 --- a/driver-core/src/main/com/mongodb/connection/TlsChannelStreamFactoryFactory.java +++ b/driver-core/src/main/com/mongodb/connection/TlsChannelStreamFactoryFactory.java @@ -57,7 +57,9 @@ * A {@code StreamFactoryFactory} that supports TLS/SSL. The implementation supports asynchronous usage. * * @since 3.10 + * @deprecated There is no replacement for this class. */ +@Deprecated public class TlsChannelStreamFactoryFactory implements StreamFactoryFactory, Closeable { private static final Logger LOGGER = Loggers.getLogger("connection.tls"); diff --git a/driver-core/src/main/com/mongodb/connection/TransportSettings.java b/driver-core/src/main/com/mongodb/connection/TransportSettings.java new file mode 100644 index 00000000000..f897a481eb4 --- /dev/null +++ b/driver-core/src/main/com/mongodb/connection/TransportSettings.java @@ -0,0 +1,38 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.connection; + +import com.mongodb.annotations.Immutable; +import com.mongodb.annotations.Sealed; + +/** + * Transport settings for the driver. + * + * @since 4.11 + */ +@Sealed +@Immutable +public abstract class TransportSettings { + /** + * A builder for {@link NettyTransportSettings}. + * + * @return a builder for {@link NettyTransportSettings} + */ + public static NettyTransportSettings.Builder nettyBuilder() { + return NettyTransportSettings.builder(); + } +} diff --git a/driver-core/src/main/com/mongodb/connection/netty/NettyStream.java b/driver-core/src/main/com/mongodb/connection/netty/NettyStream.java index 61c690a63b4..197a42566f2 100644 --- a/driver-core/src/main/com/mongodb/connection/netty/NettyStream.java +++ b/driver-core/src/main/com/mongodb/connection/netty/NettyStream.java @@ -107,6 +107,7 @@ * itself in the example above. However, there are no concurrent pending readers because the second operation * is invoked after the first operation has completed reading despite the method has not returned yet. */ +@SuppressWarnings("deprecation") final class NettyStream implements Stream { private static final byte NO_SCHEDULE_TIME = 0; private final ServerAddress address; diff --git a/driver-core/src/main/com/mongodb/connection/netty/NettyStreamFactory.java b/driver-core/src/main/com/mongodb/connection/netty/NettyStreamFactory.java index 6a387a0d8ff..22d33b8ce2b 100644 --- a/driver-core/src/main/com/mongodb/connection/netty/NettyStreamFactory.java +++ b/driver-core/src/main/com/mongodb/connection/netty/NettyStreamFactory.java @@ -36,7 +36,10 @@ * A StreamFactory for Streams based on Netty 4.x. * * @since 3.0 + * @deprecated there is no replacement for this class */ +@SuppressWarnings("deprecation") +@Deprecated public class NettyStreamFactory implements StreamFactory { private final SocketSettings settings; private final SslSettings sslSettings; diff --git a/driver-core/src/main/com/mongodb/connection/netty/NettyStreamFactoryFactory.java b/driver-core/src/main/com/mongodb/connection/netty/NettyStreamFactoryFactory.java index cb34ac1103f..20995edde70 100644 --- a/driver-core/src/main/com/mongodb/connection/netty/NettyStreamFactoryFactory.java +++ b/driver-core/src/main/com/mongodb/connection/netty/NettyStreamFactoryFactory.java @@ -16,10 +16,13 @@ package com.mongodb.connection.netty; +import com.mongodb.connection.NettyTransportSettings; import com.mongodb.connection.SocketSettings; import com.mongodb.connection.SslSettings; import com.mongodb.connection.StreamFactory; import com.mongodb.connection.StreamFactoryFactory; +import com.mongodb.connection.TransportSettings; +import com.mongodb.internal.VisibleForTesting; import com.mongodb.lang.Nullable; import io.netty.buffer.ByteBufAllocator; import io.netty.channel.EventLoopGroup; @@ -32,15 +35,20 @@ import io.netty.handler.ssl.SslProvider; import java.security.Security; +import java.util.Objects; import static com.mongodb.assertions.Assertions.isTrueArgument; import static com.mongodb.assertions.Assertions.notNull; +import static com.mongodb.internal.VisibleForTesting.AccessModifier.PRIVATE; /** * A {@code StreamFactoryFactory} implementation for Netty-based streams. * * @since 3.1 + * @deprecated Prefer {@link NettyTransportSettings}, creatable via {@link TransportSettings#nettyBuilder()} and applied via + * {@link com.mongodb.MongoClientSettings.Builder#transportSettings(TransportSettings)} */ +@Deprecated public final class NettyStreamFactoryFactory implements StreamFactoryFactory { private final EventLoopGroup eventLoopGroup; @@ -58,6 +66,27 @@ public static Builder builder() { return new Builder(); } + @VisibleForTesting(otherwise = PRIVATE) + EventLoopGroup getEventLoopGroup() { + return eventLoopGroup; + } + + @VisibleForTesting(otherwise = PRIVATE) + Class getSocketChannelClass() { + return socketChannelClass; + } + + @VisibleForTesting(otherwise = PRIVATE) + ByteBufAllocator getAllocator() { + return allocator; + } + + @VisibleForTesting(otherwise = PRIVATE) + @Nullable + SslContext getSslContext() { + return sslContext; + } + /** * A builder for an instance of {@code NettyStreamFactoryFactory}. * @@ -71,10 +100,23 @@ public static final class Builder { private SslContext sslContext; private Builder() { - allocator(ByteBufAllocator.DEFAULT); - socketChannelClass(NioSocketChannel.class); } + /** + * Apply NettyTransportSettings + * + * @param settings the settings + * @return this + */ + public Builder applySettings(final NettyTransportSettings settings) { + this.allocator = settings.getAllocator(); + this.eventLoopGroup = settings.getEventLoopGroup(); + this.sslContext = settings.getSslContext(); + this.socketChannelClass = settings.getSocketChannelClass(); + return this; + } + + /** * Sets the allocator. * @@ -162,6 +204,24 @@ public StreamFactory create(final SocketSettings socketSettings, final SslSettin return new NettyStreamFactory(socketSettings, sslSettings, eventLoopGroup, socketChannelClass, allocator, sslContext); } + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NettyStreamFactoryFactory that = (NettyStreamFactoryFactory) o; + return Objects.equals(eventLoopGroup, that.eventLoopGroup) && Objects.equals(socketChannelClass, that.socketChannelClass) + && Objects.equals(allocator, that.allocator) && Objects.equals(sslContext, that.sslContext); + } + + @Override + public int hashCode() { + return Objects.hash(eventLoopGroup, socketChannelClass, allocator, sslContext); + } + @Override public String toString() { return "NettyStreamFactoryFactory{" @@ -173,13 +233,9 @@ public String toString() { } private NettyStreamFactoryFactory(final Builder builder) { - allocator = builder.allocator; - socketChannelClass = builder.socketChannelClass; - if (builder.eventLoopGroup != null) { - eventLoopGroup = builder.eventLoopGroup; - } else { - eventLoopGroup = new NioEventLoopGroup(); - } + allocator = builder.allocator == null ? ByteBufAllocator.DEFAULT : builder.allocator; + socketChannelClass = builder.socketChannelClass == null ? NioSocketChannel.class : builder.socketChannelClass; + eventLoopGroup = builder.eventLoopGroup == null ? new NioEventLoopGroup() : builder.eventLoopGroup; sslContext = builder.sslContext; } } diff --git a/driver-core/src/main/com/mongodb/internal/connection/AsynchronousChannelStream.java b/driver-core/src/main/com/mongodb/internal/connection/AsynchronousChannelStream.java index 5a847659e1f..a22a0edcf89 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/AsynchronousChannelStream.java +++ b/driver-core/src/main/com/mongodb/internal/connection/AsynchronousChannelStream.java @@ -43,6 +43,7 @@ /** *

This class is not part of the public API and may be removed or changed at any time

*/ +@SuppressWarnings("deprecation") public abstract class AsynchronousChannelStream implements Stream { private final ServerAddress serverAddress; private final SocketSettings settings; diff --git a/driver-core/src/main/com/mongodb/internal/connection/ByteBufferBsonOutput.java b/driver-core/src/main/com/mongodb/internal/connection/ByteBufferBsonOutput.java index 2f6776b68ea..91fee075cf3 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/ByteBufferBsonOutput.java +++ b/driver-core/src/main/com/mongodb/internal/connection/ByteBufferBsonOutput.java @@ -31,6 +31,7 @@ /** *

This class is not part of the public API and may be removed or changed at any time

*/ +@SuppressWarnings("deprecation") public class ByteBufferBsonOutput extends OutputBuffer { private static final int MAX_SHIFT = 31; diff --git a/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java b/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java index d7749ce30c5..22badc93a9d 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java @@ -50,6 +50,7 @@ * *

This class is not part of the public API and may be removed or changed at any time

*/ +@SuppressWarnings("deprecation") public final class DefaultClusterFactory { public Cluster createCluster(final ClusterSettings originalClusterSettings, final ServerSettings originalServerSettings, diff --git a/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java b/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java index c5e66200de1..9b8ac1399b3 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java @@ -41,6 +41,7 @@ /** *

This class is not part of the public API and may be removed or changed at any time

*/ +@SuppressWarnings("deprecation") public class DefaultClusterableServerFactory implements ClusterableServerFactory { private final ServerSettings serverSettings; private final ConnectionPoolSettings connectionPoolSettings; diff --git a/driver-core/src/main/com/mongodb/internal/connection/InternalConnection.java b/driver-core/src/main/com/mongodb/internal/connection/InternalConnection.java index 59e34404b1f..735c5e25164 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/InternalConnection.java +++ b/driver-core/src/main/com/mongodb/internal/connection/InternalConnection.java @@ -31,6 +31,7 @@ /** *

This class is not part of the public API and may be removed or changed at any time

*/ +@SuppressWarnings("deprecation") public interface InternalConnection extends BufferProvider { int NOT_INITIALIZED_GENERATION = -1; diff --git a/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnection.java b/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnection.java index 64e85a6d337..43bcf89b6da 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnection.java +++ b/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnection.java @@ -95,6 +95,7 @@ *

This class is not part of the public API and may be removed or changed at any time

*/ @NotThreadSafe +@SuppressWarnings("deprecation") public class InternalStreamConnection implements InternalConnection { private static final Set SECURITY_SENSITIVE_COMMANDS = new HashSet<>(asList( diff --git a/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionFactory.java b/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionFactory.java index 2431a3b800a..c1b071baaff 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionFactory.java @@ -34,6 +34,7 @@ import static com.mongodb.assertions.Assertions.notNull; import static com.mongodb.internal.connection.ClientMetadataHelper.createClientMetadataDocument; +@SuppressWarnings("deprecation") class InternalStreamConnectionFactory implements InternalConnectionFactory { private final ClusterConnectionMode clusterConnectionMode; private final boolean isMonitoringConnection; diff --git a/driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java b/driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java index 54d3aca40e0..5752d41b9b6 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java @@ -41,6 +41,7 @@ *

This class is not part of the public API and may be removed or changed at any time

*/ @ThreadSafe +@SuppressWarnings("deprecation") public class LoadBalancedClusterableServerFactory implements ClusterableServerFactory { private final ServerSettings serverSettings; private final ConnectionPoolSettings connectionPoolSettings; diff --git a/driver-core/src/main/com/mongodb/internal/connection/PowerOfTwoBufferPool.java b/driver-core/src/main/com/mongodb/internal/connection/PowerOfTwoBufferPool.java index fea9b91e4ff..365cc7ebff2 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/PowerOfTwoBufferPool.java +++ b/driver-core/src/main/com/mongodb/internal/connection/PowerOfTwoBufferPool.java @@ -34,6 +34,7 @@ /** *

This class is not part of the public API and may be removed or changed at any time

*/ +@SuppressWarnings("deprecation") public class PowerOfTwoBufferPool implements BufferProvider { /** diff --git a/driver-core/src/main/com/mongodb/internal/connection/SocketStream.java b/driver-core/src/main/com/mongodb/internal/connection/SocketStream.java index 7d43c134a40..bab583ab310 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/SocketStream.java +++ b/driver-core/src/main/com/mongodb/internal/connection/SocketStream.java @@ -50,6 +50,7 @@ /** *

This class is not part of the public API and may be removed or changed at any time

*/ +@SuppressWarnings("deprecation") public class SocketStream implements Stream { private final ServerAddress address; private final SocketSettings settings; diff --git a/driver-core/src/main/com/mongodb/internal/connection/StreamFactoryHelper.java b/driver-core/src/main/com/mongodb/internal/connection/StreamFactoryHelper.java new file mode 100644 index 00000000000..ccd05a17104 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/connection/StreamFactoryHelper.java @@ -0,0 +1,51 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.internal.connection; + +import com.mongodb.MongoClientException; +import com.mongodb.MongoClientSettings; +import com.mongodb.connection.NettyTransportSettings; +import com.mongodb.connection.StreamFactoryFactory; +import com.mongodb.connection.TransportSettings; +import com.mongodb.connection.netty.NettyStreamFactoryFactory; +import com.mongodb.lang.Nullable; + +/** + *

This class is not part of the public API and may be removed or changed at any time

+ */ +@SuppressWarnings("deprecation") +public final class StreamFactoryHelper { + @Nullable + public static StreamFactoryFactory getStreamFactoryFactoryFromSettings(final MongoClientSettings settings) { + StreamFactoryFactory streamFactoryFactory; + TransportSettings transportSettings = settings.getTransportSettings(); + if (transportSettings != null) { + if (transportSettings instanceof NettyTransportSettings) { + streamFactoryFactory = + NettyStreamFactoryFactory.builder().applySettings((NettyTransportSettings) transportSettings).build(); + } else { + throw new MongoClientException("Unsupported transport settings: " + transportSettings.getClass().getName()); + } + } else { + streamFactoryFactory = settings.getStreamFactoryFactory(); + } + return streamFactoryFactory; + } + + private StreamFactoryHelper() { + } +} diff --git a/driver-core/src/main/com/mongodb/internal/connection/UnixSocketChannelStream.java b/driver-core/src/main/com/mongodb/internal/connection/UnixSocketChannelStream.java index b56887c0fbc..f19c85740c7 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/UnixSocketChannelStream.java +++ b/driver-core/src/main/com/mongodb/internal/connection/UnixSocketChannelStream.java @@ -30,6 +30,7 @@ /** *

This class is not part of the public API and may be removed or changed at any time

*/ +@SuppressWarnings("deprecation") public class UnixSocketChannelStream extends SocketStream { private final UnixServerAddress address; diff --git a/driver-core/src/test/functional/com/mongodb/ClusterFixture.java b/driver-core/src/test/functional/com/mongodb/ClusterFixture.java index 85b4a9cfeac..c40d35405dc 100644 --- a/driver-core/src/test/functional/com/mongodb/ClusterFixture.java +++ b/driver-core/src/test/functional/com/mongodb/ClusterFixture.java @@ -100,6 +100,7 @@ * Helper class for the acceptance tests. Used primarily by DatabaseTestCase and FunctionalSpecification. This fixture allows Test * super-classes to share functionality whilst minimising duplication. */ +@SuppressWarnings("deprecation") public final class ClusterFixture { public static final String DEFAULT_URI = "mongodb://localhost:27017"; public static final String MONGODB_URI_SYSTEM_PROPERTY_NAME = "org.mongodb.test.uri"; diff --git a/driver-core/src/test/functional/com/mongodb/internal/connection/PlainAuthenticatorTest.java b/driver-core/src/test/functional/com/mongodb/internal/connection/PlainAuthenticatorTest.java index 348f4fdf47c..f2230b92ca0 100644 --- a/driver-core/src/test/functional/com/mongodb/internal/connection/PlainAuthenticatorTest.java +++ b/driver-core/src/test/functional/com/mongodb/internal/connection/PlainAuthenticatorTest.java @@ -39,6 +39,7 @@ import static com.mongodb.ClusterFixture.getSslSettings; @Ignore +@SuppressWarnings("deprecation") public class PlainAuthenticatorTest { private InternalConnection internalConnection; private ConnectionDescription connectionDescription; diff --git a/driver-core/src/test/functional/com/mongodb/internal/connection/SingleServerClusterTest.java b/driver-core/src/test/functional/com/mongodb/internal/connection/SingleServerClusterTest.java index 66fa750803f..1f8ad92eaf4 100644 --- a/driver-core/src/test/functional/com/mongodb/internal/connection/SingleServerClusterTest.java +++ b/driver-core/src/test/functional/com/mongodb/internal/connection/SingleServerClusterTest.java @@ -51,6 +51,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +@SuppressWarnings("deprecation") public class SingleServerClusterTest { private SingleServerCluster cluster; diff --git a/driver-core/src/test/unit/com/mongodb/MongoClientSettingsSpecification.groovy b/driver-core/src/test/unit/com/mongodb/MongoClientSettingsSpecification.groovy index be63708ddf0..6f1e01f2f5e 100644 --- a/driver-core/src/test/unit/com/mongodb/MongoClientSettingsSpecification.groovy +++ b/driver-core/src/test/unit/com/mongodb/MongoClientSettingsSpecification.groovy @@ -23,6 +23,7 @@ import com.mongodb.connection.ProxySettings import com.mongodb.connection.ServerSettings import com.mongodb.connection.SocketSettings import com.mongodb.connection.SslSettings +import com.mongodb.connection.TransportSettings import com.mongodb.connection.netty.NettyStreamFactoryFactory import com.mongodb.event.CommandListener import com.mongodb.spi.dns.DnsClient @@ -57,6 +58,7 @@ class MongoClientSettingsSpecification extends Specification { settings.socketSettings.proxySettings == ProxySettings.builder().build() settings.heartbeatSocketSettings == SocketSettings.builder().readTimeout(10000, TimeUnit.MILLISECONDS).build() settings.serverSettings == ServerSettings.builder().build() + settings.transportSettings == null settings.streamFactoryFactory == null settings.compressorList == [] settings.credential == null @@ -96,6 +98,11 @@ class MongoClientSettingsSpecification extends Specification { then: thrown(IllegalArgumentException) + when: + builder.transportSettings(null) + then: + thrown(IllegalArgumentException) + when: builder.streamFactoryFactory(null) then: @@ -119,6 +126,7 @@ class MongoClientSettingsSpecification extends Specification { def 'should build with set configuration'() { given: + def transportSettings = TransportSettings.nettyBuilder().build() def streamFactoryFactory = NettyStreamFactoryFactory.builder().build() def credential = MongoCredential.createMongoX509Credential('test') def codecRegistry = Stub(CodecRegistry) @@ -145,6 +153,7 @@ class MongoClientSettingsSpecification extends Specification { builder.applySettings(clusterSettings) } }) + .transportSettings(transportSettings) .streamFactoryFactory(streamFactoryFactory) .compressorList([MongoCompressor.createZlibCompressor()]) .uuidRepresentation(UuidRepresentation.STANDARD) @@ -166,6 +175,7 @@ class MongoClientSettingsSpecification extends Specification { settings.getCodecRegistry() == codecRegistry settings.getCredential() == credential settings.getClusterSettings() == clusterSettings + settings.getTransportSettings() == transportSettings settings.getStreamFactoryFactory() == streamFactoryFactory settings.getCompressorList() == [MongoCompressor.createZlibCompressor()] settings.getUuidRepresentation() == UuidRepresentation.STANDARD @@ -525,7 +535,7 @@ class MongoClientSettingsSpecification extends Specification { 'heartbeatConnectTimeoutMS', 'heartbeatSocketTimeoutMS', 'inetAddressResolver', 'loggerSettingsBuilder', 'readConcern', 'readPreference', 'retryReads', 'retryWrites', 'serverApi', 'serverSettingsBuilder', 'socketSettingsBuilder', 'sslSettingsBuilder', - 'streamFactoryFactory', 'uuidRepresentation', 'writeConcern'] + 'streamFactoryFactory', 'transportSettings', 'uuidRepresentation', 'writeConcern'] then: actual == expected @@ -540,7 +550,7 @@ class MongoClientSettingsSpecification extends Specification { 'applyToSslSettings', 'autoEncryptionSettings', 'build', 'codecRegistry', 'commandListenerList', 'compressorList', 'contextProvider', 'credential', 'dnsClient', 'heartbeatConnectTimeoutMS', 'heartbeatSocketTimeoutMS', 'inetAddressResolver', 'readConcern', 'readPreference', 'retryReads', 'retryWrites', - 'serverApi', 'streamFactoryFactory', 'uuidRepresentation', 'writeConcern'] + 'serverApi', 'streamFactoryFactory', 'transportSettings', 'uuidRepresentation', 'writeConcern'] then: actual == expected } diff --git a/driver-core/src/test/unit/com/mongodb/connection/NettyTransportSettingsTest.java b/driver-core/src/test/unit/com/mongodb/connection/NettyTransportSettingsTest.java new file mode 100644 index 00000000000..4030c0672bf --- /dev/null +++ b/driver-core/src/test/unit/com/mongodb/connection/NettyTransportSettingsTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.connection; + +import io.netty.buffer.UnpooledByteBufAllocator; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.oio.OioEventLoopGroup; +import io.netty.channel.socket.oio.OioSocketChannel; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import org.junit.jupiter.api.Test; + +import javax.net.ssl.SSLException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class NettyTransportSettingsTest { + @Test + public void shouldDefaultAllValuesToNull() { + NettyTransportSettings settings = TransportSettings.nettyBuilder().build(); + + assertNull(settings.getAllocator()); + assertNull(settings.getEventLoopGroup()); + assertNull(settings.getSslContext()); + assertNull(settings.getSocketChannelClass()); + } + + @SuppressWarnings("deprecation") + @Test + public void shouldApplySettingsFromBuilder() throws SSLException { + EventLoopGroup eventLoopGroup = new OioEventLoopGroup(); + SslContext sslContext = SslContextBuilder.forClient().build(); + NettyTransportSettings settings = TransportSettings.nettyBuilder() + .allocator(UnpooledByteBufAllocator.DEFAULT) + .socketChannelClass(OioSocketChannel.class) + .eventLoopGroup(eventLoopGroup) + .sslContext(sslContext) + .build(); + + assertEquals(UnpooledByteBufAllocator.DEFAULT, settings.getAllocator()); + assertEquals(OioSocketChannel.class, settings.getSocketChannelClass()); + assertEquals(eventLoopGroup, settings.getEventLoopGroup()); + assertEquals(sslContext, settings.getSslContext()); + } +} diff --git a/driver-core/src/test/unit/com/mongodb/connection/netty/NettyStreamFactoryFactorySpecification.groovy b/driver-core/src/test/unit/com/mongodb/connection/netty/NettyStreamFactoryFactorySpecification.groovy index 2cc3123e4d3..99291dbe28c 100644 --- a/driver-core/src/test/unit/com/mongodb/connection/netty/NettyStreamFactoryFactorySpecification.groovy +++ b/driver-core/src/test/unit/com/mongodb/connection/netty/NettyStreamFactoryFactorySpecification.groovy @@ -19,17 +19,40 @@ package com.mongodb.connection.netty import com.mongodb.ServerAddress import com.mongodb.connection.SocketSettings import com.mongodb.connection.SslSettings +import com.mongodb.connection.TransportSettings import io.netty.buffer.ByteBufAllocator import io.netty.buffer.UnpooledByteBufAllocator import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.oio.OioEventLoopGroup import io.netty.channel.socket.nio.NioSocketChannel import io.netty.channel.socket.oio.OioSocketChannel +import io.netty.handler.ssl.SslContextBuilder import spock.lang.Specification import spock.lang.Unroll class NettyStreamFactoryFactorySpecification extends Specification { + def 'should apply NettingSettings'() { + given: + def nettySettings = TransportSettings.nettyBuilder() + .allocator(UnpooledByteBufAllocator.DEFAULT) + .socketChannelClass(OioSocketChannel) + .eventLoopGroup(new OioEventLoopGroup()) + .sslContext(SslContextBuilder.forClient().build()) + .build() + + when: + def factoryFactory = NettyStreamFactoryFactory.builder() + .applySettings(nettySettings) + .build() + + then: + factoryFactory.getAllocator() == nettySettings.getAllocator() + factoryFactory.getEventLoopGroup() == nettySettings.getEventLoopGroup(); + factoryFactory.getSocketChannelClass() == nettySettings.getSocketChannelClass() + factoryFactory.getSslContext() == nettySettings.getSslContext() + } + @Unroll def 'should create the expected #description NettyStream'() { given: diff --git a/driver-core/src/test/unit/com/mongodb/internal/connection/ConnectionPoolAsyncTest.java b/driver-core/src/test/unit/com/mongodb/internal/connection/ConnectionPoolAsyncTest.java index cd6fdecbfc4..954ea0b714b 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/connection/ConnectionPoolAsyncTest.java +++ b/driver-core/src/test/unit/com/mongodb/internal/connection/ConnectionPoolAsyncTest.java @@ -34,6 +34,7 @@ // https://github.com/mongodb/specifications/blob/master/source/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst // specification tests @RunWith(Parameterized.class) +@SuppressWarnings("deprecation") public class ConnectionPoolAsyncTest extends AbstractConnectionPoolTest { private static final Logger LOGGER = Loggers.getLogger(ConnectionPoolAsyncTest.class.getSimpleName()); diff --git a/driver-core/src/test/unit/com/mongodb/internal/connection/ConnectionPoolTest.java b/driver-core/src/test/unit/com/mongodb/internal/connection/ConnectionPoolTest.java index a9fe7963800..5d2dd413eea 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/connection/ConnectionPoolTest.java +++ b/driver-core/src/test/unit/com/mongodb/internal/connection/ConnectionPoolTest.java @@ -32,6 +32,7 @@ // https://github.com/mongodb/specifications/blob/master/source/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst // specification tests @RunWith(Parameterized.class) +@SuppressWarnings("deprecation") public class ConnectionPoolTest extends AbstractConnectionPoolTest { private static final Logger LOGGER = Loggers.getLogger(ConnectionPoolTest.class.getSimpleName()); diff --git a/driver-core/src/test/unit/com/mongodb/internal/connection/SimpleBufferProvider.java b/driver-core/src/test/unit/com/mongodb/internal/connection/SimpleBufferProvider.java index aa7dd203931..ffb275d34be 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/connection/SimpleBufferProvider.java +++ b/driver-core/src/test/unit/com/mongodb/internal/connection/SimpleBufferProvider.java @@ -22,6 +22,7 @@ import java.nio.ByteBuffer; +@SuppressWarnings("deprecation") public class SimpleBufferProvider implements BufferProvider { @Override public ByteBuf getBuffer(final int size) { diff --git a/driver-core/src/test/unit/com/mongodb/internal/connection/StreamFactoryHelperTest.java b/driver-core/src/test/unit/com/mongodb/internal/connection/StreamFactoryHelperTest.java new file mode 100644 index 00000000000..e71d9e10f5c --- /dev/null +++ b/driver-core/src/test/unit/com/mongodb/internal/connection/StreamFactoryHelperTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mongodb.internal.connection; + +import com.mongodb.MongoClientSettings; +import com.mongodb.connection.NettyTransportSettings; +import com.mongodb.connection.TransportSettings; +import com.mongodb.connection.netty.NettyStreamFactoryFactory; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.oio.OioSocketChannel; +import org.junit.jupiter.api.Test; + +import static com.mongodb.assertions.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SuppressWarnings("deprecation") +class StreamFactoryHelperTest { + + @Test + void streamFactoryFactoryIsNullWithDefaultSettings() { + MongoClientSettings settings = MongoClientSettings.builder().build(); + assertNull(StreamFactoryHelper.getStreamFactoryFactoryFromSettings(settings)); + } + + @Test + void streamFactoryFactoryIsEqualToSettingsStreamFactoryFactory() { + NettyStreamFactoryFactory streamFactoryFactory = NettyStreamFactoryFactory.builder().build(); + MongoClientSettings settings = MongoClientSettings.builder() + .streamFactoryFactory(streamFactoryFactory) + .build(); + assertEquals(streamFactoryFactory, StreamFactoryHelper.getStreamFactoryFactoryFromSettings(settings)); + } + + @Test + void streamFactoryFactoryIsDerivedFromTransportSettings() { + NettyTransportSettings nettyTransportSettings = TransportSettings.nettyBuilder() + .eventLoopGroup(new NioEventLoopGroup()) + .allocator(PooledByteBufAllocator.DEFAULT) + .socketChannelClass(OioSocketChannel.class) + .build(); + MongoClientSettings settings = MongoClientSettings.builder() + .transportSettings(nettyTransportSettings) + .build(); + assertEquals(NettyStreamFactoryFactory.builder().applySettings(nettyTransportSettings).build(), + StreamFactoryHelper.getStreamFactoryFactoryFromSettings(settings)); + } +} diff --git a/driver-core/src/test/unit/com/mongodb/internal/connection/TestInternalConnection.java b/driver-core/src/test/unit/com/mongodb/internal/connection/TestInternalConnection.java index aac47eb46e4..d363dcc7cdb 100644 --- a/driver-core/src/test/unit/com/mongodb/internal/connection/TestInternalConnection.java +++ b/driver-core/src/test/unit/com/mongodb/internal/connection/TestInternalConnection.java @@ -47,6 +47,7 @@ import static com.mongodb.internal.connection.ProtocolHelper.isCommandOk; import static com.mongodb.internal.operation.ServerVersionHelper.THREE_DOT_SIX_WIRE_VERSION; +@SuppressWarnings("deprecation") class TestInternalConnection implements InternalConnection { private static class Interaction { diff --git a/driver-legacy/src/main/com/mongodb/DBDecoderAdapter.java b/driver-legacy/src/main/com/mongodb/DBDecoderAdapter.java index 8d995e1abd9..9710e3b6e51 100644 --- a/driver-legacy/src/main/com/mongodb/DBDecoderAdapter.java +++ b/driver-legacy/src/main/com/mongodb/DBDecoderAdapter.java @@ -26,6 +26,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +@SuppressWarnings("deprecation") class DBDecoderAdapter implements Decoder { private final DBDecoder decoder; private final DBCollection collection; diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/MongoClients.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/MongoClients.java index 2e34af751e1..388fca29180 100644 --- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/MongoClients.java +++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/MongoClients.java @@ -20,7 +20,6 @@ import com.mongodb.MongoClientException; import com.mongodb.MongoClientSettings; import com.mongodb.MongoDriverInformation; -import com.mongodb.MongoInternalException; import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory; import com.mongodb.connection.StreamFactory; import com.mongodb.connection.StreamFactoryFactory; @@ -35,6 +34,7 @@ import java.io.Closeable; import static com.mongodb.assertions.Assertions.notNull; +import static com.mongodb.internal.connection.StreamFactoryHelper.getStreamFactoryFactoryFromSettings; import static com.mongodb.internal.event.EventListenerHelper.getCommandListener; @@ -42,6 +42,7 @@ * A factory for MongoClient instances. * */ +@SuppressWarnings("deprecation") public final class MongoClients { /** @@ -109,19 +110,22 @@ public static MongoClient create(final MongoClientSettings settings) { * @return the client * @since 1.8 */ + @SuppressWarnings("deprecation") public static MongoClient create(final MongoClientSettings settings, @Nullable final MongoDriverInformation mongoDriverInformation) { if (settings.getSocketSettings().getProxySettings().isProxyEnabled()) { throw new MongoClientException("Proxy is not supported for reactive clients"); } - if (settings.getStreamFactoryFactory() == null) { + StreamFactoryFactory streamFactoryFactory = getStreamFactoryFactoryFromSettings(settings); + + if (streamFactoryFactory == null) { if (settings.getSslSettings().isEnabled()) { return createWithTlsChannel(settings, mongoDriverInformation); } else { return createWithAsynchronousSocketChannel(settings, mongoDriverInformation); } } else { - return createMongoClient(settings, mongoDriverInformation, getStreamFactory(settings, false), - getStreamFactory(settings, true), null); + return createMongoClient(settings, mongoDriverInformation, getStreamFactory(streamFactoryFactory, settings, false), + getStreamFactory(streamFactoryFactory, settings, true), null); } } @@ -179,11 +183,8 @@ private static MongoClient createWithAsynchronousSocketChannel(final MongoClient return createMongoClient(settings, mongoDriverInformation, streamFactory, heartbeatStreamFactory, null); } - private static StreamFactory getStreamFactory(final MongoClientSettings settings, final boolean isHeartbeat) { - StreamFactoryFactory streamFactoryFactory = settings.getStreamFactoryFactory(); - if (streamFactoryFactory == null) { - throw new MongoInternalException("should not happen"); - } + private static StreamFactory getStreamFactory(final StreamFactoryFactory streamFactoryFactory, final MongoClientSettings settings, + final boolean isHeartbeat) { return streamFactoryFactory.create(isHeartbeat ? settings.getHeartbeatSocketSettings() : settings.getSocketSettings(), settings.getSslSettings()); } diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/crypt/KeyManagementService.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/crypt/KeyManagementService.java index 34ce6cb9e3f..b01b63d4a64 100644 --- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/crypt/KeyManagementService.java +++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/crypt/KeyManagementService.java @@ -43,6 +43,7 @@ import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.MILLISECONDS; +@SuppressWarnings("deprecation") class KeyManagementService implements Closeable { private static final Logger LOGGER = Loggers.getLogger("client"); private final Map kmsProviderSslContextMap; diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/Fixture.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/Fixture.java index a184dfa80c1..75a943b0c9b 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/Fixture.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/Fixture.java @@ -44,6 +44,7 @@ /** * Helper class for asynchronous tests. */ +@SuppressWarnings("deprecation") public final class Fixture { private static MongoClientImpl mongoClient; private static ServerVersion serverVersion; diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/MainTransactionsTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/MainTransactionsTest.java index b7b25472f3e..c8e6625e920 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/MainTransactionsTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/MainTransactionsTest.java @@ -35,6 +35,7 @@ import static com.mongodb.reactivestreams.client.syncadapter.ContextHelper.CONTEXT_PROVIDER; import static com.mongodb.reactivestreams.client.syncadapter.ContextHelper.assertContextPassedThrough; +@SuppressWarnings("deprecation") public class MainTransactionsTest extends AbstractMainTransactionsTest { public static final Set SESSION_CLOSE_TIMING_SENSITIVE_TESTS = new HashSet<>(Collections.singletonList( "implicit abort")); diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/MongoClientsSpecification.groovy b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/MongoClientsSpecification.groovy index 68c2163600e..39bb47395c4 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/MongoClientsSpecification.groovy +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/MongoClientsSpecification.groovy @@ -16,11 +16,13 @@ package com.mongodb.reactivestreams.client +import com.mongodb.MongoClientSettings import com.mongodb.MongoCompressor import com.mongodb.MongoCredential import com.mongodb.ReadConcern import com.mongodb.ServerAddress import com.mongodb.WriteConcern +import com.mongodb.connection.TransportSettings import com.mongodb.reactivestreams.client.internal.MongoClientImpl import org.bson.Document import reactor.core.publisher.Mono @@ -213,4 +215,21 @@ class MongoClientsSpecification extends FunctionalSpecification { 'mongodb://localhost/?compressors=zlib' | [MongoCompressor.createZlibCompressor()] 'mongodb://localhost/?compressors=zstd' | [MongoCompressor.createZstdCompressor()] } + + def 'should create client with transport settings'() { + given: + def nettySettings = TransportSettings.nettyBuilder().build() + def settings = MongoClientSettings.builder() + .transportSettings(nettySettings) + .build() + + when: + def client = MongoClients.create(settings) + + then: + true + + cleanup: + client?.close() + } } diff --git a/driver-scala/src/main/scala/org/mongodb/scala/connection/AsynchronousSocketChannelStreamFactoryFactory.scala b/driver-scala/src/main/scala/org/mongodb/scala/connection/AsynchronousSocketChannelStreamFactoryFactory.scala index 94ceba96d36..c887f3d211d 100644 --- a/driver-scala/src/main/scala/org/mongodb/scala/connection/AsynchronousSocketChannelStreamFactoryFactory.scala +++ b/driver-scala/src/main/scala/org/mongodb/scala/connection/AsynchronousSocketChannelStreamFactoryFactory.scala @@ -26,6 +26,7 @@ import com.mongodb.connection.{ * @see java.nio.channels.AsynchronousSocketChannel * @since 1.0 */ +@deprecated("For removal in 5.0", "4.11.0") object AsynchronousSocketChannelStreamFactoryFactory { /** diff --git a/driver-scala/src/main/scala/org/mongodb/scala/connection/NettyStreamFactoryFactory.scala b/driver-scala/src/main/scala/org/mongodb/scala/connection/NettyStreamFactoryFactory.scala index e00ff742bfd..37a0a00b8e2 100644 --- a/driver-scala/src/main/scala/org/mongodb/scala/connection/NettyStreamFactoryFactory.scala +++ b/driver-scala/src/main/scala/org/mongodb/scala/connection/NettyStreamFactoryFactory.scala @@ -23,6 +23,7 @@ import com.mongodb.connection.netty.{ NettyStreamFactoryFactory => JNettyStreamF * * @since 1.0 */ +@deprecated("For removal in 5.0", "4.11.0") object NettyStreamFactoryFactory { def apply(): StreamFactoryFactory = JNettyStreamFactoryFactory.builder().build() diff --git a/driver-scala/src/main/scala/org/mongodb/scala/connection/NettyTransportSettings.scala b/driver-scala/src/main/scala/org/mongodb/scala/connection/NettyTransportSettings.scala new file mode 100644 index 00000000000..de1dd57a93f --- /dev/null +++ b/driver-scala/src/main/scala/org/mongodb/scala/connection/NettyTransportSettings.scala @@ -0,0 +1,32 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.mongodb.scala.connection + +import com.mongodb.connection.{ NettyTransportSettings => JNettyTransportSettings } + +/** + * An immutable class representing Netty transport settings used for connections to a MongoDB server. + * + * @since 4.11 + */ +object NettyTransportSettings { + + /** + * NettyTransportSettings builder type + */ + type Builder = JNettyTransportSettings.Builder +} diff --git a/driver-scala/src/main/scala/org/mongodb/scala/connection/TransportSettings.scala b/driver-scala/src/main/scala/org/mongodb/scala/connection/TransportSettings.scala new file mode 100644 index 00000000000..3e194ea96ca --- /dev/null +++ b/driver-scala/src/main/scala/org/mongodb/scala/connection/TransportSettings.scala @@ -0,0 +1,34 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.mongodb.scala.connection + +import com.mongodb.connection.{ TransportSettings => JTransportSettings } + +/** + * An immutable class representing transport settings used for connections to a MongoDB server. + * + * @since 4.11 + */ +object TransportSettings { + + /** + * Creates a builder for NettyTransportSettings. + * + * @return a new Builder for creating NettyTransportSettings. + */ + def nettyBuilder(): NettyTransportSettings.Builder = JTransportSettings.nettyBuilder() +} diff --git a/driver-scala/src/main/scala/org/mongodb/scala/connection/package.scala b/driver-scala/src/main/scala/org/mongodb/scala/connection/package.scala index ab0d39d2778..7bdbef6a542 100644 --- a/driver-scala/src/main/scala/org/mongodb/scala/connection/package.scala +++ b/driver-scala/src/main/scala/org/mongodb/scala/connection/package.scala @@ -62,14 +62,30 @@ package object connection { */ type SslSettings = com.mongodb.connection.SslSettings + /** + * Transport settings for the driver. + * + * @since 4.11 + */ + type TransportSettings = com.mongodb.connection.TransportSettings + + /** + * TransportSettings for a Netty-based transport implementation. + * + * @since 4.11 + */ + type NettyTransportSettings = com.mongodb.connection.NettyTransportSettings + /** * The factory for streams. */ + @deprecated("For removal in 5.0", "4.11.0") type StreamFactory = com.mongodb.connection.StreamFactory /** * A factory of `StreamFactory` instances. */ + @deprecated("For removal in 5.0", "4.11.0") type StreamFactoryFactory = com.mongodb.connection.StreamFactoryFactory /** @@ -77,6 +93,7 @@ package object connection { * * @see java.nio.channels.AsynchronousSocketChannel */ + @deprecated("For removal in 5.0", "4.11.0") type AsynchronousSocketChannelStreamFactoryFactory = com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory @@ -86,6 +103,7 @@ package object connection { * @see java.nio.channels.AsynchronousSocketChannel * @since 2.2 */ + @deprecated("For removal in 5.0", "4.11.0") type AsynchronousSocketChannelStreamFactoryFactoryBuilder = com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory.Builder @@ -93,12 +111,14 @@ package object connection { * A `StreamFactoryFactory` implementation for Netty-based streams. * @since 2.2 */ + @deprecated("For removal in 5.0", "4.11.0") type NettyStreamFactoryFactory = com.mongodb.connection.netty.NettyStreamFactoryFactory /** * A `StreamFactoryFactory` builder for Netty-based streams. * @since 2.2 */ + @deprecated("For removal in 5.0", "4.11.0") type NettyStreamFactoryFactoryBuilder = com.mongodb.connection.netty.NettyStreamFactoryFactory.Builder /** @@ -106,5 +126,6 @@ package object connection { * * @since 2.6 */ + @deprecated("For removal in 5.0", "4.11.0") type TlsChannelStreamFactoryFactory = com.mongodb.connection.TlsChannelStreamFactoryFactory } diff --git a/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java b/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java index 5c884f66531..7fb1adcc146 100644 --- a/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java +++ b/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java @@ -54,6 +54,7 @@ import static com.mongodb.assertions.Assertions.notNull; import static com.mongodb.client.internal.Crypts.createCrypt; import static com.mongodb.internal.connection.ClientMetadataHelper.createClientMetadataDocument; +import static com.mongodb.internal.connection.StreamFactoryHelper.getStreamFactoryFactoryFromSettings; import static com.mongodb.internal.event.EventListenerHelper.getCommandListener; import static java.lang.String.format; import static org.bson.codecs.configuration.CodecRegistries.withUuidRepresentation; @@ -229,8 +230,9 @@ private static Cluster createCluster(final MongoClientSettings settings, settings.getDnsClient(), settings.getInetAddressResolver()); } + @SuppressWarnings("deprecation") private static StreamFactory getStreamFactory(final MongoClientSettings settings, final boolean isHeartbeat) { - StreamFactoryFactory streamFactoryFactory = settings.getStreamFactoryFactory(); + StreamFactoryFactory streamFactoryFactory = getStreamFactoryFactoryFromSettings(settings); SocketSettings socketSettings = isHeartbeat ? settings.getHeartbeatSocketSettings() : settings.getSocketSettings(); if (streamFactoryFactory == null) { return new SocketStreamFactory(socketSettings, settings.getSslSettings()); diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractUnifiedTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractUnifiedTest.java index 7b3d01e7666..c8b31ce2bb8 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/AbstractUnifiedTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractUnifiedTest.java @@ -92,6 +92,7 @@ import static org.junit.Assume.assumeTrue; @RunWith(Parameterized.class) +@SuppressWarnings("deprecation") public abstract class AbstractUnifiedTest { private final String filename; private final String description;