Skip to content

Commit b0fbe1d

Browse files
authored
CSHARP-3745: Add support for srvServiceName URI option (#1284)
1 parent 424ed4b commit b0fbe1d

27 files changed

+282
-27
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"uri": "mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname",
3+
"seeds": [
4+
"localhost.test.build.10gen.cc:27017",
5+
"localhost.test.build.10gen.cc:27018"
6+
],
7+
"hosts": [
8+
"localhost:27017",
9+
"localhost:27018",
10+
"localhost:27019"
11+
],
12+
"options": {
13+
"ssl": true,
14+
"srvServiceName": "customname"
15+
}
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
uri: "mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname"
2+
seeds:
3+
- localhost.test.build.10gen.cc:27017
4+
- localhost.test.build.10gen.cc:27018
5+
hosts:
6+
- localhost:27017
7+
- localhost:27018
8+
- localhost:27019
9+
options:
10+
ssl: true
11+
srvServiceName: "customname"

src/MongoDB.Driver.Core/Core/Clusters/DnsMonitor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ private static string EnsureLookupDomainNameIsValid(string lookupDomainName)
5252
// constructors
5353
public DnsMonitor(IDnsMonitoringCluster cluster,
5454
IDnsResolver dnsResolver,
55+
string srvServiceName,
5556
string lookupDomainName,
5657
IEventSubscriber eventSubscriber,
5758
ILogger<LogCategories.SDAM> logger,
@@ -61,7 +62,7 @@ public DnsMonitor(IDnsMonitoringCluster cluster,
6162
_dnsResolver = Ensure.IsNotNull(dnsResolver, nameof(dnsResolver));
6263
_lookupDomainName = EnsureLookupDomainNameIsValid(lookupDomainName);
6364
_cancellationToken = cancellationToken;
64-
_service = "_mongodb._tcp." + _lookupDomainName;
65+
_service = $"_{srvServiceName}._tcp." + _lookupDomainName;
6566
_state = DnsMonitorState.Created;
6667

6768
_eventLogger = logger.ToEventLogger(eventSubscriber);

src/MongoDB.Driver.Core/Core/Clusters/DnsMonitorFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ public DnsMonitorFactory(IEventSubscriber eventSubscriber, ILoggerFactory logger
3232
_loggerFactory = loggerFactory;
3333
}
3434

35-
public IDnsMonitor CreateDnsMonitor(IDnsMonitoringCluster cluster, string lookupDomainName, CancellationToken cancellationToken)
35+
public IDnsMonitor CreateDnsMonitor(IDnsMonitoringCluster cluster, string srvServiceName, string lookupDomainName, CancellationToken cancellationToken)
3636
{
3737
var dnsResolver = DnsClientWrapper.Instance;
38-
return new DnsMonitor(cluster, dnsResolver, lookupDomainName, _eventSubscriber, _loggerFactory?.CreateLogger<LogCategories.SDAM>(), cancellationToken);
38+
return new DnsMonitor(cluster, dnsResolver, srvServiceName, lookupDomainName, _eventSubscriber, _loggerFactory?.CreateLogger<LogCategories.SDAM>(), cancellationToken);
3939
}
4040
}
4141
}

src/MongoDB.Driver.Core/Core/Clusters/IDnsMonitorFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ namespace MongoDB.Driver.Core.Clusters
1919
{
2020
internal interface IDnsMonitorFactory
2121
{
22-
IDnsMonitor CreateDnsMonitor(IDnsMonitoringCluster cluster, string lookupDomainName, CancellationToken cancellationToken);
22+
IDnsMonitor CreateDnsMonitor(IDnsMonitoringCluster cluster, string srvServiceName, string lookupDomainName, CancellationToken cancellationToken);
2323
}
2424
}

src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public void Initialize()
183183
// _server will be created after srv resolving
184184
var dnsEndPoint = (DnsEndPoint)endPoint;
185185
var lookupDomainName = dnsEndPoint.Host;
186-
var monitor = _dnsMonitorFactory.CreateDnsMonitor(this, lookupDomainName, _dnsMonitorCancellationTokenSource.Token);
186+
var monitor = _dnsMonitorFactory.CreateDnsMonitor(this, _settings.SrvServiceName, lookupDomainName, _dnsMonitorCancellationTokenSource.Token);
187187
_dnsMonitorThread = monitor.Start();
188188
}
189189

