Skip to content

Commit e0c8bd1

Browse files
committed
JAVA-1996: Detect hidden members of a replica set and treat them as type REPLICA_SET_OTHER instead of REPLICA_SET_SECONDARY.
In practice, this will only come in to play when a hidden replica member is included in the initial host seed list, as hidden members do not appear in other members ismaster hosts lists.
1 parent 8a3c72d commit e0c8bd1

File tree

3 files changed

+87
-8
lines changed

3 files changed

+87
-8
lines changed

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

+6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import static com.mongodb.connection.ServerDescription.getDefaultMaxWireVersion;
4242
import static com.mongodb.connection.ServerDescription.getDefaultMinWireVersion;
4343
import static com.mongodb.connection.ServerType.REPLICA_SET_ARBITER;
44+
import static com.mongodb.connection.ServerType.REPLICA_SET_OTHER;
4445
import static com.mongodb.connection.ServerType.REPLICA_SET_PRIMARY;
4546
import static com.mongodb.connection.ServerType.REPLICA_SET_SECONDARY;
4647
import static com.mongodb.connection.ServerType.SHARD_ROUTER;
@@ -136,6 +137,11 @@ private static ServerType getServerType(final BsonDocument isMasterResult) {
136137
}
137138

138139
if (isReplicaSetMember(isMasterResult)) {
140+
141+
if (isMasterResult.getBoolean("hidden", BsonBoolean.FALSE).getValue()) {
142+
return REPLICA_SET_OTHER;
143+
}
144+
139145
if (isMasterResult.getBoolean("ismaster", BsonBoolean.FALSE).getValue()) {
140146
return REPLICA_SET_PRIMARY;
141147
}

driver-core/src/test/resources/server-discovery-and-monitoring/rs/rsother_discovered.json

+26-4
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,46 @@
55
"outcome": {
66
"servers": {
77
"a:27017": {
8-
"setName": null,
9-
"type": "Unknown"
8+
"setName": "rs",
9+
"type": "RSOther"
1010
},
1111
"b:27017": {
1212
"setName": "rs",
1313
"type": "RSOther"
14+
},
15+
"c:27017": {
16+
"setName": null,
17+
"type": "Unknown"
18+
},
19+
"d:27017": {
20+
"setName": null,
21+
"type": "Unknown"
1422
}
1523
},
1624
"setName": "rs",
1725
"topologyType": "ReplicaSetNoPrimary"
1826
},
1927
"responses": [
28+
[
29+
"a:27017",
30+
{
31+
"hidden": true,
32+
"hosts": [
33+
"c:27017",
34+
"d:27017"
35+
],
36+
"ismaster": false,
37+
"ok": 1,
38+
"secondary": true,
39+
"setName": "rs"
40+
}
41+
],
2042
[
2143
"b:27017",
2244
{
2345
"hosts": [
24-
"a:27017",
25-
"b:27017"
46+
"c:27017",
47+
"d:27017"
2648
],
2749
"ismaster": false,
2850
"ok": 1,

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

+55-4
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,11 @@ class DescriptionHelperSpecification extends Specification {
263263
}
264264

265265
def 'server description should reflect ismaster result from other'() {
266+
given:
267+
def serverAddressOfHidden = new ServerAddress('localhost', 27020)
268+
266269
expect:
267-
createServerDescription(serverAddress,
270+
createServerDescription(serverAddressOfHidden,
268271
parse('{' +
269272
'"setName" : "replset",' +
270273
'"setVersion" : 1,' +
@@ -276,7 +279,7 @@ class DescriptionHelperSpecification extends Specification {
276279
'"localhost:27017"' +
277280
'],' +
278281
'"arbiters" : [' +
279-
'"localhost:27020"' +
282+
'"localhost:27021"' +
280283
'],' +
281284
'"primary" : "localhost:27017",' +
282285
'"arbiterOnly" : false,' +
@@ -291,7 +294,7 @@ class DescriptionHelperSpecification extends Specification {
291294
'}'), serverVersion, roundTripTime) ==
292295
ServerDescription.builder()
293296
.ok(true)
294-
.address(serverAddress)
297+
.address(serverAddressOfHidden)
295298
.state(ServerConnectionState.CONNECTED)
296299
.version(serverVersion)
297300
.maxWireVersion(3)
@@ -301,10 +304,58 @@ class DescriptionHelperSpecification extends Specification {
301304
.primary('localhost:27017')
302305
.canonicalAddress('localhost:27020')
303306
.hosts(['localhost:27017', 'localhost:27018', 'localhost:27019'] as Set)
304-
.arbiters(['localhost:27020'] as Set)
307+
.arbiters(['localhost:27021'] as Set)
305308
.build()
306309
}
307310

311+
def 'server description should reflect ismaster result from hidden'() {
312+
given:
313+
def serverAddressOfHidden = new ServerAddress('localhost', 27020)
314+
315+
expect:
316+
createServerDescription(serverAddressOfHidden,
317+
parse('{' +
318+
'"setName" : "replset",' +
319+
'"setVersion" : 1,' +
320+
'"ismaster" : false,' +
321+
'"secondary" : true,' +
322+
'"hidden" : true,' +
323+
'"hosts" : [' +
324+
'"localhost:27019",' +
325+
'"localhost:27018",' +
326+
'"localhost:27017"' +
327+
'],' +
328+
'"arbiters" : [' +
329+
'"localhost:27021"' +
330+
'],' +
331+
'"primary" : "localhost:27017",' +
332+
'"arbiterOnly" : false,' +
333+
'"me" : "localhost:27020",' +
334+
'"maxBsonObjectSize" : 16777216,' +
335+
'"maxMessageSizeBytes" : 48000000,' +
336+
'"maxWriteBatchSize" : 1000,' +
337+
'"localTime" : ISODate("2015-03-04T23:27:55.568Z"),' +
338+
'"maxWireVersion" : 3,' +
339+
'"minWireVersion" : 0,' +
340+
'"ok" : 1' +
341+
'}'), serverVersion, roundTripTime) ==
342+
ServerDescription.builder()
343+
.ok(true)
344+
.address(serverAddressOfHidden)
345+
.state(ServerConnectionState.CONNECTED)
346+
.version(serverVersion)
347+
.maxWireVersion(3)
348+
.maxDocumentSize(16777216)
349+
.type(ServerType.REPLICA_SET_OTHER)
350+
.setName('replset')
351+
.primary('localhost:27017')
352+
.canonicalAddress('localhost:27020')
353+
.hosts(['localhost:27017', 'localhost:27018', 'localhost:27019'] as Set)
354+
.arbiters(['localhost:27021'] as Set)
355+
.build()
356+
}
357+
358+
308359
def 'server description should reflect ismaster result from ghost'() {
309360
expect:
310361
createServerDescription(serverAddress,

0 commit comments

Comments
 (0)