Skip to content

Commit b139199

Browse files
committed
Support the serverMonitoringMode connection string option
This change is with accordance to source/uri-options/uri-options.rst. JAVA-4936
1 parent 63562c6 commit b139199

File tree

10 files changed

+420
-25
lines changed

10 files changed

+420
-25
lines changed

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import com.mongodb.connection.ClusterSettings;
2020
import com.mongodb.connection.ConnectionPoolSettings;
21+
import com.mongodb.connection.ServerMonitoringMode;
22+
import com.mongodb.connection.ServerSettings;
2123
import com.mongodb.connection.SocketSettings;
2224
import com.mongodb.event.ConnectionCheckOutStartedEvent;
2325
import com.mongodb.event.ConnectionCheckedInEvent;
@@ -111,6 +113,13 @@
111113
* <ul>
112114
* <li>{@code heartbeatFrequencyMS=ms}: The frequency that the driver will attempt to determine the current state of each server in the
113115
* cluster.</li>
116+
* <li>{@code serverMonitoringMode=enum}: The server monitoring mode, which defines the monitoring protocol to use. Enumerated values:
117+
* <ul>
118+
* <li>{@code stream};</li>
119+
* <li>{@code poll};</li>
120+
* <li>{@code auto} - the default.</li>
121+
* </ul>
122+
* </li>
114123
* </ul>
115124
* <p>Replica set configuration:</p>
116125
* <ul>
@@ -307,6 +316,7 @@ public class ConnectionString {
307316
private Integer serverSelectionTimeout;
308317
private Integer localThreshold;
309318
private Integer heartbeatFrequency;
319+
private ServerMonitoringMode serverMonitoringMode;
310320
private String applicationName;
311321
private List<MongoCompressor> compressorList;
312322
private UuidRepresentation uuidRepresentation;
@@ -529,6 +539,7 @@ public ConnectionString(final String connectionString, @Nullable final DnsClient
529539
GENERAL_OPTIONS_KEYS.add("serverselectiontimeoutms");
530540
GENERAL_OPTIONS_KEYS.add("localthresholdms");
531541
GENERAL_OPTIONS_KEYS.add("heartbeatfrequencyms");
542+
GENERAL_OPTIONS_KEYS.add("servermonitoringmode");
532543
GENERAL_OPTIONS_KEYS.add("retrywrites");
533544
GENERAL_OPTIONS_KEYS.add("retryreads");
534545

@@ -665,6 +676,9 @@ private void translateOptions(final Map<String, List<String>> optionsMap) {
665676
case "heartbeatfrequencyms":
666677
heartbeatFrequency = parseInteger(value, "heartbeatfrequencyms");
667678
break;
679+
case "servermonitoringmode":
680+
serverMonitoringMode = ServerMonitoringMode.fromString(value);
681+
break;
668682
case "appname":
669683
applicationName = value;
670684
break;
@@ -1623,6 +1637,20 @@ public Integer getHeartbeatFrequency() {
16231637
return heartbeatFrequency;
16241638
}
16251639

1640+
/**
1641+
* The server monitoring mode, which defines the monitoring protocol to use.
1642+
* <p>
1643+
* Default is {@link ServerMonitoringMode#AUTO}.</p>
1644+
*
1645+
* @return The {@link ServerMonitoringMode}, or {@code null} if unset and the default is to be used.
1646+
* @see ServerSettings#getServerMonitoringMode()
1647+
* @since 5.1
1648+
*/
1649+
@Nullable
1650+
public ServerMonitoringMode getServerMonitoringMode() {
1651+
return serverMonitoringMode;
1652+
}
1653+
16261654
/**
16271655
* Gets the logical name of the application. The application name may be used by the client to identify the application to the server,
16281656
* for use in server logs, slow query logs, and profile collection.
@@ -1704,6 +1732,7 @@ public boolean equals(final Object o) {
17041732
&& Objects.equals(serverSelectionTimeout, that.serverSelectionTimeout)
17051733
&& Objects.equals(localThreshold, that.localThreshold)
17061734
&& Objects.equals(heartbeatFrequency, that.heartbeatFrequency)
1735+
&& Objects.equals(serverMonitoringMode, that.serverMonitoringMode)
17071736
&& Objects.equals(applicationName, that.applicationName)
17081737
&& Objects.equals(compressorList, that.compressorList)
17091738
&& Objects.equals(uuidRepresentation, that.uuidRepresentation)
@@ -1717,7 +1746,7 @@ public int hashCode() {
17171746
writeConcern, retryWrites, retryReads, readConcern, minConnectionPoolSize, maxConnectionPoolSize, maxWaitTime,
17181747
maxConnectionIdleTime, maxConnectionLifeTime, maxConnecting, connectTimeout, socketTimeout, sslEnabled,
17191748
sslInvalidHostnameAllowed, requiredReplicaSetName, serverSelectionTimeout, localThreshold, heartbeatFrequency,
1720-
applicationName, compressorList, uuidRepresentation, srvServiceName, srvMaxHosts, proxyHost, proxyPort,
1721-
proxyUsername, proxyPassword);
1749+
serverMonitoringMode, applicationName, compressorList, uuidRepresentation, srvServiceName, srvMaxHosts, proxyHost,
1750+
proxyPort, proxyUsername, proxyPassword);
17221751
}
17231752
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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+
package com.mongodb.connection;
17+
18+
import static com.mongodb.assertions.Assertions.notNull;
19+
import static java.lang.String.format;
20+
21+
/**
22+
* The server monitoring mode, which defines the monitoring protocol to use.
23+
*
24+
* @since 5.1
25+
*/
26+
public enum ServerMonitoringMode {
27+
/**
28+
* Use the streaming protocol whe the server supports it or fall back to the polling protocol otherwise.
29+
*/
30+
STREAM("stream"),
31+
/**
32+
* Use the polling protocol.
33+
*/
34+
POLL("poll"),
35+
/**
36+
* Behave the same as {@link #POLL} if running in a FaaS environment, otherwise behave as {@link #STREAM}.
37+
* This is the default.
38+
*/
39+
AUTO("auto");
40+
41+
private final String value;
42+
43+
ServerMonitoringMode(final String value) {
44+
this.value = value;
45+
}
46+
47+
/**
48+
* Parses a string into {@link ServerMonitoringMode}.
49+
*
50+
* @param serverMonitoringMode A server monitoring mode string.
51+
* @return The corresponding {@link ServerMonitoringMode} value.
52+
* @see #getValue()
53+
*/
54+
public static ServerMonitoringMode fromString(final String serverMonitoringMode) {
55+
notNull("serverMonitoringMode", serverMonitoringMode);
56+
for (ServerMonitoringMode mode : ServerMonitoringMode.values()) {
57+
if (serverMonitoringMode.equalsIgnoreCase(mode.value)) {
58+
return mode;
59+
}
60+
}
61+
throw new IllegalArgumentException(format("'%s' is not a valid %s",
62+
serverMonitoringMode, ServerMonitoringMode.class.getSimpleName()));
63+
}
64+
65+
/**
66+
* The string value.
67+
*
68+
* @return The string value.
69+
* @see #fromString(String)
70+
*/
71+
public String getValue() {
72+
return value;
73+
}
74+
}

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

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import java.util.ArrayList;
2626
import java.util.List;
27+
import java.util.Objects;
2728
import java.util.concurrent.TimeUnit;
2829

2930
import static com.mongodb.assertions.Assertions.notNull;
@@ -38,6 +39,7 @@
3839
public class ServerSettings {
3940
private final long heartbeatFrequencyMS;
4041
private final long minHeartbeatFrequencyMS;
42+
private final ServerMonitoringMode serverMonitoringMode;
4143
private final List<ServerListener> serverListeners;
4244
private final List<ServerMonitorListener> serverMonitorListeners;
4345

@@ -68,6 +70,7 @@ public static Builder builder(final ServerSettings serverSettings) {
6870
public static final class Builder {
6971
private long heartbeatFrequencyMS = 10000;
7072
private long minHeartbeatFrequencyMS = 500;
73+
private ServerMonitoringMode serverMonitoringMode = ServerMonitoringMode.AUTO;
7174
private List<ServerListener> serverListeners = new ArrayList<>();
7275
private List<ServerMonitorListener> serverMonitorListeners = new ArrayList<>();
7376

@@ -87,6 +90,7 @@ public Builder applySettings(final ServerSettings serverSettings) {
8790
notNull("serverSettings", serverSettings);
8891
heartbeatFrequencyMS = serverSettings.heartbeatFrequencyMS;
8992
minHeartbeatFrequencyMS = serverSettings.minHeartbeatFrequencyMS;
93+
serverMonitoringMode = serverSettings.serverMonitoringMode;
9094
serverListeners = new ArrayList<>(serverSettings.serverListeners);
9195
serverMonitorListeners = new ArrayList<>(serverSettings.serverMonitorListeners);
9296
return this;
@@ -117,6 +121,20 @@ public Builder minHeartbeatFrequency(final long minHeartbeatFrequency, final Tim
117121
return this;
118122
}
119123

124+
/**
125+
* Sets the server monitoring mode, which defines the monitoring protocol to use.
126+
* The default value is {@link ServerMonitoringMode#AUTO}.
127+
*
128+
* @param serverMonitoringMode The {@link ServerMonitoringMode}.
129+
* @return {@code this}.
130+
* @see #getServerMonitoringMode()
131+
* @since 5.1
132+
*/
133+
public Builder serverMonitoringMode(final ServerMonitoringMode serverMonitoringMode) {
134+
this.serverMonitoringMode = notNull("serverMonitoringMode", serverMonitoringMode);
135+
return this;
136+
}
137+
120138
/**
121139
* Add a server listener.
122140
*
@@ -181,6 +199,10 @@ public Builder applyConnectionString(final ConnectionString connectionString) {
181199
if (heartbeatFrequency != null) {
182200
heartbeatFrequencyMS = heartbeatFrequency;
183201
}
202+
ServerMonitoringMode serverMonitoringMode = connectionString.getServerMonitoringMode();
203+
if (serverMonitoringMode != null) {
204+
this.serverMonitoringMode = serverMonitoringMode;
205+
}
184206
return this;
185207
}
186208

@@ -215,6 +237,19 @@ public long getMinHeartbeatFrequency(final TimeUnit timeUnit) {
215237
return timeUnit.convert(minHeartbeatFrequencyMS, TimeUnit.MILLISECONDS);
216238
}
217239

240+
/**
241+
* Gets the server monitoring mode, which defines the monitoring protocol to use.
242+
* The default value is {@link ServerMonitoringMode#AUTO}.
243+
*
244+
* @return The {@link ServerMonitoringMode}.
245+
* @see Builder#serverMonitoringMode(ServerMonitoringMode)
246+
* @see ConnectionString#getServerMonitoringMode()
247+
* @since 5.1
248+
*/
249+
public ServerMonitoringMode getServerMonitoringMode() {
250+
return serverMonitoringMode;
251+
}
252+
218253
/**
219254
* Gets the server listeners. The default value is an empty list.
220255
*
@@ -243,40 +278,30 @@ public boolean equals(final Object o) {
243278
if (o == null || getClass() != o.getClass()) {
244279
return false;
245280
}
246-
247-
ServerSettings that = (ServerSettings) o;
248-
249-
if (heartbeatFrequencyMS != that.heartbeatFrequencyMS) {
250-
return false;
251-
}
252-
if (minHeartbeatFrequencyMS != that.minHeartbeatFrequencyMS) {
253-
return false;
254-
}
255-
256-
if (!serverListeners.equals(that.serverListeners)) {
257-
return false;
258-
}
259-
if (!serverMonitorListeners.equals(that.serverMonitorListeners)) {
260-
return false;
261-
}
262-
263-
return true;
281+
final ServerSettings that = (ServerSettings) o;
282+
return heartbeatFrequencyMS == that.heartbeatFrequencyMS
283+
&& minHeartbeatFrequencyMS == that.minHeartbeatFrequencyMS
284+
&& serverMonitoringMode == that.serverMonitoringMode
285+
&& Objects.equals(serverListeners, that.serverListeners)
286+
&& Objects.equals(serverMonitorListeners, that.serverMonitorListeners);
264287
}
265288

266289
@Override
267290
public int hashCode() {
268-
int result = (int) (heartbeatFrequencyMS ^ (heartbeatFrequencyMS >>> 32));
269-
result = 31 * result + (int) (minHeartbeatFrequencyMS ^ (minHeartbeatFrequencyMS >>> 32));
270-
result = 31 * result + serverListeners.hashCode();
271-
result = 31 * result + serverMonitorListeners.hashCode();
272-
return result;
291+
return Objects.hash(
292+
heartbeatFrequencyMS,
293+
minHeartbeatFrequencyMS,
294+
serverMonitoringMode,
295+
serverListeners,
296+
serverMonitorListeners);
273297
}
274298

275299
@Override
276300
public String toString() {
277301
return "ServerSettings{"
278302
+ "heartbeatFrequencyMS=" + heartbeatFrequencyMS
279303
+ ", minHeartbeatFrequencyMS=" + minHeartbeatFrequencyMS
304+
+ ", serverMonitoringMode=" + serverMonitoringMode
280305
+ ", serverListeners='" + serverListeners + '\''
281306
+ ", serverMonitorListeners='" + serverMonitorListeners + '\''
282307
+ '}';
@@ -285,6 +310,7 @@ public String toString() {
285310
ServerSettings(final Builder builder) {
286311
heartbeatFrequencyMS = builder.heartbeatFrequencyMS;
287312
minHeartbeatFrequencyMS = builder.minHeartbeatFrequencyMS;
313+
serverMonitoringMode = builder.serverMonitoringMode;
288314
serverListeners = unmodifiableList(builder.serverListeners);
289315
serverMonitorListeners = unmodifiableList(builder.serverMonitorListeners);
290316
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"tests": [
3+
{
4+
"description": "serverMonitoringMode=auto",
5+
"uri": "mongodb://example.com/?serverMonitoringMode=auto",
6+
"valid": true,
7+
"warning": false,
8+
"hosts": null,
9+
"auth": null,
10+
"options": {
11+
"serverMonitoringMode": "auto"
12+
}
13+
},
14+
{
15+
"description": "serverMonitoringMode=stream",
16+
"uri": "mongodb://example.com/?serverMonitoringMode=stream",
17+
"valid": true,
18+
"warning": false,
19+
"hosts": null,
20+
"auth": null,
21+
"options": {
22+
"serverMonitoringMode": "stream"
23+
}
24+
},
25+
{
26+
"description": "serverMonitoringMode=poll",
27+
"uri": "mongodb://example.com/?serverMonitoringMode=poll",
28+
"valid": true,
29+
"warning": false,
30+
"hosts": null,
31+
"auth": null,
32+
"options": {
33+
"serverMonitoringMode": "poll"
34+
}
35+
},
36+
{
37+
"description": "invalid serverMonitoringMode",
38+
"uri": "mongodb://example.com/?serverMonitoringMode=invalid",
39+
"valid": true,
40+
"warning": true,
41+
"hosts": null,
42+
"auth": null,
43+
"options": {}
44+
}
45+
]
46+
}

driver-core/src/test/unit/com/mongodb/AbstractConnectionStringTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ protected void testValidOptions() {
139139
} else if (option.getKey().equalsIgnoreCase("heartbeatfrequencyms")) {
140140
int expected = option.getValue().asInt32().getValue();
141141
assertEquals(expected, connectionString.getHeartbeatFrequency().intValue());
142+
} else if (option.getKey().equalsIgnoreCase("servermonitoringmode")) {
143+
String expected = option.getValue().asString().getValue();
144+
assertEquals(expected, connectionString.getServerMonitoringMode().getValue());
142145
} else if (option.getKey().equalsIgnoreCase("localthresholdms")) {
143146
int expected = option.getValue().asInt32().getValue();
144147
assertEquals(expected, connectionString.getLocalThreshold().intValue());

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ import static com.mongodb.ReadPreference.secondaryPreferred
3535
import static java.util.Arrays.asList
3636
import static java.util.concurrent.TimeUnit.MILLISECONDS
3737

38+
/**
39+
* Update {@link ConnectionStringUnitTest} instead.
40+
*/
3841
class ConnectionStringSpecification extends Specification {
3942
static final LONG_STRING = new String((1..256).collect { (byte) 1 } as byte[])
4043

0 commit comments

Comments
 (0)