src/MongoDB.Driver.Core/Core/Clusters/MultiServerCluster.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public override void Initialize()
151151
{
152152
var dnsEndPoint = (DnsEndPoint)Settings.EndPoints.Single();
153153
var lookupDomainName = dnsEndPoint.Host;
154-
var dnsMonitor = _dnsMonitorFactory.CreateDnsMonitor(this, lookupDomainName, _monitorServersCancellationTokenSource.Token);
154+
var dnsMonitor = _dnsMonitorFactory.CreateDnsMonitor(this, Settings.SrvServiceName, lookupDomainName, _monitorServersCancellationTokenSource.Token);
155155
_dnsMonitorThread = dnsMonitor.Start(); // store the Thread for use as evidence when testing that the DnsMonitor was started
156156
}
157157
}

src/MongoDB.Driver.Core/Core/Configuration/ClusterSettings.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public class ClusterSettings
4949
private readonly ServerApi _serverApi;
5050
private readonly TimeSpan _serverSelectionTimeout;
5151
private readonly int _srvMaxHosts;
52+
private readonly string _srvServiceName;
5253
private readonly IServerSelector _preServerSelector;
5354
private readonly IServerSelector _postServerSelector;
5455

@@ -71,6 +72,7 @@ public class ClusterSettings
7172
/// <param name="postServerSelector">The post server selector.</param>
7273
/// <param name="scheme">The connection string scheme.</param>
7374
/// <param name="srvMaxHosts">Limits the number of SRV records used to populate the seedlist during initial discovery, as well as the number of additional hosts that may be added during SRV polling.</param>
75+
/// <param name="srvServiceName"> The SRV service name which modifies the srv URI to look like: <code>_{srvServiceName}._tcp.{hostname}.{domainname}</code> Defaults to "mongodb".</param>
7476
public ClusterSettings(
7577
#pragma warning disable CS0618 // Type or member is obsolete
7678
Optional<ClusterConnectionMode> connectionMode = default(Optional<ClusterConnectionMode>),
@@ -88,7 +90,8 @@ public ClusterSettings(
8890
Optional<IServerSelector> preServerSelector = default(Optional<IServerSelector>),
8991
Optional<IServerSelector> postServerSelector = default(Optional<IServerSelector>),
9092
Optional<ConnectionStringScheme> scheme = default(Optional<ConnectionStringScheme>),
91-
Optional<int> srvMaxHosts = default)
93+
Optional<int> srvMaxHosts = default,
94+
Optional<string> srvServiceName = default(Optional<string>))
9295
{
9396
#pragma warning disable CS0618 // Type or member is obsolete
9497
_connectionMode = connectionMode.WithDefault(ClusterConnectionMode.Automatic);
@@ -107,6 +110,7 @@ public ClusterSettings(
107110
_postServerSelector = postServerSelector.WithDefault(null);
108111
_scheme = scheme.WithDefault(ConnectionStringScheme.MongoDB);
109112
_srvMaxHosts = Ensure.IsGreaterThanOrEqualToZero(srvMaxHosts.WithDefault(0), nameof(srvMaxHosts));
113+
_srvServiceName = srvServiceName.WithDefault(MongoInternalDefaults.MongoClientSettings.SrvServiceName);
110114

111115
ClusterConnectionModeHelper.EnsureConnectionModeValuesAreValid(_connectionMode, _connectionModeSwitch, _directConnection);
112116
}
@@ -258,6 +262,13 @@ public TimeSpan ServerSelectionTimeout
258262
/// </summary>
259263
public int SrvMaxHosts => _srvMaxHosts;
260264

265+
/// <summary>
266+
/// Gets the SRV service name which modifies the srv URI to look like:
267+
/// <code>_{srvServiceName}._tcp.{hostname}.{domainname}</code>
268+
/// The default value is "mongodb".
269+
/// </summary>
270+
public string SrvServiceName => _srvServiceName;
271+
261272
/// <summary>
262273
/// Gets the pre server selector.
263274
/// </summary>
@@ -299,6 +310,7 @@ public IServerSelector PostServerSelector
299310
/// <param name="postServerSelector">The post server selector.</param>
300311
/// <param name="scheme">The connection string scheme.</param>
301312
/// <param name="srvMaxHosts">Limits the number of SRV records used to populate the seedlist during initial discovery, as well as the number of additional hosts that may be added during SRV polling.</param>
313+
/// <param name="srvServiceName"> The SRV service name which modifies the srv URI to look like: <code>_{srvServiceName}._tcp.{hostname}.{domainname}</code> Defaults to "mongodb".</param>
302314
/// <returns>A new ClusterSettings instance.</returns>
303315
public ClusterSettings With(
304316
#pragma warning disable CS0618 // Type or member is obsolete
@@ -317,7 +329,8 @@ public ClusterSettings With(
317329
Optional<IServerSelector> preServerSelector = default(Optional<IServerSelector>),
318330
Optional<IServerSelector> postServerSelector = default(Optional<IServerSelector>),
319331
Optional<ConnectionStringScheme> scheme = default(Optional<ConnectionStringScheme>),
320-
Optional<int> srvMaxHosts = default)
332+
Optional<int> srvMaxHosts = default,
333+
Optional<string> srvServiceName = default(Optional<string>))
321334
{
322335
return new ClusterSettings(
323336
connectionMode: connectionMode.WithDefault(_connectionMode),
@@ -334,7 +347,8 @@ public ClusterSettings With(
334347
preServerSelector: Optional.Create(preServerSelector.WithDefault(_preServerSelector)),
335348
postServerSelector: Optional.Create(postServerSelector.WithDefault(_postServerSelector)),
336349
scheme: scheme.WithDefault(_scheme),
337-
srvMaxHosts: srvMaxHosts.WithDefault(_srvMaxHosts));
350+
srvMaxHosts: srvMaxHosts.WithDefault(_srvMaxHosts),
351+
srvServiceName: srvServiceName.WithDefault(_srvServiceName));
338352
}
339353

340354
// internal methods

src/MongoDB.Driver.Core/Core/Configuration/ConnectionString.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ public enum ConnectionStringScheme
5151
public sealed class ConnectionString
5252
{
5353
// constants
54-
private const string srvPrefix = "_mongodb._tcp.";
5554
private const int defaultMongoDBPort = 27017;
5655
private const int defaultSrvPort = 53;
5756

@@ -62,6 +61,7 @@ public sealed class ConnectionString
6261
private readonly Dictionary<string, string> _authMechanismProperties;
6362
private readonly CompressorsOptions _compressorsOptions;
6463
private readonly IDnsResolver _dnsResolver;
64+
private readonly string _srvPrefix;
6565

6666
// these are all readonly, but since they are not assigned
6767
// from the ctor, they cannot be marked as such.
@@ -103,6 +103,7 @@ public sealed class ConnectionString
103103
private TimeSpan? _serverSelectionTimeout;
104104
private TimeSpan? _socketTimeout;
105105
private int? _srvMaxHosts;
106+
private string _srvServiceName;
106107
private bool? _tls;
107108
private bool? _tlsDisableCertificateRevocationCheck;
108109
private bool? _tlsInsecure;
@@ -135,6 +136,8 @@ internal ConnectionString(string connectionString, bool isInternalRepresentation
135136
_dnsResolver = Ensure.IsNotNull(dnsResolver, nameof(dnsResolver));
136137
Parse();
137138

139+
_srvPrefix = $"_{_srvServiceName ?? MongoInternalDefaults.MongoClientSettings.SrvServiceName}._tcp.";
140+
138141
_isResolved = _scheme != ConnectionStringScheme.MongoDBPlusSrv;
139142
}
140143

@@ -485,6 +488,12 @@ public TimeSpan? SocketTimeout
485488
/// </summary>
486489
public int? SrvMaxHosts => _srvMaxHosts;
487490

491+
/// <summary>
492+
/// Gets the SRV service name which modifies the srv URI to look like:
493+
/// <code>_{srvServiceName}._tcp.{hostname}.{domainname}</code>
494+
/// </summary>
495+
public string SrvServiceName => _srvServiceName;
496+
488497
/// <summary>
489498
/// Gets whether to use SSL.
490499
/// </summary>
@@ -616,7 +625,7 @@ public string GetOption(string name)
616625
if (resolveHosts)
617626
{
618627
resolvedScheme = ConnectionStringScheme.MongoDB;
619-
var srvRecords = _dnsResolver.ResolveSrvRecords(srvPrefix + host, cancellationToken);
628+
var srvRecords = _dnsResolver.ResolveSrvRecords(_srvPrefix + host, cancellationToken);
620629
hosts = GetHostsFromSrvRecords(srvRecords);
621630
ValidateResolvedHosts(host, hosts);
622631
}
@@ -664,7 +673,7 @@ public string GetOption(string name)
664673
if (resolveHosts)
665674
{
666675
resolvedScheme = ConnectionStringScheme.MongoDB;
667-
var srvRecords = await _dnsResolver.ResolveSrvRecordsAsync(srvPrefix + host, cancellationToken).ConfigureAwait(false);
676+
var srvRecords = await _dnsResolver.ResolveSrvRecordsAsync(_srvPrefix + host, cancellationToken).ConfigureAwait(false);
668677
hosts = GetHostsFromSrvRecords(srvRecords);
669678
ValidateResolvedHosts(host, hosts);
670679
}
@@ -928,6 +937,11 @@ private void Parse()
928937
throw new MongoConfigurationException("Specifying srvMaxHosts when connecting to a replica set is invalid.");
929938
}
930939

940+
if (!_isInternalRepresentation && _srvServiceName != null && _scheme != ConnectionStringScheme.MongoDBPlusSrv)
941+
{
942+
throw new MongoConfigurationException("Specifying srvServiceName is only allowed with the mongodb+srv scheme.");
943+
}
944+
931945
if (_loadBalanced)
932946
{
933947
if (_hosts.Count > 1)
@@ -1126,6 +1140,13 @@ private void ParseOption(string name, string value)
11261140
}
11271141
_srvMaxHosts = srvMaxHostsValue;
11281142
break;
1143+
case "srvservicename":
1144+
_srvServiceName = value;
1145+
if (_srvServiceName.Length == 0)
1146+
{
1147+
throw new MongoConfigurationException("SrvServiceName cannot be empty.");
1148+
}
1149+
break;
11291150
case "ssl": // Obsolete
11301151
case "tls":
11311152
var tlsValue = ParseBoolean(name, value);

src/MongoDB.Driver.Core/MongoInternalDefaults.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,10 @@ public static class ConnectionPool
2626
{
2727
public const int MaxConnecting = 2;
2828
}
29+
30+
public static class MongoClientSettings
31+
{
32+
public const string SrvServiceName = "mongodb";
33+
}
2934
}
3035
}

