Skip to content

Commit ff55404

Browse files
committed
Set connection mode to MULTIPLE when srvHost is specified in ClusterSettings
Also: * Fix the check that the srvHost has three parts * Throw exception if the mode is not compatible with SRV * Beef up the unit tests for SRV in ClusterSettings JAVA-3573
1 parent da844ef commit ff55404

File tree

2 files changed

+56
-10
lines changed

2 files changed

+56
-10
lines changed

driver-core/src/main/com/mongodb/connection/ClusterSettings.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.mongodb.connection;
1818

1919
import com.mongodb.ConnectionString;
20-
import com.mongodb.MongoClientException;
2120
import com.mongodb.MongoClientSettings;
2221
import com.mongodb.ServerAddress;
2322
import com.mongodb.annotations.Immutable;
@@ -596,14 +595,13 @@ public String getShortDescription() {
596595
}
597596

598597
private ClusterSettings(final Builder builder) {
599-
// TODO: Unit test this
600598
if (builder.srvHost != null) {
601599
if (builder.srvHost.contains(":")) {
602600
throw new IllegalArgumentException("The srvHost can not contain a host name that specifies a port");
603601
}
604602

605-
if (builder.hosts.get(0).getHost().split("\\.").length < 3) {
606-
throw new MongoClientException(format("An SRV host name '%s' was provided that does not contain at least three parts. "
603+
if (builder.srvHost.split("\\.").length < 3) {
604+
throw new IllegalArgumentException(format("An SRV host name '%s' was provided that does not contain at least three parts. "
607605
+ "It must contain a hostname, domain name and a top level domain.", builder.hosts.get(0).getHost()));
608606
}
609607
}
@@ -612,10 +610,6 @@ private ClusterSettings(final Builder builder) {
612610
throw new IllegalArgumentException("Multiple hosts cannot be specified when using ClusterType.STANDALONE.");
613611
}
614612

615-
if (builder.mode != null && builder.mode == ClusterConnectionMode.SINGLE && builder.hosts.size() > 1) {
616-
throw new IllegalArgumentException("Can not directly connect to more than one server");
617-
}
618-
619613
if (builder.requiredReplicaSetName != null) {
620614
if (builder.requiredClusterType == ClusterType.UNKNOWN) {
621615
builder.requiredClusterType = ClusterType.REPLICA_SET;
@@ -628,7 +622,18 @@ private ClusterSettings(final Builder builder) {
628622
description = builder.description;
629623
srvHost = builder.srvHost;
630624
hosts = builder.hosts;
631-
mode = builder.mode != null ? builder.mode : hosts.size() == 1 ? ClusterConnectionMode.SINGLE : ClusterConnectionMode.MULTIPLE;
625+
if (srvHost != null) {
626+
if (builder.mode == ClusterConnectionMode.SINGLE) {
627+
throw new IllegalArgumentException("An SRV host name was provided but the connection mode is not MULTIPLE");
628+
}
629+
mode = ClusterConnectionMode.MULTIPLE;
630+
} else {
631+
if (builder.mode == ClusterConnectionMode.SINGLE && builder.hosts.size() > 1) {
632+
throw new IllegalArgumentException("Can not directly connect to more than one server");
633+
}
634+
635+
mode = builder.mode != null ? builder.mode : hosts.size() == 1 ? ClusterConnectionMode.SINGLE : ClusterConnectionMode.MULTIPLE;
636+
}
632637
requiredReplicaSetName = builder.requiredReplicaSetName;
633638
requiredClusterType = builder.requiredClusterType;
634639
localThresholdMS = builder.localThresholdMS;

driver-core/src/test/unit/com/mongodb/connection/ClusterSettingsSpecification.groovy

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import spock.lang.Specification
2828

2929
import java.util.concurrent.TimeUnit
3030

31-
// TODO: add SRV tests
3231
class ClusterSettingsSpecification extends Specification {
3332
def hosts = [new ServerAddress('localhost'), new ServerAddress('localhost', 30000)]
3433
def serverSelector = new WritableServerSelector()
@@ -105,6 +104,48 @@ class ClusterSettingsSpecification extends Specification {
105104
ClusterSettings.builder(customSettings).applySettings(defaultSettings).build() == defaultSettings
106105
}
107106

107+
def 'when hosts contains more than one element and mode is SINGLE, should throw IllegalArgumentException'() {
108+
when:
109+
def builder = ClusterSettings.builder()
110+
builder.hosts([new ServerAddress('host1'), new ServerAddress('host2')])
111+
builder.mode(ClusterConnectionMode.SINGLE)
112+
builder.build()
113+
114+
then:
115+
thrown(IllegalArgumentException)
116+
}
117+
118+
def 'when srvHost is specified, should set mode to MULTIPLE'() {
119+
when:
120+
def builder = ClusterSettings.builder()
121+
builder.srvHost('foo.bar.com')
122+
def settings = builder.build()
123+
124+
then:
125+
settings.getSrvHost() == 'foo.bar.com'
126+
settings.getMode() == ClusterConnectionMode.MULTIPLE
127+
}
128+
129+
def 'when srvHost contains a colon, should throw IllegalArgumentException'() {
130+
when:
131+
def builder = ClusterSettings.builder()
132+
builder.srvHost('foo.bar.com:27017')
133+
builder.build()
134+
135+
then:
136+
thrown(IllegalArgumentException)
137+
}
138+
139+
def 'when srvHost contains less than three parts (host, domain, top-level domain, should throw IllegalArgumentException'() {
140+
when:
141+
def builder = ClusterSettings.builder()
142+
builder.srvHost('foo.bar')
143+
builder.build()
144+
145+
then:
146+
thrown(IllegalArgumentException)
147+
}
148+
108149
def 'should allow configure serverSelectors correctly'() {
109150
given:
110151
def latMinServerSelector = new LatencyMinimizingServerSelector(10, TimeUnit.MILLISECONDS)

0 commit comments

Comments
 (0)