From 37b2edbabec1ee61746d9b9339a69c11feec23c8 Mon Sep 17 00:00:00 2001 From: Nabil Hachicha Date: Sat, 17 Jan 2026 19:15:23 +0000 Subject: [PATCH 1/3] Replace static recordEverything with instance-based InternalMongoClientSettings configuration --- .../connection/DefaultClusterFactory.java | 6 +- .../DefaultClusterableServerFactory.java | 14 +- .../InternalMongoClientSettings.java | 158 +++++++++++++++++ .../connection/InternalStreamConnection.java | 30 ++-- .../InternalStreamConnectionFactory.java | 11 +- .../LoadBalancedClusterableServerFactory.java | 12 +- .../com/mongodb/ClusterFixture.java | 6 +- .../CommandHelperSpecification.groovy | 5 +- .../connection/SingleServerClusterTest.java | 2 +- .../connection/TestCommandListener.java | 2 +- .../reactivestreams/client/MongoClients.java | 64 ++----- .../client/internal/InternalMongoClients.java | 163 ++++++++++++++++++ .../AbstractClientMetadataProseTest.java | 5 +- .../ClientSideOperationTimeoutProseTest.java | 11 ++ .../client/syncadapter/SyncMongoClient.java | 11 ++ .../internal/InternalMongoClientsTest.java | 53 ++++++ .../main/com/mongodb/client/MongoClients.java | 40 ++--- .../com/mongodb/client/internal/Clusters.java | 29 +++- .../client/internal/InternalMongoClients.java | 135 +++++++++++++++ .../client/internal/MongoClientImpl.java | 27 --- .../AbstractClientMetadataProseTest.java | 8 - ...tClientSideOperationsTimeoutProseTest.java | 28 +-- .../client/ClientMetadataProseTest.java | 5 +- .../ClientSideOperationTimeoutProseTest.java | 8 + .../OidcAuthenticationProseTests.java | 12 +- .../internal/InternalMongoClientsTest.java | 92 ++++++++++ 26 files changed, 753 insertions(+), 184 deletions(-) create mode 100644 driver-core/src/main/com/mongodb/internal/connection/InternalMongoClientSettings.java create mode 100644 driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/InternalMongoClients.java create mode 100644 driver-reactive-streams/src/test/unit/com/mongodb/reactivestreams/client/internal/InternalMongoClientsTest.java create mode 100644 driver-sync/src/main/com/mongodb/client/internal/InternalMongoClients.java create mode 100644 driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java 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 ac853cb002e..c42675f945e 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java @@ -60,7 +60,7 @@ public final class DefaultClusterFactory { public Cluster createCluster(final ClusterSettings originalClusterSettings, final ServerSettings originalServerSettings, final ConnectionPoolSettings connectionPoolSettings, - final InternalConnectionPoolSettings internalConnectionPoolSettings, + final InternalMongoClientSettings internalSettings, final TimeoutSettings clusterTimeoutSettings, final StreamFactory streamFactory, final TimeoutSettings heartbeatTimeoutSettings, @@ -113,12 +113,12 @@ public Cluster createCluster(final ClusterSettings originalClusterSettings, fina if (clusterSettings.getMode() == ClusterConnectionMode.LOAD_BALANCED) { ClusterableServerFactory serverFactory = new LoadBalancedClusterableServerFactory(serverSettings, - connectionPoolSettings, internalConnectionPoolSettings, streamFactory, credential, loggerSettings, commandListener, + connectionPoolSettings, internalSettings, streamFactory, credential, loggerSettings, commandListener, compressorList, serverApi, clusterOperationContextFactory); return new LoadBalancedCluster(clusterId, clusterSettings, serverFactory, clientMetadata, dnsSrvRecordMonitorFactory); } else { ClusterableServerFactory serverFactory = new DefaultClusterableServerFactory(serverSettings, - connectionPoolSettings, internalConnectionPoolSettings, + connectionPoolSettings, internalSettings, clusterOperationContextFactory, streamFactory, heartBeatOperationContextFactory, heartbeatStreamFactory, credential, loggerSettings, commandListener, compressorList, serverApi, FaasEnvironment.getFaasEnvironment() != FaasEnvironment.UNKNOWN); 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 cb9830c4017..6656947056a 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java @@ -41,7 +41,7 @@ public class DefaultClusterableServerFactory implements ClusterableServerFactory { private final ServerSettings serverSettings; private final ConnectionPoolSettings connectionPoolSettings; - private final InternalConnectionPoolSettings internalConnectionPoolSettings; + private final InternalMongoClientSettings internalSettings; private final InternalOperationContextFactory clusterOperationContextFactory; private final StreamFactory streamFactory; private final InternalOperationContextFactory heartbeatOperationContextFactory; @@ -56,7 +56,7 @@ public class DefaultClusterableServerFactory implements ClusterableServerFactory public DefaultClusterableServerFactory( final ServerSettings serverSettings, final ConnectionPoolSettings connectionPoolSettings, - final InternalConnectionPoolSettings internalConnectionPoolSettings, + final InternalMongoClientSettings internalSettings, final InternalOperationContextFactory clusterOperationContextFactory, final StreamFactory streamFactory, final InternalOperationContextFactory heartbeatOperationContextFactory, final StreamFactory heartbeatStreamFactory, @Nullable final MongoCredential credential, final LoggerSettings loggerSettings, @@ -64,7 +64,7 @@ public DefaultClusterableServerFactory( final List compressorList, @Nullable final ServerApi serverApi, final boolean isFunctionAsAServiceEnvironment) { this.serverSettings = serverSettings; this.connectionPoolSettings = connectionPoolSettings; - this.internalConnectionPoolSettings = internalConnectionPoolSettings; + this.internalSettings = internalSettings; this.clusterOperationContextFactory = clusterOperationContextFactory; this.streamFactory = streamFactory; this.heartbeatOperationContextFactory = heartbeatOperationContextFactory; @@ -87,13 +87,13 @@ public ClusterableServer create(final Cluster cluster, final ServerAddress serve ServerMonitor serverMonitor = new DefaultServerMonitor(serverId, serverSettings, // no credentials, compressor list, or command listener for the server monitor factory new InternalStreamConnectionFactory(clusterMode, true, heartbeatStreamFactory, null, clientMetadata, - emptyList(), loggerSettings, null, serverApi), + emptyList(), loggerSettings, null, serverApi, internalSettings.isRecordEverything()), clusterMode, serverApi, isFunctionAsAServiceEnvironment, sdamProvider, heartbeatOperationContextFactory); ConnectionPool connectionPool = new DefaultConnectionPool(serverId, - new InternalStreamConnectionFactory(clusterMode, streamFactory, credential, clientMetadata, - compressorList, loggerSettings, commandListener, serverApi), - connectionPoolSettings, internalConnectionPoolSettings, sdamProvider, clusterOperationContextFactory); + new InternalStreamConnectionFactory(clusterMode, false, streamFactory, credential, clientMetadata, + compressorList, loggerSettings, commandListener, serverApi, internalSettings.isRecordEverything()), + connectionPoolSettings, internalSettings.getInternalConnectionPoolSettings(), sdamProvider, clusterOperationContextFactory); ServerListener serverListener = singleServerListener(serverSettings); SdamServerDescriptionManager sdam = new DefaultSdamServerDescriptionManager(cluster, serverId, serverListener, serverMonitor, connectionPool, clusterMode); diff --git a/driver-core/src/main/com/mongodb/internal/connection/InternalMongoClientSettings.java b/driver-core/src/main/com/mongodb/internal/connection/InternalMongoClientSettings.java new file mode 100644 index 00000000000..dd685d8c5dd --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/connection/InternalMongoClientSettings.java @@ -0,0 +1,158 @@ +/* + * 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.annotations.Immutable; + +import java.util.Objects; + +/** + * Internal settings for MongoClient that are not part of the public API. + * Used for testing and internal configuration purposes. + * + *

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

+ */ +@Immutable +public final class InternalMongoClientSettings { + + private static final InternalMongoClientSettings DEFAULTS = builder().build(); + + private final InternalConnectionPoolSettings internalConnectionPoolSettings; + private final boolean recordEverything; + + private InternalMongoClientSettings(final Builder builder) { + this.internalConnectionPoolSettings = builder.internalConnectionPoolSettings != null + ? builder.internalConnectionPoolSettings + : InternalConnectionPoolSettings.builder().build(); + this.recordEverything = builder.recordEverything; + } + + /** + * Gets the default internal settings for production use. + * + * @return the default settings + */ + public static InternalMongoClientSettings getDefaults() { + return DEFAULTS; + } + + /** + * Creates a new builder for InternalMongoClientSettings. + * + * @return the builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Gets the internal connection pool settings. + * + * @return the internal connection pool settings + */ + public InternalConnectionPoolSettings getInternalConnectionPoolSettings() { + return internalConnectionPoolSettings; + } + + /** + * Indicates whether to record all commands including security-sensitive commands + * (like authentication commands) to the command listener. + *

+ * When disabled (the default for production), security-sensitive commands are not recorded + * to the command listener for security reasons. When enabled, all commands are recorded, + * which is useful for testing authentication and handshake behavior. + *

+ * + * @return true if all commands should be recorded + */ + public boolean isRecordEverything() { + return recordEverything; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + InternalMongoClientSettings that = (InternalMongoClientSettings) o; + return recordEverything == that.recordEverything + && Objects.equals(internalConnectionPoolSettings, that.internalConnectionPoolSettings); + } + + @Override + public int hashCode() { + return Objects.hash(internalConnectionPoolSettings, recordEverything); + } + + @Override + public String toString() { + return "InternalMongoClientSettings{" + + "internalConnectionPoolSettings=" + internalConnectionPoolSettings + + ", recordEverything=" + recordEverything + + '}'; + } + + /** + * A builder for InternalMongoClientSettings. + */ + public static final class Builder { + private InternalConnectionPoolSettings internalConnectionPoolSettings = InternalConnectionPoolSettings.builder().build(); + private boolean recordEverything = false; + + private Builder() { + } + + /** + * Sets the internal connection pool settings. + * + * @param internalConnectionPoolSettings the internal connection pool settings + * @return this + */ + public Builder internalConnectionPoolSettings( + final InternalConnectionPoolSettings internalConnectionPoolSettings) { + this.internalConnectionPoolSettings = internalConnectionPoolSettings; + return this; + } + + /** + * Sets whether to record all commands including security-sensitive commands. + *

+ * Default is {@code false} for production use. Set to {@code true} for testing + * authentication and handshake behavior. + *

+ * + * @param recordEverything whether to record all commands + * @return this + */ + public Builder recordEverything(final boolean recordEverything) { + this.recordEverything = recordEverything; + return this; + } + + /** + * Builds the InternalMongoClientSettings. + * + * @return the internal settings + */ + public InternalMongoClientSettings build() { + return new InternalMongoClientSettings(this); + } + } +} + 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 6b20c467191..a466753a84b 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnection.java +++ b/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnection.java @@ -105,19 +105,6 @@ @NotThreadSafe public class InternalStreamConnection implements InternalConnection { - private static volatile boolean recordEverything = false; - - /** - * Will attempt to record events to the command listener that are usually - * suppressed. - * - * @param recordEverything whether to attempt to record everything - */ - @VisibleForTesting(otherwise = VisibleForTesting.AccessModifier.PRIVATE) - public static void setRecordEverything(final boolean recordEverything) { - InternalStreamConnection.recordEverything = recordEverything; - } - private static final Set SECURITY_SENSITIVE_COMMANDS = new HashSet<>(asList( "authenticate", "saslStart", @@ -160,6 +147,7 @@ public static void setRecordEverything(final boolean recordEverything) { private volatile boolean hasMoreToCome; private volatile int responseTo; private int generation = NOT_INITIALIZED_GENERATION; + private final boolean recordEverything; // Package-level access provided to avoid duplicating the list in test code static Set getSecuritySensitiveCommands() { @@ -177,7 +165,7 @@ public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMod final StreamFactory streamFactory, final List compressorList, final CommandListener commandListener, final InternalConnectionInitializer connectionInitializer) { this(clusterConnectionMode, null, false, serverId, connectionGenerationSupplier, streamFactory, compressorList, - LoggerSettings.builder().build(), commandListener, connectionInitializer); + LoggerSettings.builder().build(), commandListener, connectionInitializer, false); } public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMode, @@ -188,6 +176,19 @@ public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMod final StreamFactory streamFactory, final List compressorList, final LoggerSettings loggerSettings, final CommandListener commandListener, final InternalConnectionInitializer connectionInitializer) { + this(clusterConnectionMode, authenticator, isMonitoringConnection, serverId, connectionGenerationSupplier, + streamFactory, compressorList, loggerSettings, commandListener, connectionInitializer, false); + } + + public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMode, + @Nullable final Authenticator authenticator, + final boolean isMonitoringConnection, + final ServerId serverId, + final ConnectionGenerationSupplier connectionGenerationSupplier, + final StreamFactory streamFactory, final List compressorList, + final LoggerSettings loggerSettings, + final CommandListener commandListener, final InternalConnectionInitializer connectionInitializer, + final boolean recordEverything) { this.clusterConnectionMode = clusterConnectionMode; this.authenticator = authenticator; this.isMonitoringConnection = isMonitoringConnection; @@ -199,6 +200,7 @@ public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMod this.loggerSettings = loggerSettings; this.commandListener = commandListener; this.connectionInitializer = notNull("connectionInitializer", connectionInitializer); + this.recordEverything = recordEverything; description = new ConnectionDescription(serverId); initialServerDescription = ServerDescription.builder() .address(serverId.getAddress()) 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 252d62c35f8..4163833f45b 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnectionFactory.java @@ -40,6 +40,7 @@ class InternalStreamConnectionFactory implements InternalConnectionFactory { @Nullable private final ServerApi serverApi; private final MongoCredentialWithCache credential; + private final boolean recordEverything; InternalStreamConnectionFactory(final ClusterConnectionMode clusterConnectionMode, final StreamFactory streamFactory, @@ -49,15 +50,16 @@ class InternalStreamConnectionFactory implements InternalConnectionFactory { final LoggerSettings loggerSettings, @Nullable final CommandListener commandListener, @Nullable final ServerApi serverApi) { this(clusterConnectionMode, false, streamFactory, credential, clientMetadata, compressorList, - loggerSettings, commandListener, serverApi); + loggerSettings, commandListener, serverApi, false); } InternalStreamConnectionFactory(final ClusterConnectionMode clusterConnectionMode, final boolean isMonitoringConnection, final StreamFactory streamFactory, @Nullable final MongoCredentialWithCache credential, final ClientMetadata clientMetadata, - final List compressorList, - final LoggerSettings loggerSettings, @Nullable final CommandListener commandListener, @Nullable final ServerApi serverApi) { + final List compressorList, + final LoggerSettings loggerSettings, @Nullable final CommandListener commandListener, + @Nullable final ServerApi serverApi, final boolean recordEverything) { this.clusterConnectionMode = clusterConnectionMode; this.isMonitoringConnection = isMonitoringConnection; this.streamFactory = notNull("streamFactory", streamFactory); @@ -67,6 +69,7 @@ class InternalStreamConnectionFactory implements InternalConnectionFactory { this.serverApi = serverApi; this.clientMetadata = clientMetadata; this.credential = credential; + this.recordEverything = recordEverything; } @Override @@ -78,7 +81,7 @@ public InternalConnection create(final ServerId serverId, final ConnectionGenera clusterConnectionMode, authenticator, isMonitoringConnection, serverId, connectionGenerationSupplier, streamFactory, compressorList, loggerSettings, commandListener, - connectionInitializer); + connectionInitializer, recordEverything); } private Authenticator createAuthenticator(final MongoCredentialWithCache credential) { 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 296240cf39f..6e8561902ac 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java @@ -41,7 +41,7 @@ public class LoadBalancedClusterableServerFactory implements ClusterableServerFactory { private final ServerSettings serverSettings; private final ConnectionPoolSettings connectionPoolSettings; - private final InternalConnectionPoolSettings internalConnectionPoolSettings; + private final InternalMongoClientSettings internalSettings; private final StreamFactory streamFactory; private final MongoCredentialWithCache credential; private final LoggerSettings loggerSettings; @@ -52,7 +52,7 @@ public class LoadBalancedClusterableServerFactory implements ClusterableServerFa public LoadBalancedClusterableServerFactory(final ServerSettings serverSettings, final ConnectionPoolSettings connectionPoolSettings, - final InternalConnectionPoolSettings internalConnectionPoolSettings, + final InternalMongoClientSettings internalSettings, final StreamFactory streamFactory, @Nullable final MongoCredential credential, final LoggerSettings loggerSettings, @Nullable final CommandListener commandListener, @@ -60,7 +60,7 @@ public LoadBalancedClusterableServerFactory(final ServerSettings serverSettings, final InternalOperationContextFactory operationContextFactory) { this.serverSettings = serverSettings; this.connectionPoolSettings = connectionPoolSettings; - this.internalConnectionPoolSettings = internalConnectionPoolSettings; + this.internalSettings = internalSettings; this.streamFactory = streamFactory; this.credential = credential == null ? null : new MongoCredentialWithCache(credential); this.loggerSettings = loggerSettings; @@ -73,9 +73,9 @@ public LoadBalancedClusterableServerFactory(final ServerSettings serverSettings, @Override public ClusterableServer create(final Cluster cluster, final ServerAddress serverAddress) { ConnectionPool connectionPool = new DefaultConnectionPool(new ServerId(cluster.getClusterId(), serverAddress), - new InternalStreamConnectionFactory(ClusterConnectionMode.LOAD_BALANCED, streamFactory, credential, cluster.getClientMetadata(), - compressorList, loggerSettings, commandListener, serverApi), - connectionPoolSettings, internalConnectionPoolSettings, EmptyProvider.instance(), operationContextFactory); + new InternalStreamConnectionFactory(ClusterConnectionMode.LOAD_BALANCED, false, streamFactory, credential, cluster.getClientMetadata(), + compressorList, loggerSettings, commandListener, serverApi, internalSettings.isRecordEverything()), + connectionPoolSettings, internalSettings.getInternalConnectionPoolSettings(), EmptyProvider.instance(), operationContextFactory); connectionPool.ready(); return new LoadBalancedServer(new ServerId(cluster.getClusterId(), serverAddress), connectionPool, new DefaultConnectionFactory(), diff --git a/driver-core/src/test/functional/com/mongodb/ClusterFixture.java b/driver-core/src/test/functional/com/mongodb/ClusterFixture.java index 1a5bead6207..c56a17283ea 100644 --- a/driver-core/src/test/functional/com/mongodb/ClusterFixture.java +++ b/driver-core/src/test/functional/com/mongodb/ClusterFixture.java @@ -52,7 +52,7 @@ import com.mongodb.internal.connection.Cluster; import com.mongodb.internal.connection.DefaultClusterFactory; import com.mongodb.internal.connection.DefaultInetAddressResolver; -import com.mongodb.internal.connection.InternalConnectionPoolSettings; +import com.mongodb.internal.connection.InternalMongoClientSettings; import com.mongodb.internal.connection.InternalOperationContextFactory; import com.mongodb.internal.connection.MongoCredentialWithCache; import com.mongodb.internal.connection.OperationContext; @@ -478,7 +478,7 @@ public static Cluster createAsyncCluster(final MongoCredential credential) { private static Cluster createCluster(final MongoCredential credential, final StreamFactory streamFactory) { return new DefaultClusterFactory().createCluster(ClusterSettings.builder().hosts(asList(getPrimary())).build(), ServerSettings.builder().build(), - ConnectionPoolSettings.builder().maxSize(1).build(), InternalConnectionPoolSettings.builder().build(), + ConnectionPoolSettings.builder().maxSize(1).build(), InternalMongoClientSettings.getDefaults(), TIMEOUT_SETTINGS.connectionOnly(), streamFactory, TIMEOUT_SETTINGS.connectionOnly(), streamFactory, credential, LoggerSettings.builder().build(), null, null, null, Collections.emptyList(), getServerApi(), null); } @@ -488,7 +488,7 @@ private static Cluster createCluster(final ConnectionString connectionString, fi return new DefaultClusterFactory().createCluster(mongoClientSettings.getClusterSettings(), mongoClientSettings.getServerSettings(), mongoClientSettings.getConnectionPoolSettings(), - InternalConnectionPoolSettings.builder().build(), TimeoutSettings.create(mongoClientSettings).connectionOnly(), + InternalMongoClientSettings.getDefaults(), TimeoutSettings.create(mongoClientSettings).connectionOnly(), streamFactory, TimeoutSettings.createHeartbeatSettings(mongoClientSettings).connectionOnly(), new SocketStreamFactory(new DefaultInetAddressResolver(), SocketSettings.builder().readTimeout(5, SECONDS).build(), getSslSettings(connectionString)), diff --git a/driver-core/src/test/functional/com/mongodb/internal/connection/CommandHelperSpecification.groovy b/driver-core/src/test/functional/com/mongodb/internal/connection/CommandHelperSpecification.groovy index 2d7dc04d758..7f76f8ab563 100644 --- a/driver-core/src/test/functional/com/mongodb/internal/connection/CommandHelperSpecification.groovy +++ b/driver-core/src/test/functional/com/mongodb/internal/connection/CommandHelperSpecification.groovy @@ -43,10 +43,9 @@ class CommandHelperSpecification extends Specification { InternalConnection connection def setup() { - InternalStreamConnection.setRecordEverything(true) - connection = new InternalStreamConnectionFactory(ClusterConnectionMode.SINGLE, + connection = new InternalStreamConnectionFactory(ClusterConnectionMode.SINGLE, false, new NettyStreamFactory(SocketSettings.builder().build(), getSslSettings()), - getCredentialWithCache(), CLIENT_METADATA, [], LoggerSettings.builder().build(), null, getServerApi()) + getCredentialWithCache(), CLIENT_METADATA, [], LoggerSettings.builder().build(), null, getServerApi(), true) .create(new ServerId(new ClusterId(), getPrimary())) connection.open(OPERATION_CONTEXT) } 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 62fa6c27032..0f1c9571de6 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 @@ -66,7 +66,7 @@ private void setUpCluster(final ServerAddress serverAddress) { cluster = new SingleServerCluster(clusterId, clusterSettings, new DefaultClusterableServerFactory(ServerSettings.builder().build(), - ConnectionPoolSettings.builder().maxSize(1).build(), InternalConnectionPoolSettings.builder().build(), + ConnectionPoolSettings.builder().maxSize(1).build(), InternalMongoClientSettings.getDefaults(), OPERATION_CONTEXT_FACTORY, streamFactory, OPERATION_CONTEXT_FACTORY, streamFactory, getCredential(), LoggerSettings.builder().build(), null, Collections.emptyList(), getServerApi(), false), CLIENT_METADATA); diff --git a/driver-core/src/test/functional/com/mongodb/internal/connection/TestCommandListener.java b/driver-core/src/test/functional/com/mongodb/internal/connection/TestCommandListener.java index 9381ad842a1..5b4b1de26c6 100644 --- a/driver-core/src/test/functional/com/mongodb/internal/connection/TestCommandListener.java +++ b/driver-core/src/test/functional/com/mongodb/internal/connection/TestCommandListener.java @@ -90,7 +90,7 @@ public Codec get(final Class clazz, final CodecRegistry registry) { * type will be lowercase and will omit the terms "command" and "event". * For example: {@code "saslContinue succeeded"}. * - * @see InternalStreamConnection#setRecordEverything(boolean) + * @see InternalMongoClientSettings.Builder#recordEverything(boolean) * @param listener the test listener */ public TestCommandListener(final TestListener listener) { 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 57ee076039e..99a5815f940 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 @@ -17,26 +17,13 @@ package com.mongodb.reactivestreams.client; import com.mongodb.ConnectionString; -import com.mongodb.MongoClientException; import com.mongodb.MongoClientSettings; import com.mongodb.MongoDriverInformation; -import com.mongodb.connection.SocketSettings; -import com.mongodb.internal.TimeoutSettings; -import com.mongodb.internal.connection.Cluster; -import com.mongodb.internal.connection.DefaultClusterFactory; -import com.mongodb.internal.connection.InternalConnectionPoolSettings; -import com.mongodb.internal.connection.StreamFactory; -import com.mongodb.internal.connection.StreamFactoryFactory; +import com.mongodb.internal.connection.InternalMongoClientSettings; import com.mongodb.lang.Nullable; -import com.mongodb.reactivestreams.client.internal.MongoClientImpl; -import com.mongodb.spi.dns.InetAddressResolver; +import com.mongodb.reactivestreams.client.internal.InternalMongoClients; import org.bson.codecs.configuration.CodecRegistry; -import static com.mongodb.assertions.Assertions.notNull; -import static com.mongodb.internal.connection.ServerAddressHelper.getInetAddressResolver; -import static com.mongodb.internal.connection.StreamFactoryHelper.getAsyncStreamFactoryFactory; -import static com.mongodb.internal.event.EventListenerHelper.getCommandListener; - /** * A factory for MongoClient instances. @@ -44,13 +31,15 @@ */ public final class MongoClients { + private static final InternalMongoClientSettings DEFAULT_INTERNAL_SETTINGS = InternalMongoClientSettings.getDefaults(); + /** * Creates a new client with the default connection string "mongodb://localhost". * * @return the client */ public static MongoClient create() { - return create(new ConnectionString("mongodb://localhost")); + return InternalMongoClients.create(DEFAULT_INTERNAL_SETTINGS); } /** @@ -60,7 +49,7 @@ public static MongoClient create() { * @return the client */ public static MongoClient create(final String connectionString) { - return create(new ConnectionString(connectionString)); + return InternalMongoClients.create(connectionString, DEFAULT_INTERNAL_SETTINGS); } /** @@ -70,7 +59,7 @@ public static MongoClient create(final String connectionString) { * @return the client */ public static MongoClient create(final ConnectionString connectionString) { - return create(connectionString, null); + return InternalMongoClients.create(connectionString, DEFAULT_INTERNAL_SETTINGS); } /** @@ -85,7 +74,7 @@ public static MongoClient create(final ConnectionString connectionString) { */ public static MongoClient create(final ConnectionString connectionString, @Nullable final MongoDriverInformation mongoDriverInformation) { - return create(MongoClientSettings.builder().applyConnectionString(connectionString).build(), mongoDriverInformation); + return InternalMongoClients.create(connectionString, mongoDriverInformation, DEFAULT_INTERNAL_SETTINGS); } /** @@ -96,7 +85,7 @@ public static MongoClient create(final ConnectionString connectionString, * @since 1.8 */ public static MongoClient create(final MongoClientSettings settings) { - return create(settings, null); + return InternalMongoClients.create(settings, DEFAULT_INTERNAL_SETTINGS); } /** @@ -110,16 +99,7 @@ public static MongoClient create(final MongoClientSettings settings) { * @since 1.8 */ 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"); - } - InetAddressResolver inetAddressResolver = getInetAddressResolver(settings); - StreamFactoryFactory streamFactoryFactory = getAsyncStreamFactoryFactory(settings, inetAddressResolver); - StreamFactory streamFactory = getStreamFactory(streamFactoryFactory, settings, false); - StreamFactory heartbeatStreamFactory = getStreamFactory(streamFactoryFactory, settings, true); - MongoDriverInformation wrappedMongoDriverInformation = wrapMongoDriverInformation(mongoDriverInformation); - Cluster cluster = createCluster(settings, wrappedMongoDriverInformation, streamFactory, heartbeatStreamFactory); - return new MongoClientImpl(settings, wrappedMongoDriverInformation, cluster, streamFactoryFactory); + return InternalMongoClients.create(settings, mongoDriverInformation, DEFAULT_INTERNAL_SETTINGS); } /** @@ -133,30 +113,6 @@ public static CodecRegistry getDefaultCodecRegistry() { return MongoClientSettings.getDefaultCodecRegistry(); } - private static Cluster createCluster(final MongoClientSettings settings, - @Nullable final MongoDriverInformation mongoDriverInformation, - final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory) { - notNull("settings", settings); - return new DefaultClusterFactory().createCluster(settings.getClusterSettings(), settings.getServerSettings(), - settings.getConnectionPoolSettings(), InternalConnectionPoolSettings.builder().prestartAsyncWorkManager(true).build(), - TimeoutSettings.create(settings), streamFactory, TimeoutSettings.createHeartbeatSettings(settings), heartbeatStreamFactory, - settings.getCredential(), settings.getLoggerSettings(), getCommandListener(settings.getCommandListeners()), - settings.getApplicationName(), mongoDriverInformation, settings.getCompressorList(), settings.getServerApi(), - settings.getDnsClient()); - } - - private static MongoDriverInformation wrapMongoDriverInformation(@Nullable final MongoDriverInformation mongoDriverInformation) { - return (mongoDriverInformation == null ? MongoDriverInformation.builder() : MongoDriverInformation.builder(mongoDriverInformation)) - .driverName("reactive-streams").build(); - } - - private static StreamFactory getStreamFactory( - final StreamFactoryFactory streamFactoryFactory, final MongoClientSettings settings, - final boolean isHeartbeat) { - SocketSettings socketSettings = isHeartbeat - ? settings.getHeartbeatSocketSettings() : settings.getSocketSettings(); - return streamFactoryFactory.create(socketSettings, settings.getSslSettings()); - } private MongoClients() { } diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/InternalMongoClients.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/InternalMongoClients.java new file mode 100644 index 00000000000..c1f34ad7c94 --- /dev/null +++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/InternalMongoClients.java @@ -0,0 +1,163 @@ +/* + * 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.reactivestreams.client.internal; + +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientException; +import com.mongodb.MongoClientSettings; +import com.mongodb.MongoDriverInformation; +import com.mongodb.connection.SocketSettings; +import com.mongodb.internal.TimeoutSettings; +import com.mongodb.internal.connection.Cluster; +import com.mongodb.internal.connection.DefaultClusterFactory; +import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.connection.StreamFactory; +import com.mongodb.internal.connection.StreamFactoryFactory; +import com.mongodb.lang.Nullable; +import com.mongodb.reactivestreams.client.MongoClient; +import com.mongodb.spi.dns.InetAddressResolver; + +import static com.mongodb.assertions.Assertions.notNull; +import static com.mongodb.internal.connection.ServerAddressHelper.getInetAddressResolver; +import static com.mongodb.internal.connection.StreamFactoryHelper.getAsyncStreamFactoryFactory; +import static com.mongodb.internal.event.EventListenerHelper.getCommandListener; + +/** + * Internal factory for MongoClient instances. + * + *

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

+ */ +public final class InternalMongoClients { + + private InternalMongoClients() { + } + + /** + * Creates a new client with the default connection string "mongodb://localhost" and the given internal settings. + * + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final InternalMongoClientSettings internalSettings) { + return create(new ConnectionString("mongodb://localhost"), internalSettings); + } + + /** + * Creates a new client with the given connection string and internal settings. + * + * @param connectionString the connection string + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final String connectionString, + final InternalMongoClientSettings internalSettings) { + return create(new ConnectionString(connectionString), internalSettings); + } + + /** + * Creates a new client with the given connection string and internal settings. + * + * @param connectionString the connection string + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final ConnectionString connectionString, + final InternalMongoClientSettings internalSettings) { + return create(connectionString, null, internalSettings); + } + + /** + * Creates a new client with the given connection string, driver information and internal settings. + * + * @param connectionString the connection string + * @param mongoDriverInformation any driver information to associate with the MongoClient + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final ConnectionString connectionString, + @Nullable final MongoDriverInformation mongoDriverInformation, + final InternalMongoClientSettings internalSettings) { + return create(MongoClientSettings.builder().applyConnectionString(connectionString).build(), + mongoDriverInformation, internalSettings); + } + + /** + * Creates a new client with the given client settings and internal settings. + * + * @param settings the public settings + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final MongoClientSettings settings, + final InternalMongoClientSettings internalSettings) { + return create(settings, null, internalSettings); + } + + /** + * Creates a new client with the given client settings, driver information and internal settings. + * + * @param settings the public settings + * @param mongoDriverInformation any driver information to associate with the MongoClient + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final MongoClientSettings settings, + @Nullable final MongoDriverInformation mongoDriverInformation, + final InternalMongoClientSettings internalSettings) { + notNull("settings", settings); + notNull("internalSettings", internalSettings); + + if (settings.getSocketSettings().getProxySettings().isProxyEnabled()) { + throw new MongoClientException("Proxy is not supported for reactive clients"); + } + InetAddressResolver inetAddressResolver = getInetAddressResolver(settings); + StreamFactoryFactory streamFactoryFactory = getAsyncStreamFactoryFactory(settings, inetAddressResolver); + StreamFactory streamFactory = getStreamFactory(streamFactoryFactory, settings, false); + StreamFactory heartbeatStreamFactory = getStreamFactory(streamFactoryFactory, settings, true); + MongoDriverInformation wrappedMongoDriverInformation = wrapMongoDriverInformation(mongoDriverInformation); + Cluster cluster = createCluster(settings, wrappedMongoDriverInformation, streamFactory, heartbeatStreamFactory, internalSettings); + return new MongoClientImpl(settings, wrappedMongoDriverInformation, cluster, streamFactoryFactory); + } + + private static Cluster createCluster(final MongoClientSettings settings, + @Nullable final MongoDriverInformation mongoDriverInformation, + final StreamFactory streamFactory, + final StreamFactory heartbeatStreamFactory, + final InternalMongoClientSettings internalSettings) { + notNull("settings", settings); + return new DefaultClusterFactory().createCluster(settings.getClusterSettings(), settings.getServerSettings(), + settings.getConnectionPoolSettings(), internalSettings, + TimeoutSettings.create(settings), streamFactory, TimeoutSettings.createHeartbeatSettings(settings), heartbeatStreamFactory, + settings.getCredential(), settings.getLoggerSettings(), getCommandListener(settings.getCommandListeners()), + settings.getApplicationName(), mongoDriverInformation, settings.getCompressorList(), settings.getServerApi(), + settings.getDnsClient()); + } + + private static MongoDriverInformation wrapMongoDriverInformation(@Nullable final MongoDriverInformation mongoDriverInformation) { + return (mongoDriverInformation == null ? MongoDriverInformation.builder() : MongoDriverInformation.builder(mongoDriverInformation)) + .driverName("reactive-streams").build(); + } + + private static StreamFactory getStreamFactory( + final StreamFactoryFactory streamFactoryFactory, final MongoClientSettings settings, + final boolean isHeartbeat) { + SocketSettings socketSettings = isHeartbeat + ? settings.getHeartbeatSocketSettings() : settings.getSocketSettings(); + return streamFactoryFactory.create(socketSettings, settings.getSslSettings()); + } +} + diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/AbstractClientMetadataProseTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/AbstractClientMetadataProseTest.java index 8aa4db32e79..cc84fb9b948 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/AbstractClientMetadataProseTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/AbstractClientMetadataProseTest.java @@ -20,7 +20,9 @@ import com.mongodb.MongoDriverInformation; import com.mongodb.client.AbstractClientMetadataProseTest; import com.mongodb.client.MongoClient; +import com.mongodb.internal.connection.InternalMongoClientSettings; import com.mongodb.lang.Nullable; +import com.mongodb.reactivestreams.client.internal.InternalMongoClients; import com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient; /** @@ -29,6 +31,7 @@ class ClientMetadataProseTest extends AbstractClientMetadataProseTest { protected MongoClient createMongoClient(@Nullable final MongoDriverInformation mongoDriverInformation, final MongoClientSettings mongoClientSettings) { - return new SyncMongoClient(mongoClientSettings, mongoDriverInformation); + return new SyncMongoClient(InternalMongoClients.create(mongoClientSettings, mongoDriverInformation, + InternalMongoClientSettings.builder().recordEverything(true).build())); } } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java index b922ec20b71..f7f92a0cded 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java @@ -28,8 +28,10 @@ import com.mongodb.client.model.changestream.FullDocument; import com.mongodb.event.CommandFailedEvent; import com.mongodb.event.CommandStartedEvent; +import com.mongodb.internal.connection.InternalMongoClientSettings; import com.mongodb.reactivestreams.client.gridfs.GridFSBucket; import com.mongodb.reactivestreams.client.gridfs.GridFSBuckets; +import com.mongodb.reactivestreams.client.internal.InternalMongoClients; import com.mongodb.reactivestreams.client.syncadapter.SyncGridFSBucket; import com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient; import org.bson.BsonDocument; @@ -80,6 +82,15 @@ protected com.mongodb.client.MongoClient createMongoClient(final MongoClientSett return client; } + @Override + protected com.mongodb.client.MongoClient createMongoClientWithInternalSettings(final MongoClientSettings mongoClientSettings, + final InternalMongoClientSettings internalSettings) { + MongoClient reactiveClient = InternalMongoClients.create(mongoClientSettings, null, internalSettings); + SyncMongoClient client = new SyncMongoClient(reactiveClient); + wrapped = reactiveClient; + return client; + } + private static MongoClient createReactiveClient(final MongoClientSettings.Builder builder) { return MongoClients.create(builder.build()); } diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoClient.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoClient.java index 348bef110ff..59e912edc7f 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoClient.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/syncadapter/SyncMongoClient.java @@ -158,6 +158,17 @@ public SyncMongoClient(final MongoClientSettings.Builder builder, @Nullable fina this.delegate = new SyncMongoCluster(wrapped); } + /** + * Wraps an existing reactive MongoClient as a sync client adapter. + * + * @param reactiveMongoClient the reactive MongoClient to wrap + */ + public SyncMongoClient(final com.mongodb.reactivestreams.client.MongoClient reactiveMongoClient) { + this.connectionPoolCounter = new ConnectionPoolCounter(); + this.wrapped = reactiveMongoClient; + this.delegate = new SyncMongoCluster(wrapped); + } + public com.mongodb.reactivestreams.client.MongoClient getWrapped() { return wrapped; } diff --git a/driver-reactive-streams/src/test/unit/com/mongodb/reactivestreams/client/internal/InternalMongoClientsTest.java b/driver-reactive-streams/src/test/unit/com/mongodb/reactivestreams/client/internal/InternalMongoClientsTest.java new file mode 100644 index 00000000000..b21a9157d77 --- /dev/null +++ b/driver-reactive-streams/src/test/unit/com/mongodb/reactivestreams/client/internal/InternalMongoClientsTest.java @@ -0,0 +1,53 @@ +/* + * 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.reactivestreams.client.internal; + +import com.mongodb.MongoClientSettings; +import com.mongodb.internal.connection.InternalMongoClientSettings; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Unit tests for reactive {@link InternalMongoClients}. + * See sync InternalMongoClientsTest for comprehensive InternalMongoClientSettings tests. + */ +class InternalMongoClientsTest { + + @Test + void testCreateMethodsValidateNullSettings() { + // Verify that null MongoClientSettings is rejected + assertThrows(IllegalArgumentException.class, () -> + InternalMongoClients.create((MongoClientSettings) null, InternalMongoClientSettings.getDefaults())); + + // Verify that null InternalMongoClientSettings is rejected + MongoClientSettings settings = MongoClientSettings.builder().build(); + assertThrows(IllegalArgumentException.class, () -> + InternalMongoClients.create(settings, null)); + } + + @Test + void testInternalSettingsArePreserved() { + // Verify that InternalMongoClientSettings can be built with recordEverything for reactive clients + InternalMongoClientSettings internalSettings = InternalMongoClientSettings.builder() + .recordEverything(true) + .build(); + assertNotNull(internalSettings); + } +} + diff --git a/driver-sync/src/main/com/mongodb/client/MongoClients.java b/driver-sync/src/main/com/mongodb/client/MongoClients.java index e0e59ba5f78..3ecd2026803 100644 --- a/driver-sync/src/main/com/mongodb/client/MongoClients.java +++ b/driver-sync/src/main/com/mongodb/client/MongoClients.java @@ -19,16 +19,10 @@ import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; import com.mongodb.MongoDriverInformation; -import com.mongodb.client.internal.Clusters; -import com.mongodb.client.internal.MongoClientImpl; -import com.mongodb.internal.connection.Cluster; -import com.mongodb.internal.connection.StreamFactoryFactory; +import com.mongodb.client.internal.InternalMongoClients; +import com.mongodb.internal.connection.InternalMongoClientSettings; import com.mongodb.lang.Nullable; -import static com.mongodb.assertions.Assertions.notNull; -import static com.mongodb.internal.connection.ServerAddressHelper.getInetAddressResolver; -import static com.mongodb.internal.connection.StreamFactoryHelper.getSyncStreamFactoryFactory; - /** * A factory for {@link MongoClient} instances. Use of this class is now the recommended way to connect to MongoDB via the Java driver. @@ -38,13 +32,15 @@ */ public final class MongoClients { + private static final InternalMongoClientSettings DEFAULT_INTERNAL_SETTINGS = InternalMongoClientSettings.getDefaults(); + /** * Creates a new client with the default connection string "mongodb://localhost". * * @return the client */ public static MongoClient create() { - return create(new ConnectionString("mongodb://localhost")); + return InternalMongoClients.create(DEFAULT_INTERNAL_SETTINGS); } /** @@ -54,7 +50,7 @@ public static MongoClient create() { * @return the client */ public static MongoClient create(final MongoClientSettings settings) { - return create(settings, null); + return InternalMongoClients.create(settings, DEFAULT_INTERNAL_SETTINGS); } /** @@ -65,7 +61,7 @@ public static MongoClient create(final MongoClientSettings settings) { * @see #create(ConnectionString) */ public static MongoClient create(final String connectionString) { - return create(new ConnectionString(connectionString)); + return InternalMongoClients.create(connectionString, DEFAULT_INTERNAL_SETTINGS); } /** @@ -82,7 +78,7 @@ public static MongoClient create(final String connectionString) { * @see com.mongodb.MongoClientSettings.Builder#applyConnectionString(ConnectionString) */ public static MongoClient create(final ConnectionString connectionString) { - return create(connectionString, null); + return InternalMongoClients.create(connectionString, DEFAULT_INTERNAL_SETTINGS); } /** @@ -97,7 +93,7 @@ public static MongoClient create(final ConnectionString connectionString) { */ public static MongoClient create(final ConnectionString connectionString, @Nullable final MongoDriverInformation mongoDriverInformation) { - return create(MongoClientSettings.builder().applyConnectionString(connectionString).build(), mongoDriverInformation); + return InternalMongoClients.create(connectionString, mongoDriverInformation, DEFAULT_INTERNAL_SETTINGS); } /** @@ -110,23 +106,7 @@ public static MongoClient create(final ConnectionString connectionString, * @return the client */ public static MongoClient create(final MongoClientSettings settings, @Nullable final MongoDriverInformation mongoDriverInformation) { - notNull("settings", settings); - - MongoDriverInformation.Builder builder = mongoDriverInformation == null ? MongoDriverInformation.builder() - : MongoDriverInformation.builder(mongoDriverInformation); - - MongoDriverInformation driverInfo = builder.driverName("sync").build(); - - StreamFactoryFactory syncStreamFactoryFactory = getSyncStreamFactoryFactory( - settings.getTransportSettings(), - getInetAddressResolver(settings)); - - Cluster cluster = Clusters.createCluster( - settings, - driverInfo, - syncStreamFactoryFactory); - - return new MongoClientImpl(cluster, settings, driverInfo, syncStreamFactoryFactory); + return InternalMongoClients.create(settings, mongoDriverInformation, DEFAULT_INTERNAL_SETTINGS); } private MongoClients() { diff --git a/driver-sync/src/main/com/mongodb/client/internal/Clusters.java b/driver-sync/src/main/com/mongodb/client/internal/Clusters.java index 6c57505e090..21ab58c6b21 100644 --- a/driver-sync/src/main/com/mongodb/client/internal/Clusters.java +++ b/driver-sync/src/main/com/mongodb/client/internal/Clusters.java @@ -21,7 +21,7 @@ import com.mongodb.internal.TimeoutSettings; import com.mongodb.internal.connection.Cluster; import com.mongodb.internal.connection.DefaultClusterFactory; -import com.mongodb.internal.connection.InternalConnectionPoolSettings; +import com.mongodb.internal.connection.InternalMongoClientSettings; import com.mongodb.internal.connection.StreamFactory; import com.mongodb.internal.connection.StreamFactoryFactory; import com.mongodb.lang.Nullable; @@ -35,17 +35,42 @@ private Clusters() { //NOP } + /** + * Creates a cluster with the given settings and default internal settings. + * + * @param settings the client settings + * @param mongoDriverInformation driver information + * @param streamFactoryFactory the stream factory + * @return the cluster + */ public static Cluster createCluster(final MongoClientSettings settings, @Nullable final MongoDriverInformation mongoDriverInformation, final StreamFactoryFactory streamFactoryFactory) { + return createCluster(settings, mongoDriverInformation, streamFactoryFactory, InternalMongoClientSettings.getDefaults()); + } + + /** + * Creates a cluster with the given settings and internal settings. + * + * @param settings the client settings + * @param mongoDriverInformation driver information + * @param streamFactoryFactory the stream factory + * @param internalSettings the internal settings + * @return the cluster + */ + public static Cluster createCluster(final MongoClientSettings settings, + @Nullable final MongoDriverInformation mongoDriverInformation, + final StreamFactoryFactory streamFactoryFactory, + final InternalMongoClientSettings internalSettings) { assertNotNull(streamFactoryFactory); assertNotNull(settings); + assertNotNull(internalSettings); StreamFactory streamFactory = getStreamFactory(streamFactoryFactory, settings, false); StreamFactory heartbeatStreamFactory = getStreamFactory(streamFactoryFactory, settings, true); return new DefaultClusterFactory().createCluster(settings.getClusterSettings(), settings.getServerSettings(), - settings.getConnectionPoolSettings(), InternalConnectionPoolSettings.builder().build(), + settings.getConnectionPoolSettings(), internalSettings, TimeoutSettings.create(settings), streamFactory, TimeoutSettings.createHeartbeatSettings(settings), heartbeatStreamFactory, settings.getCredential(), settings.getLoggerSettings(), getCommandListener(settings.getCommandListeners()), diff --git a/driver-sync/src/main/com/mongodb/client/internal/InternalMongoClients.java b/driver-sync/src/main/com/mongodb/client/internal/InternalMongoClients.java new file mode 100644 index 00000000000..85ba9990277 --- /dev/null +++ b/driver-sync/src/main/com/mongodb/client/internal/InternalMongoClients.java @@ -0,0 +1,135 @@ +/* + * 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.client.internal; + +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import com.mongodb.MongoDriverInformation; +import com.mongodb.client.MongoClient; +import com.mongodb.internal.connection.Cluster; +import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.connection.StreamFactoryFactory; +import com.mongodb.lang.Nullable; + +import static com.mongodb.assertions.Assertions.notNull; +import static com.mongodb.internal.connection.ServerAddressHelper.getInetAddressResolver; +import static com.mongodb.internal.connection.StreamFactoryHelper.getSyncStreamFactoryFactory; + +/** + * Internal factory for MongoClient instances. + * + *

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

+ */ +public final class InternalMongoClients { + + private InternalMongoClients() { + } + + /** + * Creates a new client with the default connection string "mongodb://localhost" and the given internal settings. + * + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final InternalMongoClientSettings internalSettings) { + return create(new ConnectionString("mongodb://localhost"), internalSettings); + } + + /** + * Creates a new client with the given connection string and internal settings. + * + * @param connectionString the connection string + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final String connectionString, + final InternalMongoClientSettings internalSettings) { + return create(new ConnectionString(connectionString), internalSettings); + } + + /** + * Creates a new client with the given connection string and internal settings. + * + * @param connectionString the connection string + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final ConnectionString connectionString, + final InternalMongoClientSettings internalSettings) { + return create(connectionString, null, internalSettings); + } + + /** + * Creates a new client with the given connection string, driver information and internal settings. + * + * @param connectionString the connection string + * @param mongoDriverInformation any driver information to associate with the MongoClient + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final ConnectionString connectionString, + @Nullable final MongoDriverInformation mongoDriverInformation, + final InternalMongoClientSettings internalSettings) { + return create(MongoClientSettings.builder().applyConnectionString(connectionString).build(), + mongoDriverInformation, internalSettings); + } + + /** + * Creates a new client with the given client settings and internal settings. + * + * @param settings the public settings + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final MongoClientSettings settings, + final InternalMongoClientSettings internalSettings) { + return create(settings, null, internalSettings); + } + + /** + * Creates a new client with the given client settings, driver information and internal settings. + * + * @param settings the public settings + * @param mongoDriverInformation any driver information to associate with the MongoClient + * @param internalSettings the internal settings + * @return the client + */ + public static MongoClient create(final MongoClientSettings settings, + @Nullable final MongoDriverInformation mongoDriverInformation, + final InternalMongoClientSettings internalSettings) { + notNull("settings", settings); + notNull("internalSettings", internalSettings); + + MongoDriverInformation.Builder builder = mongoDriverInformation == null ? MongoDriverInformation.builder() + : MongoDriverInformation.builder(mongoDriverInformation); + + MongoDriverInformation driverInfo = builder.driverName("sync").build(); + + StreamFactoryFactory syncStreamFactoryFactory = getSyncStreamFactoryFactory( + settings.getTransportSettings(), + getInetAddressResolver(settings)); + + Cluster cluster = Clusters.createCluster( + settings, + driverInfo, + syncStreamFactoryFactory, + internalSettings); + + return new MongoClientImpl(cluster, settings, driverInfo, syncStreamFactoryFactory); + } +} + 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 bbeb7419bc7..42d6bd93ce0 100644 --- a/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java +++ b/driver-sync/src/main/com/mongodb/client/internal/MongoClientImpl.java @@ -36,15 +36,10 @@ import com.mongodb.client.model.bulk.ClientBulkWriteResult; import com.mongodb.client.model.bulk.ClientNamespacedWriteModel; import com.mongodb.connection.ClusterDescription; -import com.mongodb.connection.SocketSettings; import com.mongodb.internal.TimeoutSettings; import com.mongodb.internal.VisibleForTesting; import com.mongodb.internal.connection.ClientMetadata; import com.mongodb.internal.connection.Cluster; -import com.mongodb.internal.connection.DefaultClusterFactory; -import com.mongodb.internal.connection.InternalConnectionPoolSettings; -import com.mongodb.internal.connection.StreamFactory; -import com.mongodb.internal.connection.StreamFactoryFactory; import com.mongodb.internal.diagnostics.logging.Logger; import com.mongodb.internal.diagnostics.logging.Loggers; import com.mongodb.internal.session.ServerSessionPool; @@ -61,7 +56,6 @@ import static com.mongodb.assertions.Assertions.notNull; import static com.mongodb.client.internal.Crypts.createCrypt; -import static com.mongodb.internal.event.EventListenerHelper.getCommandListener; import static java.lang.String.format; import static org.bson.codecs.configuration.CodecRegistries.withUuidRepresentation; @@ -310,27 +304,6 @@ public ClientBulkWriteResult bulkWrite( return delegate.bulkWrite(clientSession, clientWriteModels, options); } - private static Cluster createCluster(final MongoClientSettings settings, - @Nullable final MongoDriverInformation mongoDriverInformation, - final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory) { - notNull("settings", settings); - return new DefaultClusterFactory().createCluster(settings.getClusterSettings(), settings.getServerSettings(), - settings.getConnectionPoolSettings(), InternalConnectionPoolSettings.builder().build(), - TimeoutSettings.create(settings), streamFactory, - TimeoutSettings.createHeartbeatSettings(settings), heartbeatStreamFactory, - settings.getCredential(), settings.getLoggerSettings(), getCommandListener(settings.getCommandListeners()), - settings.getApplicationName(), mongoDriverInformation, settings.getCompressorList(), settings.getServerApi(), - settings.getDnsClient()); - } - - private static StreamFactory getStreamFactory( - final StreamFactoryFactory streamFactoryFactory, - final MongoClientSettings settings, - final boolean isHeartbeat) { - SocketSettings socketSettings = isHeartbeat ? settings.getHeartbeatSocketSettings() : settings.getSocketSettings(); - return streamFactoryFactory.create(socketSettings, settings.getSslSettings()); - } - public Cluster getCluster() { return delegate.getCluster(); } diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientMetadataProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientMetadataProseTest.java index b958afcf145..639a2f687f5 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientMetadataProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientMetadataProseTest.java @@ -20,12 +20,10 @@ import com.mongodb.MongoDriverInformation; import com.mongodb.event.CommandStartedEvent; import com.mongodb.internal.client.DriverInformation; -import com.mongodb.internal.connection.InternalStreamConnection; import com.mongodb.internal.connection.TestCommandListener; import com.mongodb.internal.connection.TestConnectionPoolListener; import com.mongodb.lang.Nullable; import org.bson.BsonDocument; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -65,12 +63,6 @@ public void setUp() { commandListener = new TestCommandListener(); connectionPoolListener = new TestConnectionPoolListener(); - InternalStreamConnection.setRecordEverything(true); - } - - @AfterEach - public void tearDown() { - InternalStreamConnection.setRecordEverything(false); } @DisplayName("Test 1: Test that the driver updates metadata") diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java index 9ce58b1654f..44d1d2902e0 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java @@ -47,11 +47,7 @@ import com.mongodb.event.ConnectionClosedEvent; import com.mongodb.event.ConnectionCreatedEvent; import com.mongodb.event.ConnectionReadyEvent; - -import static com.mongodb.internal.connection.CommandHelper.HELLO; -import static com.mongodb.internal.connection.CommandHelper.LEGACY_HELLO; - -import com.mongodb.internal.connection.InternalStreamConnection; +import com.mongodb.internal.connection.InternalMongoClientSettings; import com.mongodb.internal.connection.ServerHelper; import com.mongodb.internal.connection.TestCommandListener; import com.mongodb.internal.connection.TestConnectionPoolListener; @@ -93,6 +89,8 @@ import static com.mongodb.ClusterFixture.sleep; import static com.mongodb.client.Fixture.getDefaultDatabaseName; import static com.mongodb.client.Fixture.getPrimary; +import static com.mongodb.internal.connection.CommandHelper.HELLO; +import static com.mongodb.internal.connection.CommandHelper.LEGACY_HELLO; import static java.lang.Long.MAX_VALUE; import static java.lang.String.join; import static java.util.Arrays.asList; @@ -134,6 +132,17 @@ public abstract class AbstractClientSideOperationsTimeoutProseTest { protected abstract MongoClient createMongoClient(MongoClientSettings mongoClientSettings); + /** + * Creates a MongoClient with the given settings and internal settings. + * Used for tests that need to configure internal settings like recordEverything. + * + * @param mongoClientSettings the client settings + * @param internalSettings the internal settings + * @return the MongoClient + */ + protected abstract MongoClient createMongoClientWithInternalSettings(MongoClientSettings mongoClientSettings, + InternalMongoClientSettings internalSettings); + protected abstract GridFSBucket createGridFsBucket(MongoDatabase mongoDatabase, String bucketName); protected abstract boolean isAsync(); @@ -1044,16 +1053,15 @@ public void shouldUseConnectTimeoutMsWhenEstablishingConnectionInBackground() { + " }" + "}"); - try (MongoClient ignored = createMongoClient(getMongoClientSettingsBuilder() + try (MongoClient ignored = createMongoClientWithInternalSettings(getMongoClientSettingsBuilder() .applyToConnectionPoolSettings(builder -> builder.minSize(1)) // Use a very short timeout to ensure that the connection establishment will fail on the first handshake command. - .timeout(10, TimeUnit.MILLISECONDS))) { - InternalStreamConnection.setRecordEverything(true); + .timeout(10, TimeUnit.MILLISECONDS) + .build(), + InternalMongoClientSettings.builder().recordEverything(true).build())) { // Wait for the connection to start establishment in the background. sleep(1000); - } finally { - InternalStreamConnection.setRecordEverything(false); } List commandFailedEvents = commandListener.getCommandFailedEvents(getHandshakeCommandName()); assertFalse(commandFailedEvents.isEmpty()); diff --git a/driver-sync/src/test/functional/com/mongodb/client/ClientMetadataProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/ClientMetadataProseTest.java index f457eb350fe..30b0a583528 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/ClientMetadataProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/ClientMetadataProseTest.java @@ -18,6 +18,8 @@ import com.mongodb.MongoClientSettings; import com.mongodb.MongoDriverInformation; +import com.mongodb.client.internal.InternalMongoClients; +import com.mongodb.internal.connection.InternalMongoClientSettings; import com.mongodb.lang.Nullable; public class ClientMetadataProseTest extends AbstractClientMetadataProseTest { @@ -25,6 +27,7 @@ public class ClientMetadataProseTest extends AbstractClientMetadataProseTest { @Override protected MongoClient createMongoClient(@Nullable final MongoDriverInformation mongoDriverInformation, final MongoClientSettings mongoClientSettings) { - return MongoClients.create(mongoClientSettings, mongoDriverInformation); + return InternalMongoClients.create(mongoClientSettings, mongoDriverInformation, + InternalMongoClientSettings.builder().recordEverything(true).build()); } } diff --git a/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutProseTest.java index 4dcbc4d1a0f..c69ed39874e 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutProseTest.java @@ -19,6 +19,8 @@ import com.mongodb.MongoClientSettings; import com.mongodb.client.gridfs.GridFSBucket; import com.mongodb.client.gridfs.GridFSBuckets; +import com.mongodb.client.internal.InternalMongoClients; +import com.mongodb.internal.connection.InternalMongoClientSettings; /** @@ -31,6 +33,12 @@ protected MongoClient createMongoClient(final MongoClientSettings mongoClientSet return MongoClients.create(mongoClientSettings); } + @Override + protected MongoClient createMongoClientWithInternalSettings(final MongoClientSettings mongoClientSettings, + final InternalMongoClientSettings internalSettings) { + return InternalMongoClients.create(mongoClientSettings, internalSettings); + } + @Override protected GridFSBucket createGridFsBucket(final MongoDatabase mongoDatabase, final String bucketName) { return GridFSBuckets.create(mongoDatabase, bucketName); diff --git a/driver-sync/src/test/functional/com/mongodb/internal/connection/OidcAuthenticationProseTests.java b/driver-sync/src/test/functional/com/mongodb/internal/connection/OidcAuthenticationProseTests.java index 8c9432b77bf..1c01a006611 100644 --- a/driver-sync/src/test/functional/com/mongodb/internal/connection/OidcAuthenticationProseTests.java +++ b/driver-sync/src/test/functional/com/mongodb/internal/connection/OidcAuthenticationProseTests.java @@ -29,9 +29,9 @@ import com.mongodb.client.FindIterable; import com.mongodb.client.Fixture; import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.TestListener; +import com.mongodb.client.internal.InternalMongoClients; import com.mongodb.event.CommandListener; import com.mongodb.lang.Nullable; import org.bson.BsonArray; @@ -40,7 +40,6 @@ import org.bson.BsonInt32; import org.bson.BsonString; import org.bson.Document; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -141,21 +140,16 @@ private static String getTestTokenFilePath() { } protected MongoClient createMongoClient(final MongoClientSettings settings) { - return MongoClients.create(settings); + return InternalMongoClients.create(settings, + InternalMongoClientSettings.builder().recordEverything(true).build()); } @BeforeEach public void beforeEach() { assumeTrue(oidcTestsEnabled()); - InternalStreamConnection.setRecordEverything(true); this.appName = this.getClass().getSimpleName() + "-" + new Random().nextInt(Integer.MAX_VALUE); } - @AfterEach - public void afterEach() { - InternalStreamConnection.setRecordEverything(false); - } - @Test public void test1p1CallbackIsCalledDuringAuth() { // #. Create a ``MongoClient`` configured with an OIDC callback... diff --git a/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java b/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java new file mode 100644 index 00000000000..0d03e9c3bee --- /dev/null +++ b/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java @@ -0,0 +1,92 @@ +/* + * 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.client.internal; + +import com.mongodb.MongoClientSettings; +import com.mongodb.internal.connection.InternalConnectionPoolSettings; +import com.mongodb.internal.connection.InternalMongoClientSettings; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Unit tests for {@link InternalMongoClients}. + * + *

These tests demonstrate how to use InternalMongoClients to create MongoClient instances + * with custom internal settings, avoiding the need for global mutable state in tests.

+ */ +class InternalMongoClientsTest { + + @Test + void testCreateWithDefaultInternalSettings() { + // Tests can now create clients with explicit internal settings + InternalMongoClientSettings internalSettings = InternalMongoClientSettings.builder().build(); + + assertNotNull(internalSettings.getInternalConnectionPoolSettings(), + "Default internal settings should have connection pool settings"); + assertFalse(internalSettings.isRecordEverything(), + "Default internal settings should have log recordEverything set to false"); + } + + @Test + void testCreateWithCustomInternalConnectionPoolSettings() { + // Demonstrates setting custom internal connection pool settings + InternalConnectionPoolSettings poolSettings = InternalConnectionPoolSettings.builder() + .prestartAsyncWorkManager(false) + .build(); + + InternalMongoClientSettings internalSettings = InternalMongoClientSettings.builder() + .internalConnectionPoolSettings(poolSettings) + .build(); + + assertEquals(poolSettings, internalSettings.getInternalConnectionPoolSettings(), + "Custom connection pool settings should be preserved"); + } + + @Test + void testCreateWithCustomLogRecordingSettings() { + InternalMongoClientSettings internalSettings = InternalMongoClientSettings.builder() + .recordEverything(true) + .build(); + + assertTrue(internalSettings.isRecordEverything()); + } + + @Test + void testGetDefaultsReturnsSameInstance() { + InternalMongoClientSettings defaults1 = InternalMongoClientSettings.getDefaults(); + InternalMongoClientSettings defaults2 = InternalMongoClientSettings.getDefaults(); + assertSame(defaults1, defaults2, "getDefaults() should return the same instances"); + } + + @Test + void testCreateMethodsValidateNullSettings() { + // Verify that null MongoClientSettings is rejected + assertThrows(IllegalArgumentException.class, () -> + InternalMongoClients.create((MongoClientSettings) null, InternalMongoClientSettings.getDefaults())); + + // Verify that null InternalMongoClientSettings is rejected + MongoClientSettings settings = MongoClientSettings.builder().build(); + assertThrows(IllegalArgumentException.class, () -> + InternalMongoClients.create(settings, null)); + } +} From 482b31a02a615235efda6b3348c7b6ce81fdd639 Mon Sep 17 00:00:00 2001 From: Nabil Hachicha Date: Mon, 19 Jan 2026 14:55:49 +0000 Subject: [PATCH 2/3] Update driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../com/mongodb/client/internal/InternalMongoClientsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java b/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java index 0d03e9c3bee..696a2358b57 100644 --- a/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java +++ b/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java @@ -75,7 +75,7 @@ void testCreateWithCustomLogRecordingSettings() { void testGetDefaultsReturnsSameInstance() { InternalMongoClientSettings defaults1 = InternalMongoClientSettings.getDefaults(); InternalMongoClientSettings defaults2 = InternalMongoClientSettings.getDefaults(); - assertSame(defaults1, defaults2, "getDefaults() should return the same instances"); + assertSame(defaults1, defaults2, "getDefaults() should return the same instance"); } @Test From 95a53b23fb434c803bf8807aa97f6fc97ad9f2f0 Mon Sep 17 00:00:00 2001 From: Nabil Hachicha Date: Mon, 19 Jan 2026 15:05:35 +0000 Subject: [PATCH 3/3] moved InternalMongoClientSettings package --- .../internal/{connection => }/InternalMongoClientSettings.java | 3 ++- .../com/mongodb/internal/connection/DefaultClusterFactory.java | 1 + .../internal/connection/DefaultClusterableServerFactory.java | 1 + .../connection/LoadBalancedClusterableServerFactory.java | 1 + .../src/test/functional/com/mongodb/ClusterFixture.java | 2 +- .../mongodb/internal/connection/SingleServerClusterTest.java | 1 + .../com/mongodb/internal/connection/TestCommandListener.java | 1 + .../main/com/mongodb/reactivestreams/client/MongoClients.java | 2 +- .../reactivestreams/client/internal/InternalMongoClients.java | 2 +- .../client/AbstractClientMetadataProseTest.java | 2 +- .../client/ClientSideOperationTimeoutProseTest.java | 2 +- .../client/internal/InternalMongoClientsTest.java | 2 +- driver-sync/src/main/com/mongodb/client/MongoClients.java | 2 +- driver-sync/src/main/com/mongodb/client/internal/Clusters.java | 2 +- .../main/com/mongodb/client/internal/InternalMongoClients.java | 2 +- .../client/AbstractClientSideOperationsTimeoutProseTest.java | 2 +- .../functional/com/mongodb/client/ClientMetadataProseTest.java | 2 +- .../mongodb/client/ClientSideOperationTimeoutProseTest.java | 2 +- .../internal/connection/OidcAuthenticationProseTests.java | 1 + .../com/mongodb/client/internal/InternalMongoClientsTest.java | 2 +- 20 files changed, 21 insertions(+), 14 deletions(-) rename driver-core/src/main/com/mongodb/internal/{connection => }/InternalMongoClientSettings.java (98%) diff --git a/driver-core/src/main/com/mongodb/internal/connection/InternalMongoClientSettings.java b/driver-core/src/main/com/mongodb/internal/InternalMongoClientSettings.java similarity index 98% rename from driver-core/src/main/com/mongodb/internal/connection/InternalMongoClientSettings.java rename to driver-core/src/main/com/mongodb/internal/InternalMongoClientSettings.java index dd685d8c5dd..8e4bb9440c6 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/InternalMongoClientSettings.java +++ b/driver-core/src/main/com/mongodb/internal/InternalMongoClientSettings.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mongodb.internal.connection; +package com.mongodb.internal; import com.mongodb.annotations.Immutable; +import com.mongodb.internal.connection.InternalConnectionPoolSettings; import java.util.Objects; 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 c42675f945e..9940d8196c5 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java @@ -31,6 +31,7 @@ import com.mongodb.event.CommandListener; import com.mongodb.event.ServerListener; import com.mongodb.event.ServerMonitorListener; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.TimeoutSettings; import com.mongodb.internal.VisibleForTesting; import com.mongodb.internal.diagnostics.logging.Logger; 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 6656947056a..90833a0f585 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java @@ -27,6 +27,7 @@ import com.mongodb.connection.ServerSettings; import com.mongodb.event.CommandListener; import com.mongodb.event.ServerListener; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.inject.SameObjectProvider; import com.mongodb.lang.Nullable; 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 6e8561902ac..aa0a1f81239 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/LoadBalancedClusterableServerFactory.java @@ -27,6 +27,7 @@ import com.mongodb.connection.ServerId; import com.mongodb.connection.ServerSettings; import com.mongodb.event.CommandListener; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.inject.EmptyProvider; import com.mongodb.lang.Nullable; diff --git a/driver-core/src/test/functional/com/mongodb/ClusterFixture.java b/driver-core/src/test/functional/com/mongodb/ClusterFixture.java index c56a17283ea..0878ca4d76b 100644 --- a/driver-core/src/test/functional/com/mongodb/ClusterFixture.java +++ b/driver-core/src/test/functional/com/mongodb/ClusterFixture.java @@ -52,7 +52,7 @@ import com.mongodb.internal.connection.Cluster; import com.mongodb.internal.connection.DefaultClusterFactory; import com.mongodb.internal.connection.DefaultInetAddressResolver; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.connection.InternalOperationContextFactory; import com.mongodb.internal.connection.MongoCredentialWithCache; import com.mongodb.internal.connection.OperationContext; 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 0f1c9571de6..4f0167918a2 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 @@ -25,6 +25,7 @@ import com.mongodb.connection.ConnectionPoolSettings; import com.mongodb.connection.ServerSettings; import com.mongodb.connection.SocketSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.selector.ServerAddressSelector; import com.mongodb.internal.validator.NoOpFieldNameValidator; import org.bson.BsonDocument; diff --git a/driver-core/src/test/functional/com/mongodb/internal/connection/TestCommandListener.java b/driver-core/src/test/functional/com/mongodb/internal/connection/TestCommandListener.java index 5b4b1de26c6..621a32be67d 100644 --- a/driver-core/src/test/functional/com/mongodb/internal/connection/TestCommandListener.java +++ b/driver-core/src/test/functional/com/mongodb/internal/connection/TestCommandListener.java @@ -23,6 +23,7 @@ import com.mongodb.event.CommandListener; import com.mongodb.event.CommandStartedEvent; import com.mongodb.event.CommandSucceededEvent; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.lang.Nullable; import org.bson.BsonDocument; import org.bson.BsonDocumentWriter; 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 99a5815f940..92d93658761 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 @@ -19,7 +19,7 @@ import com.mongodb.ConnectionString; import com.mongodb.MongoClientSettings; import com.mongodb.MongoDriverInformation; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.lang.Nullable; import com.mongodb.reactivestreams.client.internal.InternalMongoClients; import org.bson.codecs.configuration.CodecRegistry; diff --git a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/InternalMongoClients.java b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/InternalMongoClients.java index c1f34ad7c94..75037425481 100644 --- a/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/InternalMongoClients.java +++ b/driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/InternalMongoClients.java @@ -24,7 +24,7 @@ import com.mongodb.internal.TimeoutSettings; import com.mongodb.internal.connection.Cluster; import com.mongodb.internal.connection.DefaultClusterFactory; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.connection.StreamFactory; import com.mongodb.internal.connection.StreamFactoryFactory; import com.mongodb.lang.Nullable; diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/AbstractClientMetadataProseTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/AbstractClientMetadataProseTest.java index cc84fb9b948..1ebe60d1769 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/AbstractClientMetadataProseTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/AbstractClientMetadataProseTest.java @@ -20,7 +20,7 @@ import com.mongodb.MongoDriverInformation; import com.mongodb.client.AbstractClientMetadataProseTest; import com.mongodb.client.MongoClient; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.lang.Nullable; import com.mongodb.reactivestreams.client.internal.InternalMongoClients; import com.mongodb.reactivestreams.client.syncadapter.SyncMongoClient; diff --git a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java index f7f92a0cded..cd478d60d97 100644 --- a/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java +++ b/driver-reactive-streams/src/test/functional/com/mongodb/reactivestreams/client/ClientSideOperationTimeoutProseTest.java @@ -28,7 +28,7 @@ import com.mongodb.client.model.changestream.FullDocument; import com.mongodb.event.CommandFailedEvent; import com.mongodb.event.CommandStartedEvent; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.reactivestreams.client.gridfs.GridFSBucket; import com.mongodb.reactivestreams.client.gridfs.GridFSBuckets; import com.mongodb.reactivestreams.client.internal.InternalMongoClients; diff --git a/driver-reactive-streams/src/test/unit/com/mongodb/reactivestreams/client/internal/InternalMongoClientsTest.java b/driver-reactive-streams/src/test/unit/com/mongodb/reactivestreams/client/internal/InternalMongoClientsTest.java index b21a9157d77..4db711ae3b5 100644 --- a/driver-reactive-streams/src/test/unit/com/mongodb/reactivestreams/client/internal/InternalMongoClientsTest.java +++ b/driver-reactive-streams/src/test/unit/com/mongodb/reactivestreams/client/internal/InternalMongoClientsTest.java @@ -17,7 +17,7 @@ package com.mongodb.reactivestreams.client.internal; import com.mongodb.MongoClientSettings; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/driver-sync/src/main/com/mongodb/client/MongoClients.java b/driver-sync/src/main/com/mongodb/client/MongoClients.java index 3ecd2026803..51dd58868d5 100644 --- a/driver-sync/src/main/com/mongodb/client/MongoClients.java +++ b/driver-sync/src/main/com/mongodb/client/MongoClients.java @@ -20,7 +20,7 @@ import com.mongodb.MongoClientSettings; import com.mongodb.MongoDriverInformation; import com.mongodb.client.internal.InternalMongoClients; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.lang.Nullable; diff --git a/driver-sync/src/main/com/mongodb/client/internal/Clusters.java b/driver-sync/src/main/com/mongodb/client/internal/Clusters.java index 21ab58c6b21..7e09ee7d909 100644 --- a/driver-sync/src/main/com/mongodb/client/internal/Clusters.java +++ b/driver-sync/src/main/com/mongodb/client/internal/Clusters.java @@ -21,7 +21,7 @@ import com.mongodb.internal.TimeoutSettings; import com.mongodb.internal.connection.Cluster; import com.mongodb.internal.connection.DefaultClusterFactory; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.connection.StreamFactory; import com.mongodb.internal.connection.StreamFactoryFactory; import com.mongodb.lang.Nullable; diff --git a/driver-sync/src/main/com/mongodb/client/internal/InternalMongoClients.java b/driver-sync/src/main/com/mongodb/client/internal/InternalMongoClients.java index 85ba9990277..6d6edceb160 100644 --- a/driver-sync/src/main/com/mongodb/client/internal/InternalMongoClients.java +++ b/driver-sync/src/main/com/mongodb/client/internal/InternalMongoClients.java @@ -21,7 +21,7 @@ import com.mongodb.MongoDriverInformation; import com.mongodb.client.MongoClient; import com.mongodb.internal.connection.Cluster; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.connection.StreamFactoryFactory; import com.mongodb.lang.Nullable; diff --git a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java index 44d1d2902e0..19178c89d6d 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/AbstractClientSideOperationsTimeoutProseTest.java @@ -47,7 +47,7 @@ import com.mongodb.event.ConnectionClosedEvent; import com.mongodb.event.ConnectionCreatedEvent; import com.mongodb.event.ConnectionReadyEvent; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.internal.connection.ServerHelper; import com.mongodb.internal.connection.TestCommandListener; import com.mongodb.internal.connection.TestConnectionPoolListener; diff --git a/driver-sync/src/test/functional/com/mongodb/client/ClientMetadataProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/ClientMetadataProseTest.java index 30b0a583528..dd7f6784c2b 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/ClientMetadataProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/ClientMetadataProseTest.java @@ -19,7 +19,7 @@ import com.mongodb.MongoClientSettings; import com.mongodb.MongoDriverInformation; import com.mongodb.client.internal.InternalMongoClients; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.lang.Nullable; public class ClientMetadataProseTest extends AbstractClientMetadataProseTest { diff --git a/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutProseTest.java b/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutProseTest.java index c69ed39874e..6b37779265d 100644 --- a/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutProseTest.java +++ b/driver-sync/src/test/functional/com/mongodb/client/ClientSideOperationTimeoutProseTest.java @@ -20,7 +20,7 @@ import com.mongodb.client.gridfs.GridFSBucket; import com.mongodb.client.gridfs.GridFSBuckets; import com.mongodb.client.internal.InternalMongoClients; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; /** diff --git a/driver-sync/src/test/functional/com/mongodb/internal/connection/OidcAuthenticationProseTests.java b/driver-sync/src/test/functional/com/mongodb/internal/connection/OidcAuthenticationProseTests.java index 1c01a006611..d5be36cbd9a 100644 --- a/driver-sync/src/test/functional/com/mongodb/internal/connection/OidcAuthenticationProseTests.java +++ b/driver-sync/src/test/functional/com/mongodb/internal/connection/OidcAuthenticationProseTests.java @@ -33,6 +33,7 @@ import com.mongodb.client.TestListener; import com.mongodb.client.internal.InternalMongoClients; import com.mongodb.event.CommandListener; +import com.mongodb.internal.InternalMongoClientSettings; import com.mongodb.lang.Nullable; import org.bson.BsonArray; import org.bson.BsonBoolean; diff --git a/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java b/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java index 696a2358b57..6b7c87a194a 100644 --- a/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java +++ b/driver-sync/src/test/unit/com/mongodb/client/internal/InternalMongoClientsTest.java @@ -18,7 +18,7 @@ import com.mongodb.MongoClientSettings; import com.mongodb.internal.connection.InternalConnectionPoolSettings; -import com.mongodb.internal.connection.InternalMongoClientSettings; +import com.mongodb.internal.InternalMongoClientSettings; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals;