Skip to content

Commit 0ab5590

Browse files
committed
Add topology version to server description
JAVA-3696
1 parent d917045 commit 0ab5590

File tree

6 files changed

+202
-7
lines changed

6 files changed

+202
-7
lines changed

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ public class ServerDescription {
8585

8686
private final ObjectId electionId;
8787
private final Integer setVersion;
88+
private final TopologyVersion topologyVersion;
89+
8890
private final Date lastWriteDate;
8991
private final long lastUpdateTimeNanos;
9092

@@ -156,6 +158,7 @@ public static class Builder {
156158
private int maxWireVersion = 0;
157159
private ObjectId electionId;
158160
private Integer setVersion;
161+
private TopologyVersion topologyVersion;
159162
private Date lastWriteDate;
160163
private long lastUpdateTimeNanos = Time.nanoTime();
161164
private Integer logicalSessionTimeoutMinutes;
@@ -183,6 +186,7 @@ public static class Builder {
183186
this.maxWireVersion = serverDescription.maxWireVersion;
184187
this.electionId = serverDescription.electionId;
185188
this.setVersion = serverDescription.setVersion;
189+
this.topologyVersion = serverDescription.topologyVersion;
186190
this.lastWriteDate = serverDescription.lastWriteDate;
187191
this.lastUpdateTimeNanos = serverDescription.lastUpdateTimeNanos;
188192
this.logicalSessionTimeoutMinutes = serverDescription.logicalSessionTimeoutMinutes;
@@ -382,6 +386,19 @@ public Builder setVersion(final Integer setVersion) {
382386
return this;
383387
}
384388

389+
/**
390+
* Sets the topologyVersion reported by this server.
391+
*
392+
* @param topologyVersion the topology version
393+
* @return this
394+
* @since 4.1
395+
* @mongodb.server.release 4.4
396+
*/
397+
public Builder topologyVersion(final TopologyVersion topologyVersion) {
398+
this.topologyVersion = topologyVersion;
399+
return this;
400+
}
401+
385402
/**
386403
* Sets the lastWriteDate reported by this server
387404
*
@@ -440,7 +457,7 @@ public Builder exception(final Throwable exception) {
440457
*
441458
* @return a new server description
442459
*/
443-
public ServerDescription build() {
460+
public ServerDescription build() {
444461
return new ServerDescription(this);
445462
}
446463
}
@@ -659,6 +676,17 @@ public Integer getSetVersion() {
659676
return setVersion;
660677
}
661678

679+
/**
680+
* The topologyVersion reported by this MongoDB server.
681+
*
682+
* @return the topologyVersion, which may be null
683+
* @since 4.1
684+
* @mongodb.server.release 4.4
685+
*/
686+
public TopologyVersion getTopologyVersion() {
687+
return topologyVersion;
688+
}
689+
662690
/**
663691
* Gets the last write date.
664692
* @return the last write date, which may be null
@@ -832,6 +860,10 @@ public boolean equals(final Object o) {
832860
if (setVersion != null ? !setVersion.equals(that.setVersion) : that.setVersion != null) {
833861
return false;
834862
}
863+
if (topologyVersion != null ? !topologyVersion.equals(that.topologyVersion) : that.topologyVersion != null) {
864+
return false;
865+
}
866+
835867
if (lastWriteDate != null ? !lastWriteDate.equals(that.lastWriteDate) : that.lastWriteDate != null) {
836868
return false;
837869
}
@@ -876,6 +908,7 @@ public int hashCode() {
876908
result = 31 * result + (setName != null ? setName.hashCode() : 0);
877909
result = 31 * result + (electionId != null ? electionId.hashCode() : 0);
878910
result = 31 * result + (setVersion != null ? setVersion.hashCode() : 0);
911+
result = 31 * result + (topologyVersion != null ? topologyVersion.hashCode() : 0);
879912
result = 31 * result + (lastWriteDate != null ? lastWriteDate.hashCode() : 0);
880913
result = 31 * result + (int) (lastUpdateTimeNanos ^ (lastUpdateTimeNanos >>> 32));
881914
result = 31 * result + (ok ? 1 : 0);
@@ -914,6 +947,7 @@ public String toString() {
914947
+ ", tagSet=" + tagSet
915948
+ ", electionId=" + electionId
916949
+ ", setVersion=" + setVersion
950+
+ ", topologyVersion=" + topologyVersion
917951
+ ", lastWriteDate=" + lastWriteDate
918952
+ ", lastUpdateTimeNanos=" + lastUpdateTimeNanos
919953
: "")
@@ -977,6 +1011,7 @@ private String getRoundTripFormattedInMilliseconds() {
9771011
maxWireVersion = builder.maxWireVersion;
9781012
electionId = builder.electionId;
9791013
setVersion = builder.setVersion;
1014+
topologyVersion = builder.topologyVersion;
9801015
lastWriteDate = builder.lastWriteDate;
9811016
lastUpdateTimeNanos = builder.lastUpdateTimeNanos;
9821017
logicalSessionTimeoutMinutes = builder.logicalSessionTimeoutMinutes;
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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.connection;
18+
19+
import com.mongodb.annotations.ThreadSafe;
20+
import org.bson.BsonDocument;
21+
import org.bson.BsonInt64;
22+
import org.bson.BsonObjectId;
23+
import org.bson.types.ObjectId;
24+
25+
/**
26+
* The topology version of a cluster.
27+
*
28+
* @since 4.1
29+
* @mongodb.server.release 4.4
30+
*/
31+
@ThreadSafe
32+
public final class TopologyVersion {
33+
private final ObjectId processId;
34+
private final long counter;
35+
36+
/**
37+
* Construct a new instance from a document description
38+
*
39+
* @param topologyVersionDocument a document description of the topology version
40+
*/
41+
public TopologyVersion(final BsonDocument topologyVersionDocument) {
42+
processId = topologyVersionDocument.getObjectId("processId").getValue();
43+
counter = topologyVersionDocument.getInt64("counter").getValue();
44+
}
45+
46+
/**
47+
* Construct a new instance from process identifier and counter
48+
*
49+
* @param processId the process identifer
50+
* @param counter the counter
51+
*/
52+
public TopologyVersion(final ObjectId processId, final long counter) {
53+
this.processId = processId;
54+
this.counter = counter;
55+
}
56+
57+
/**
58+
* Get the process identifier
59+
*
60+
* @return the process identifier
61+
*/
62+
public ObjectId getProcessId() {
63+
return processId;
64+
}
65+
66+
/**
67+
* Get the counter
68+
*
69+
* @return the counter
70+
*/
71+
public long getCounter() {
72+
return counter;
73+
}
74+
75+
/**
76+
* Get the document representation of the topology version
77+
*
78+
* @return the document representation of the topology version
79+
*/
80+
public BsonDocument asDocument() {
81+
return new BsonDocument("processId", new BsonObjectId(processId))
82+
.append("counter", new BsonInt64(counter));
83+
84+
}
85+
86+
@Override
87+
public boolean equals(final Object o) {
88+
if (this == o) {
89+
return true;
90+
}
91+
if (o == null || getClass() != o.getClass()) {
92+
return false;
93+
}
94+
95+
TopologyVersion that = (TopologyVersion) o;
96+
97+
if (counter != that.counter) {
98+
return false;
99+
}
100+
return processId.equals(that.processId);
101+
}
102+
103+
@Override
104+
public int hashCode() {
105+
int result = processId.hashCode();
106+
result = 31 * result + (int) (counter ^ (counter >>> 32));
107+
return result;
108+
}
109+
110+
@Override
111+
public String toString() {
112+
return "TopologyVersion{"
113+
+ "processId=" + processId
114+
+ ", counter=" + counter
115+
+ '}';
116+
}
117+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.mongodb.connection.ConnectionId;
2424
import com.mongodb.connection.ServerDescription;
2525
import com.mongodb.connection.ServerType;
26+
import com.mongodb.connection.TopologyVersion;
2627
import org.bson.BsonArray;
2728
import org.bson.BsonBoolean;
2829
import org.bson.BsonDocument;
@@ -88,6 +89,7 @@ public static ServerDescription createServerDescription(final ServerAddress serv
8889
.maxWireVersion(getMaxWireVersion(isMasterResult))
8990
.electionId(getElectionId(isMasterResult))
9091
.setVersion(getSetVersion(isMasterResult))
92+
.topologyVersion(getTopologyVersion(isMasterResult))
9193
.lastWriteDate(getLastWriteDate(isMasterResult))
9294
.roundTripTime(roundTripTime, NANOSECONDS)
9395
.logicalSessionTimeoutMinutes(getLogicalSessionTimeoutMinutes(isMasterResult))
@@ -117,6 +119,10 @@ private static Integer getSetVersion(final BsonDocument isMasterResult) {
117119
return isMasterResult.containsKey("setVersion") ? isMasterResult.getNumber("setVersion").intValue() : null;
118120
}
119121

122+
private static TopologyVersion getTopologyVersion(final BsonDocument isMasterResult) {
123+
return isMasterResult.containsKey("topologyVersion") ? new TopologyVersion(isMasterResult.getDocument("topologyVersion")) : null;
124+
}
125+
120126
private static int getMaxMessageSizeBytes(final BsonDocument isMasterResult) {
121127
return isMasterResult.getInt32("maxMessageSizeBytes", new BsonInt32(getDefaultMaxMessageSize())).getValue();
122128
}

driver-core/src/test/unit/com/mongodb/connection/ServerDescriptionTest.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public void testDefaults() throws UnknownHostException {
9595
assertEquals(0, serverDescription.getMaxWireVersion());
9696
assertNull(serverDescription.getElectionId());
9797
assertNull(serverDescription.getSetVersion());
98+
assertNull(serverDescription.getTopologyVersion());
9899
assertNull(serverDescription.getLastWriteDate());
99100
assertTrue(serverDescription.getLastUpdateTime(TimeUnit.NANOSECONDS) > currentNanoTime);
100101
assertNull(serverDescription.getLogicalSessionTimeoutMinutes());
@@ -104,6 +105,7 @@ public void testDefaults() throws UnknownHostException {
104105
@Test
105106
public void testBuilder() throws UnknownHostException {
106107
IllegalArgumentException exception = new IllegalArgumentException();
108+
TopologyVersion topologyVersion = new TopologyVersion(new ObjectId(), 42);
107109
ServerDescription serverDescription = builder()
108110
.address(new ServerAddress("localhost:27018"))
109111
.type(ServerType.REPLICA_SET_PRIMARY)
@@ -125,6 +127,7 @@ public void testBuilder() throws UnknownHostException {
125127
.maxWireVersion(2)
126128
.electionId(new ObjectId("123412341234123412341234"))
127129
.setVersion(2)
130+
.topologyVersion(topologyVersion)
128131
.lastWriteDate(new Date(1234L))
129132
.lastUpdateTimeNanos(40000L)
130133
.logicalSessionTimeoutMinutes(30)
@@ -160,6 +163,7 @@ public void testBuilder() throws UnknownHostException {
160163
assertEquals(2, serverDescription.getMaxWireVersion());
161164
assertEquals(new ObjectId("123412341234123412341234"), serverDescription.getElectionId());
162165
assertEquals(Integer.valueOf(2), serverDescription.getSetVersion());
166+
assertEquals(topologyVersion, serverDescription.getTopologyVersion());
163167
assertEquals(new Date(1234), serverDescription.getLastWriteDate());
164168
assertEquals(40000L, serverDescription.getLastUpdateTime(TimeUnit.NANOSECONDS));
165169
assertEquals((Integer) 30, serverDescription.getLogicalSessionTimeoutMinutes());
@@ -229,6 +233,9 @@ public void testObjectOverrides() throws UnknownHostException {
229233
otherDescription = createBuilder().setVersion(3).build();
230234
assertNotEquals(builder.build(), otherDescription);
231235

236+
otherDescription = createBuilder().topologyVersion(new TopologyVersion(new ObjectId(), 44)).build();
237+
assertNotEquals(builder.build(), otherDescription);
238+
232239
// test exception state changes
233240
assertNotEquals(createBuilder().exception(new IOException()).build(),
234241
createBuilder().exception(new RuntimeException()).build());
@@ -250,6 +257,32 @@ public void testObjectOverrides() throws UnknownHostException {
250257
assertEquals(builder.build(), otherDescription);
251258
}
252259

260+
private ServerDescription.Builder createBuilder() {
261+
return builder().address(new ServerAddress())
262+
.type(ServerType.SHARD_ROUTER)
263+
.tagSet(new TagSet(singletonList(new Tag("dc", "ny"))))
264+
.setName("test")
265+
.maxDocumentSize(100)
266+
.roundTripTime(50000, TimeUnit.NANOSECONDS)
267+
.primary("localhost:27017")
268+
.canonicalAddress("localhost:27017")
269+
.hosts(new HashSet<String>(asList("localhost:27017", "localhost:27018")))
270+
.passives(new HashSet<String>(singletonList("localhost:27019")))
271+
.arbiters(new HashSet<String>(singletonList("localhost:27020")))
272+
.ok(true)
273+
.state(CONNECTED)
274+
.minWireVersion(1)
275+
.lastWriteDate(new Date())
276+
.maxWireVersion(2)
277+
.electionId(new ObjectId("abcdabcdabcdabcdabcdabcd"))
278+
.setVersion(2)
279+
.topologyVersion(new TopologyVersion(new ObjectId("5e47699e32e4571020a96f07"), 42))
280+
.lastUpdateTimeNanos(1)
281+
.lastWriteDate(new Date(42))
282+
.logicalSessionTimeoutMinutes(25)
283+
.roundTripTime(56, TimeUnit.MILLISECONDS);
284+
}
285+
253286
@Test
254287
public void testObjectOverridesWithUnequalException() throws UnknownHostException {
255288
ServerDescription.Builder builder1 = builder()
@@ -495,8 +528,4 @@ public void serverWithMaxWireVersionLessThanDriverMinWireVersionShouldBeIncompat
495528
.lastWriteDate(new Date(42))
496529
.logicalSessionTimeoutMinutes(25)
497530
.roundTripTime(56, TimeUnit.MILLISECONDS).build();
498-
499-
private ServerDescription.Builder createBuilder() {
500-
return builder(SERVER_DESCRIPTION);
501-
}
502531
}

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import com.mongodb.connection.ServerConnectionState
2626
import com.mongodb.connection.ServerDescription
2727
import com.mongodb.connection.ServerId
2828
import com.mongodb.connection.ServerType
29+
import com.mongodb.connection.TopologyVersion
2930
import org.bson.types.ObjectId
3031
import spock.lang.Specification
3132

@@ -243,7 +244,8 @@ class DescriptionHelperSpecification extends Specification {
243244

244245
def 'server description should reflect ismaster result from primary'() {
245246
given:
246-
ObjectId electionId = new ObjectId();
247+
ObjectId electionId = new ObjectId()
248+
ObjectId topologyVersionProcessId = new ObjectId()
247249

248250
when:
249251
def serverDescription = createServerDescription(serverAddress,
@@ -269,6 +271,10 @@ class DescriptionHelperSpecification extends Specification {
269271
"maxWireVersion" : 3,
270272
"minWireVersion" : 0,
271273
"electionId" : {\$oid : "${electionId.toHexString()}" },
274+
"topologyVersion" : {
275+
processId: {\$oid : "${topologyVersionProcessId.toHexString()}"},
276+
counter: {\$numberLong : "42"}
277+
},
272278
"setVersion" : 2,
273279
tags : { "dc" : "east", "use" : "production" }
274280
"ok" : 1
@@ -284,6 +290,7 @@ class DescriptionHelperSpecification extends Specification {
284290
.maxDocumentSize(16777216)
285291
.electionId(electionId)
286292
.setVersion(2)
293+
.topologyVersion(new TopologyVersion(topologyVersionProcessId, 42))
287294
.type(ServerType.REPLICA_SET_PRIMARY)
288295
.setName('replset')
289296
.primary('localhost:27017')

driver-scala/src/test/scala/org/mongodb/scala/ApiAliasAndCompanionSpec.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ class ApiAliasAndCompanionSpec extends BaseSpec {
180180
"ServerVersion",
181181
"SocketStreamFactory",
182182
"Stream",
183-
"SplittablePayload"
183+
"SplittablePayload",
184+
"TopologyVersion"
184185
)
185186

186187
val filters = FilterBuilder.parse("-com.mongodb.connection.netty.*")

0 commit comments

Comments
 (0)