Skip to content

Commit afe1692

Browse files
committed
Ensure srv resolution works for legacy
JAVA-3251
1 parent 83319fe commit afe1692

File tree

3 files changed

+226
-24
lines changed

3 files changed

+226
-24
lines changed

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

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
import static com.mongodb.ReadPreference.primary;
6060
import static com.mongodb.connection.ClusterConnectionMode.MULTIPLE;
6161
import static com.mongodb.connection.ClusterType.REPLICA_SET;
62-
import static com.mongodb.internal.connection.ServerAddressHelper.createServerAddress;
6362
import static com.mongodb.internal.event.EventListenerHelper.getCommandListener;
6463
import static java.util.Arrays.asList;
6564
import static java.util.Collections.singletonList;
@@ -708,27 +707,14 @@ public String getConnectPoint() {
708707
}
709708

710709
private static MongoClientOptions createLegacyOptions() {
711-
return MongoClientOptions.builder()
712-
.legacyDefaults()
713-
.build();
710+
return MongoClientOptions.builder().legacyDefaults().build();
714711
}
715712

716713
private static Cluster createCluster(final MongoClientURI mongoURI, @Nullable final MongoDriverInformation mongoDriverInformation) {
717714
List<MongoCredential> credentialList = mongoURI.getCredentials() != null
718-
? singletonList(mongoURI.getCredentials())
719-
: Collections.<MongoCredential>emptyList();
720-
721-
if (mongoURI.getHosts().size() == 1) {
722-
return createCluster(createServerAddress(mongoURI.getHosts().get(0)),
723-
credentialList,
724-
mongoURI.getOptions(), null);
725-
} else {
726-
List<ServerAddress> seedList = new ArrayList<ServerAddress>(mongoURI.getHosts().size());
727-
for (final String host : mongoURI.getHosts()) {
728-
seedList.add(createServerAddress(host));
729-
}
730-
return createCluster(seedList, credentialList, mongoURI.getOptions(), mongoDriverInformation);
731-
}
715+
? singletonList(mongoURI.getCredentials()) : Collections.<MongoCredential>emptyList();
716+
return createCluster(getClusterSettings(ClusterSettings.builder().applyConnectionString(mongoURI.getProxied()),
717+
mongoURI.getOptions()), credentialList, mongoURI.getOptions(), mongoDriverInformation);
732718
}
733719

734720
private static Cluster createCluster(final List<ServerAddress> seedList,
@@ -764,12 +750,8 @@ private static Cluster createCluster(final ClusterSettings clusterSettings, fina
764750
options.getCompressorList());
765751
}
766752

