Skip to content

Commit 59906de

Browse files
committed
Only apply retryWrites/compressors from connection string if set
JAVA-3057 JAVA-3058
1 parent 5096761 commit 59906de

File tree

6 files changed

+165
-13
lines changed

6 files changed

+165
-13
lines changed

driver-core/src/main/com/mongodb/ConnectionString.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public class ConnectionString {
238238

239239
private ReadPreference readPreference;
240240
private WriteConcern writeConcern;
241-
private boolean retryWrites;
241+
private Boolean retryWrites;
242242
private ReadConcern readConcern;
243243

244244
private Integer minConnectionPoolSize;
@@ -1067,13 +1067,30 @@ public WriteConcern getWriteConcern() {
10671067
}
10681068

10691069
/**
1070-
* Returns true if writes should be retried if they fail due to a network error.
1070+
* Returns true if writes should be retried if they fail due to a network error, and false otherwise
10711071
*
1072-
* @return the retryWrites value
1072+
* @return the retryWrites value, or false if unset
10731073
* @since 3.6
10741074
* @mongodb.server.release 3.6
1075+
* @deprecated Prefer {@link #getRetryWritesValue()}
10751076
*/
1077+
@Deprecated
10761078
public boolean getRetryWrites() {
1079+
return retryWrites == null ? false : retryWrites;
1080+
}
1081+
1082+
/**
1083+
* <p>Gets whether writes should be retried if they fail due to a network error</p>
1084+
*
1085+
* The name of this method differs from others in this class so as not to conflict with the deprecated (and soon to be removed)
1086+
* {@link #getRetryWrites()} method, which returns a primitive {@code boolean} value, which doesn't allow callers to differentiate
1087+
* between a false value and an unset value.
1088+
*
1089+
* @return the retryWrites value, or null if unset
1090+
* @since 3.9
1091+
* @mongodb.server.release 3.6
1092+
*/
1093+
public Boolean getRetryWritesValue() {
10771094
return retryWrites;
10781095
}
10791096

driver-core/src/main/com/mongodb/MongoClientSettings.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@ public Builder applyConnectionString(final ConnectionString connectionString) {
195195
if (connectionString.getReadPreference() != null) {
196196
readPreference = connectionString.getReadPreference();
197197
}
198-
retryWrites = connectionString.getRetryWrites();
198+
if (connectionString.getRetryWritesValue() != null) {
199+
retryWrites = connectionString.getRetryWrites();
200+
}
199201
serverSettingsBuilder.applyConnectionString(connectionString);
200202
socketSettingsBuilder.applyConnectionString(connectionString);
201203
sslSettingsBuilder.applyConnectionString(connectionString);
@@ -452,7 +454,7 @@ public WriteConcern getWriteConcern() {
452454
}
453455

454456
/**
455-
* Returns true if writes should be retried if they fail due to a network error.
457+
* Returns true if writes should be retried if they fail due to a network error. The default is false.
456458
*
457459
* @return the retryWrites value
458460
* @mongodb.server.release 3.6

driver-core/src/test/unit/com/mongodb/ConnectionStringSpecification.groovy

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,14 @@ class ConnectionStringSpecification extends Specification {
129129
def 'should correct parse retryWrites'() {
130130
expect:
131131
uri.getRetryWrites() == retryWrites
132+
uri.getRetryWritesValue() == retryWritesValue
132133

133134
where:
134-
uri | retryWrites
135-
new ConnectionString('mongodb://localhost/') | false
136-
new ConnectionString('mongodb://localhost/?retryWrites=false') | false
137-
new ConnectionString('mongodb://localhost/?retryWrites=true') | true
135+
uri | retryWrites | retryWritesValue
136+
new ConnectionString('mongodb://localhost/') | false | null
137+
new ConnectionString('mongodb://localhost/?retryWrites=false') | false | false
138+
new ConnectionString('mongodb://localhost/?retryWrites=true') | true | true
139+
new ConnectionString('mongodb://localhost/?retryWrites=foos') | false | false
138140
}
139141

140142
@Unroll
@@ -248,6 +250,8 @@ class ConnectionStringSpecification extends Specification {
248250
connectionString.getStreamType() == null
249251
connectionString.getApplicationName() == null
250252
connectionString.getCompressorList() == []
253+
!connectionString.getRetryWrites()
254+
connectionString.getRetryWritesValue() == null
251255
}
252256

253257
@Unroll

driver-core/src/test/unit/com/mongodb/MongoClientSettingsSpecification.groovy

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,67 @@ class MongoClientSettingsSpecification extends Specification {
330330
expect expected, isTheSameAs(settings)
331331
}
332332

333+
@IgnoreIf({ isNotAtLeastJava7() })
334+
def 'should build settings from a connection string with default values'() {
335+
when:
336+
def builder = MongoClientSettings.builder()
337+
.applyToClusterSettings(new Block<ClusterSettings.Builder>() {
338+
@Override
339+
void apply(final ClusterSettings.Builder builder) {
340+
builder.hosts([new ServerAddress('localhost', 27017)])
341+
.mode(ClusterConnectionMode.SINGLE)
342+
.serverSelectionTimeout(25000, TimeUnit.MILLISECONDS)
343+
.localThreshold(30, TimeUnit.MILLISECONDS)
344+
}
345+
})
346+
.applyToConnectionPoolSettings(new Block<ConnectionPoolSettings.Builder>() {
347+
@Override
348+
void apply(final ConnectionPoolSettings.Builder builder) {
349+
builder.minSize(5)
350+
.maxSize(10)
351+
.maxWaitQueueSize(10 * 7) // maxPoolSize * waitQueueMultiple
352+
.maxWaitTime(150, TimeUnit.MILLISECONDS)
353+
.maxConnectionLifeTime(300, TimeUnit.MILLISECONDS)
354+
.maxConnectionIdleTime(200, TimeUnit.MILLISECONDS)
355+
}
356+
})
357+
.applyToServerSettings(new Block<ServerSettings.Builder>() {
358+
@Override
359+
void apply(final ServerSettings.Builder builder) {
360+
builder.heartbeatFrequency(20000, TimeUnit.MILLISECONDS)
361+
}
362+
})
363+
.applyToSocketSettings(new Block<SocketSettings.Builder>() {
364+
@Override
365+
void apply(final SocketSettings.Builder builder) {
366+
builder.connectTimeout(2500, TimeUnit.MILLISECONDS)
367+
.readTimeout(5500, TimeUnit.MILLISECONDS)
368+
}
369+
})
370+
.applyToSslSettings(new Block<SslSettings.Builder>() {
371+
@Override
372+
void apply(final SslSettings.Builder builder) {
373+
builder.enabled(true)
374+
.invalidHostNameAllowed(true)
375+
}
376+
})
377+
.readConcern(ReadConcern.MAJORITY)
378+
.readPreference(ReadPreference.secondary())
379+
.writeConcern(WriteConcern.MAJORITY.withWTimeout(2500, TimeUnit.MILLISECONDS))
380+
.applicationName('MyApp')
381+
.credential(MongoCredential.createScramSha1Credential('user', 'test', 'pass'.toCharArray()))
382+
.compressorList([MongoCompressor.createZlibCompressor().withProperty(MongoCompressor.LEVEL, 5)])
383+
.retryWrites(true)
384+
385+
def expectedSettings = builder.build()
386+
def settingsWithDefaultConnectionStringApplied = builder
387+
.applyConnectionString(new ConnectionString('mongodb://localhost'))
388+
.build()
389+
390+
then:
391+
expect expectedSettings, isTheSameAs(settingsWithDefaultConnectionStringApplied)
392+
}
393+
333394
def 'should use the socket settings connectionTime out for the heartbeat settings'() {
334395
when:
335396
def settings = MongoClientSettings.builder().applyToSocketSettings(new Block<SocketSettings.Builder>() {

driver-legacy/src/main/com/mongodb/MongoClientURI.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ public MongoClientOptions getOptions() {
327327
if (writeConcern != null) {
328328
builder.writeConcern(writeConcern);
329329
}
330-
if (proxied.getRetryWrites()) {
331-
builder.retryWrites(proxied.getRetryWrites());
330+
if (proxied.getRetryWritesValue() != null) {
331+
builder.retryWrites(proxied.getRetryWritesValue());
332332
}
333333
Integer maxConnectionPoolSize = proxied.getMaxConnectionPoolSize();
334334
if (maxConnectionPoolSize != null) {
@@ -390,8 +390,9 @@ public MongoClientOptions getOptions() {
390390
if (applicationName != null) {
391391
builder.applicationName(applicationName);
392392
}
393-
builder.compressorList(proxied.getCompressorList());
394-
393+
if (!proxied.getCompressorList().isEmpty()) {
394+
builder.compressorList(proxied.getCompressorList());
395+
}
395396
return builder.build();
396397
}
397398

driver-legacy/src/test/unit/com/mongodb/MongoClientURISpecification.groovy

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717
package com.mongodb
1818

19+
1920
import spock.lang.IgnoreIf
2021
import spock.lang.Specification
2122
import spock.lang.Unroll
2223

24+
import javax.net.ssl.SSLContext
25+
2326
import static com.mongodb.ClusterFixture.isNotAtLeastJava7
2427
import static com.mongodb.MongoCredential.createCredential
2528
import static com.mongodb.MongoCredential.createGSSAPICredential
@@ -135,6 +138,7 @@ class MongoClientURISpecification extends Specification {
135138
+ 'serverSelectionTimeoutMS=25000&'
136139
+ 'localThresholdMS=30&'
137140
+ 'heartbeatFrequencyMS=20000&'
141+
+ 'retryWrites=true&'
138142
+ 'appName=app1')
139143

140144
when:
@@ -157,6 +161,7 @@ class MongoClientURISpecification extends Specification {
157161
options.getServerSelectionTimeout() == 25000
158162
options.getLocalThreshold() == 30
159163
options.getHeartbeatFrequency() == 20000
164+
options.getRetryWrites()
160165
options.getApplicationName() == 'app1'
161166
}
162167

@@ -174,6 +179,68 @@ class MongoClientURISpecification extends Specification {
174179
options.getReadPreference() == ReadPreference.primary()
175180
options.getRequiredReplicaSetName() == null
176181
!options.isSslEnabled()
182+
!options.getRetryWrites()
183+
}
184+
185+
def 'should apply default uri to options'() {
186+
given:
187+
def optionsBuilder = MongoClientOptions.builder()
188+
.description('test')
189+
.applicationName('appName')
190+
.readPreference(ReadPreference.secondary())
191+
.retryWrites(true)
192+
.writeConcern(WriteConcern.JOURNALED)
193+
.minConnectionsPerHost(30)
194+
.connectionsPerHost(500)
195+
.connectTimeout(100)
196+
.socketTimeout(700)
197+
.serverSelectionTimeout(150)
198+
.maxWaitTime(200)
199+
.maxConnectionIdleTime(300)
200+
.maxConnectionLifeTime(400)
201+
.threadsAllowedToBlockForConnectionMultiplier(2)
202+
.socketKeepAlive(false)
203+
.sslEnabled(true)
204+
.sslInvalidHostNameAllowed(true)
205+
.sslContext(SSLContext.getDefault())
206+
.heartbeatFrequency(5)
207+
.minHeartbeatFrequency(11)
208+
.heartbeatConnectTimeout(15)
209+
.heartbeatSocketTimeout(20)
210+
.localThreshold(25)
211+
.requiredReplicaSetName('test')
212+
.compressorList([MongoCompressor.createZlibCompressor()])
213+
214+
when:
215+
def options = new MongoClientURI('mongodb://localhost', optionsBuilder).getOptions()
216+
217+
then:
218+
options.getDescription() == 'test'
219+
options.getApplicationName() == 'appName'
220+
options.getReadPreference() == ReadPreference.secondary()
221+
options.getWriteConcern() == WriteConcern.JOURNALED
222+
options.getRetryWrites()
223+
options.getServerSelectionTimeout() == 150
224+
options.getMaxWaitTime() == 200
225+
options.getMaxConnectionIdleTime() == 300
226+
options.getMaxConnectionLifeTime() == 400
227+
options.getMinConnectionsPerHost() == 30
228+
options.getConnectionsPerHost() == 500
229+
options.getConnectTimeout() == 100
230+
options.getSocketTimeout() == 700
231+
options.getThreadsAllowedToBlockForConnectionMultiplier() == 2
232+
!options.isSocketKeepAlive()
233+
options.isSslEnabled()
234+
options.isSslInvalidHostNameAllowed()
235+
options.getHeartbeatFrequency() == 5
236+
options.getMinHeartbeatFrequency() == 11
237+
options.getHeartbeatConnectTimeout() == 15
238+
options.getHeartbeatSocketTimeout() == 20
239+
options.getLocalThreshold() == 25
240+
options.getRequiredReplicaSetName() == 'test'
241+
options.getServerSettings().getHeartbeatFrequency(MILLISECONDS) == 5
242+
options.getServerSettings().getMinHeartbeatFrequency(MILLISECONDS) == 11
243+
options.compressorList == [MongoCompressor.createZlibCompressor()]
177244
}
178245

179246
@Unroll

0 commit comments

Comments
 (0)