src/MongoDB.Driver.Legacy/MongoServerSettings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,7 @@ internal ClusterKey ToClusterKey()
12281228
_serverSelectionTimeout,
12291229
_socketTimeout,
12301230
srvMaxHosts: 0, // not supported for legacy
1231+
srvServiceName: MongoInternalDefaults.MongoClientSettings.SrvServiceName,
12311232
_sslSettings,
12321233
_useTls,
12331234
_waitQueueSize,

src/MongoDB.Driver/ClusterKey.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ internal class ClusterKey
6363
private readonly TimeSpan _serverSelectionTimeout;
6464
private readonly TimeSpan _socketTimeout;
6565
private readonly int _srvMaxHosts;
66+
private readonly string _srvServiceName;
6667
private readonly SslSettings _sslSettings;
6768
private readonly bool _useTls;
6869
private readonly int _waitQueueSize;
@@ -105,6 +106,7 @@ public ClusterKey(
105106
TimeSpan serverSelectionTimeout,
106107
TimeSpan socketTimeout,
107108
int srvMaxHosts,
109+
string srvServiceName,
108110
SslSettings sslSettings,
109111
bool useTls,
110112
int waitQueueSize,
@@ -145,6 +147,7 @@ public ClusterKey(
145147
_serverSelectionTimeout = serverSelectionTimeout;
146148
_socketTimeout = socketTimeout;
147149
_srvMaxHosts = srvMaxHosts;
150+
_srvServiceName = srvServiceName;
148151
_sslSettings = sslSettings;
149152
_useTls = useTls;
150153
_waitQueueSize = waitQueueSize;
@@ -211,6 +214,7 @@ public bool? DirectConnection
211214
public TimeSpan ServerSelectionTimeout { get { return _serverSelectionTimeout; } }
212215
public TimeSpan SocketTimeout { get { return _socketTimeout; } }
213216
public int SrvMaxHosts { get { return _srvMaxHosts; } }
217+
public string SrvServiceName { get { return _srvServiceName; } }
214218
public SslSettings SslSettings { get { return _sslSettings; } }
215219
public bool UseTls => _useTls;
216220
public int WaitQueueSize { get { return _waitQueueSize; } }
@@ -268,6 +272,7 @@ public override bool Equals(object obj)
268272
_serverSelectionTimeout == rhs._serverSelectionTimeout &&
269273
_socketTimeout == rhs._socketTimeout &&
270274
_srvMaxHosts == rhs._srvMaxHosts &&
275+
_srvServiceName == rhs.SrvServiceName &&
271276
object.Equals(_sslSettings, rhs._sslSettings) &&
272277
_useTls == rhs._useTls &&
273278
_waitQueueSize == rhs._waitQueueSize &&

0 commit comments

Comments
 (0)