767-
private static ClusterSettings getClusterSettings(final List<ServerAddress> seedList, final MongoClientOptions options,
768-
final ClusterConnectionMode clusterConnectionMode) {
769-
ClusterSettings.Builder builder = ClusterSettings.builder()
770-
.hosts(new ArrayList<ServerAddress>(seedList))
771-
.mode(clusterConnectionMode)
772-
.requiredReplicaSetName(options.getRequiredReplicaSetName())
753+
private static ClusterSettings getClusterSettings(final ClusterSettings.Builder builder, final MongoClientOptions options) {
754+
builder.requiredReplicaSetName(options.getRequiredReplicaSetName())
773755
.serverSelectionTimeout(options.getServerSelectionTimeout(), MILLISECONDS)
774756
.localThreshold(options.getLocalThreshold(), MILLISECONDS)
775757
.serverSelector(options.getServerSelector())
@@ -781,6 +763,13 @@ private static ClusterSettings getClusterSettings(final List<ServerAddress> seed
781763
return builder.build();
782764
}
783765

766+
private static ClusterSettings getClusterSettings(final List<ServerAddress> seedList, final MongoClientOptions options,
767+
final ClusterConnectionMode clusterConnectionMode) {
768+
return getClusterSettings(ClusterSettings.builder()
769+
.hosts(new ArrayList<ServerAddress>(seedList))
770+
.mode(clusterConnectionMode), options);
771+
}
772+
784773
Cluster getCluster() {
785774
return delegate.getCluster();
786775
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ public MongoClientURI(final String uri, final MongoClientOptions.Builder builder
244244
proxied = new ConnectionString(uri);
245245
}
246246

247+
ConnectionString getProxied() {
248+
return proxied;
249+
}
250+
247251
// ---------------------------------
248252

249253
/**
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mongodb;
18+
19+
import com.mongodb.connection.ServerDescription;
20+
import com.mongodb.event.ClusterClosedEvent;
21+
import com.mongodb.event.ClusterDescriptionChangedEvent;
22+
import com.mongodb.event.ClusterListener;
23+
import com.mongodb.event.ClusterOpeningEvent;
24+
import org.bson.BsonArray;
25+
import org.bson.BsonBoolean;
26+
import org.bson.BsonDocument;
27+
import org.bson.BsonValue;
28+
import org.bson.Document;
29+
import org.junit.Test;
30+
import org.junit.runner.RunWith;
31+
import org.junit.runners.Parameterized;
32+
import util.JsonPoweredTestHelper;
33+
34+
import java.io.File;
35+
import java.io.IOException;
36+
import java.net.URISyntaxException;
37+
import java.util.ArrayList;
38+
import java.util.Collection;
39+
import java.util.List;
40+
import java.util.Map;
41+
import java.util.concurrent.CountDownLatch;
42+
import java.util.concurrent.TimeUnit;
43+
import java.util.concurrent.atomic.AtomicReference;
44+
45+
import static com.mongodb.ClusterFixture.getSslSettings;
46+
import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet;
47+
import static org.junit.Assert.assertEquals;
48+
import static org.junit.Assert.assertTrue;
49+
import static org.junit.Assert.fail;
50+
import static org.junit.Assume.assumeTrue;
51+
52+
// See https://github.com/mongodb/specifications/tree/master/source/initial-dns-seedlist-discovery/tests
53+
@RunWith(Parameterized.class)
54+
public class InitialDnsSeedlistDiscoveryTest {
55+
56+
private final String filename;
57+
private final String uri;
58+
private final List<String> seeds;
59+
private final List<ServerAddress> hosts;
60+
private final boolean isError;
61+
private final BsonDocument options;
62+
63+
public InitialDnsSeedlistDiscoveryTest(final String filename, final String uri, final List<String> seeds,
64+
final List<ServerAddress> hosts, final boolean isError, final BsonDocument options) {
65+
this.filename = filename;
66+
this.uri = uri;
67+
this.seeds = seeds;
68+
this.hosts = hosts;
69+
this.isError = isError;
70+
this.options = options;
71+
}
72+
73+
@Test
74+
public void shouldResolveTxtRecord() throws InterruptedException {
75+
if (isError) {
76+
MongoClient client = null;
77+
try {
78+
final AtomicReference<MongoException> exceptionReference = new AtomicReference<MongoException>();
79+
final CountDownLatch latch = new CountDownLatch(1);
80+
MongoClientOptions.Builder builder = MongoClientOptions.builder().addClusterListener(
81+
new ClusterListener() {
82+
@Override
83+
public void clusterOpening(final ClusterOpeningEvent event) {
84+
}
85+
86+
@Override
87+
public void clusterClosed(final ClusterClosedEvent event) {
88+
}
89+
90+
@Override
91+
public void clusterDescriptionChanged(final ClusterDescriptionChangedEvent event) {
92+
if (event.getNewDescription().getSrvResolutionException() != null) {
93+
exceptionReference.set(event.getNewDescription().getSrvResolutionException());
94+
latch.countDown();
95+
}
96+
}
97+
});
98+
client = new MongoClient(new MongoClientURI(uri, builder));
99+
if (!latch.await(5, TimeUnit.SECONDS)) {
100+
fail("");
101+
}
102+
throw exceptionReference.get();
103+
} catch (IllegalArgumentException e) {
104+
// all good
105+
} catch (MongoClientException e) {
106+
// all good
107+
} finally {
108+
if (client != null) {
109+
client.close();
110+
}
111+
}
112+
} else {
113+
ConnectionString connectionString = new ConnectionString(this.uri);
114+
115+
for (Map.Entry<String, BsonValue> entry : options.entrySet()) {
116+
if (entry.getKey().equals("replicaSet")) {
117+
assertEquals(entry.getValue().asString().getValue(), connectionString.getRequiredReplicaSetName());
118+
} else if (entry.getKey().equals("ssl")) {
119+
assertEquals(entry.getValue().asBoolean().getValue(), connectionString.getSslEnabled());
120+
} else if (entry.getKey().equals("authSource")) {
121+
// ignoring authSource for now, because without at least a userName also in the connection string,
122+
// the authSource is ignored. If the test gets this far, at least we know that a TXT record
123+
// containing in authSource doesn't blow up. We just don't test that it's actually used.
124+
assertTrue(true);
125+
} else {
126+
throw new UnsupportedOperationException("No support configured yet for " + entry.getKey());
127+
}
128+
}
129+
}
130+
}
131+
132+
@Test
133+
public void shouldDiscoverSrvRecord() throws InterruptedException {
134+
if (seeds.isEmpty()) {
135+
return;
136+
}
137+
final CountDownLatch latch = new CountDownLatch(1);
138+
139+
MongoClientOptions.Builder builder = MongoClientOptions.builder().addClusterListener(
140+
new ClusterListener() {
141+
@Override
142+
public void clusterOpening(final ClusterOpeningEvent event) {
143+
}
144+
145+
@Override
146+
public void clusterClosed(final ClusterClosedEvent event) {
147+
}
148+
149+
@Override
150+
public void clusterDescriptionChanged(final ClusterDescriptionChangedEvent event) {
151+
List<ServerAddress> curHostList = new ArrayList<ServerAddress>();
152+
for (ServerDescription cur : event.getNewDescription().getServerDescriptions()) {
153+
if (cur.isOk()) {
154+
curHostList.add(cur.getAddress());
155+
}
156+
}
157+
if (hosts.size() == curHostList.size() && curHostList.containsAll(hosts)) {
158+
latch.countDown();
159+
}
160+
}
161+
});
162+
MongoClientURI mongoClientURI = new MongoClientURI(uri, builder);
163+
assumeTrue("It's not a replica set", isDiscoverableReplicaSet());
164+
assumeTrue("SSL settings don't match", getSslSettings().isEnabled() == getSslSettings(mongoClientURI.getProxied()).isEnabled());
165+
166+
MongoClient client = new MongoClient(mongoClientURI);
167+
168+
try {
169+
assertTrue(latch.await(500, TimeUnit.SECONDS));
170+
assertTrue(client.getDatabase("admin").runCommand(new Document("ping", 1)).containsKey("ok"));
171+
} finally {
172+
client.close();
173+
}
174+
}
175+
176+
@Parameterized.Parameters(name = "{0}")
177+
public static Collection<Object[]> data() throws URISyntaxException, IOException {
178+
List<Object[]> data = new ArrayList<Object[]>();
179+
for (File file : JsonPoweredTestHelper.getTestFiles("/initial-dns-seedlist-discovery")) {
180+
BsonDocument testDocument = JsonPoweredTestHelper.getTestDocument(file);
181+
data.add(new Object[]{
182+
file.getName(),
183+
testDocument.getString("uri").getValue(),
184+
toStringList(testDocument.getArray("seeds")),
185+
toServerAddressList(testDocument.getArray("hosts")),
186+
testDocument.getBoolean("error", BsonBoolean.FALSE).getValue(),
187+
testDocument.getDocument("options", new BsonDocument())
188+
});
189+
190+
}
191+
return data;
192+
}
193+
194+
private static List<String> toStringList(final BsonArray bsonArray) {
195+
List<String> retVal = new ArrayList<String>(bsonArray.size());
196+
for (BsonValue cur : bsonArray) {
197+
retVal.add(cur.asString().getValue());
198+
}
199+
return retVal;
200+
}
201+
202+
private static List<ServerAddress> toServerAddressList(final BsonArray bsonArray) {
203+
List<ServerAddress> retVal = new ArrayList<ServerAddress>(bsonArray.size());
204+
for (BsonValue cur : bsonArray) {
205+
retVal.add(new ServerAddress(cur.asString().getValue()));
206+
}
207+
return retVal;
208+
}
209+
}

0 commit comments

Comments
 (0)