MongoClientSettings.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. /* Copyright 2010-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Collections.ObjectModel;
  18. using System.Linq;
  19. using System.Text;
  20. using System.Threading;
  21. using MongoDB.Bson;
  22. using MongoDB.Driver.Core.Configuration;
  23. using MongoDB.Driver.Core.Misc;
  24. using MongoDB.Shared;
  25. namespace MongoDB.Driver
  26. {
  27. /// <summary>
  28. /// The settings for a MongoDB client.
  29. /// </summary>
  30. public class MongoClientSettings : IEquatable<MongoClientSettings>, IInheritableMongoClientSettings
  31. {
  32. // private fields
  33. private string _applicationName;
  34. private Action<ClusterBuilder> _clusterConfigurator;
  35. private ConnectionMode _connectionMode;
  36. private TimeSpan _connectTimeout;
  37. private MongoCredentialStore _credentials;
  38. private GuidRepresentation _guidRepresentation;
  39. private TimeSpan _heartbeatInterval;
  40. private TimeSpan _heartbeatTimeout;
  41. private bool _ipv6;
  42. private TimeSpan _localThreshold;
  43. private TimeSpan _maxConnectionIdleTime;
  44. private TimeSpan _maxConnectionLifeTime;
  45. private int _maxConnectionPoolSize;
  46. private int _minConnectionPoolSize;
  47. private ReadConcern _readConcern;
  48. private UTF8Encoding _readEncoding;
  49. private ReadPreference _readPreference;
  50. private string _replicaSetName;
  51. private bool _retryWrites;
  52. private string _sdamLogFilename;
  53. private List<MongoServerAddress> _servers;
  54. private TimeSpan _serverSelectionTimeout;
  55. private TimeSpan _socketTimeout;
  56. private SslSettings _sslSettings;
  57. private bool _useSsl;
  58. private bool _verifySslCertificate;
  59. private int _waitQueueSize;
  60. private TimeSpan _waitQueueTimeout;
  61. private WriteConcern _writeConcern;
  62. private UTF8Encoding _writeEncoding;
  63. // the following fields are set when Freeze is called
  64. private bool _isFrozen;
  65. private int _frozenHashCode;
  66. private string _frozenStringRepresentation;
  67. // constructors
  68. /// <summary>
  69. /// Creates a new instance of MongoClientSettings. Usually you would use a connection string instead.
  70. /// </summary>
  71. public MongoClientSettings()
  72. {
  73. _applicationName = null;
  74. _connectionMode = ConnectionMode.Automatic;
  75. _connectTimeout = MongoDefaults.ConnectTimeout;
  76. _credentials = new MongoCredentialStore(new MongoCredential[0]);
  77. _guidRepresentation = MongoDefaults.GuidRepresentation;
  78. _heartbeatInterval = ServerSettings.DefaultHeartbeatInterval;
  79. _heartbeatTimeout = ServerSettings.DefaultHeartbeatTimeout;
  80. _ipv6 = false;
  81. _localThreshold = MongoDefaults.LocalThreshold;
  82. _maxConnectionIdleTime = MongoDefaults.MaxConnectionIdleTime;
  83. _maxConnectionLifeTime = MongoDefaults.MaxConnectionLifeTime;
  84. _maxConnectionPoolSize = MongoDefaults.MaxConnectionPoolSize;
  85. _minConnectionPoolSize = MongoDefaults.MinConnectionPoolSize;
  86. _readConcern = ReadConcern.Default;
  87. _readEncoding = null;
  88. _readPreference = ReadPreference.Primary;
  89. _replicaSetName = null;
  90. _retryWrites = false;
  91. _sdamLogFilename = null;
  92. _servers = new List<MongoServerAddress> { new MongoServerAddress("localhost") };
  93. _serverSelectionTimeout = MongoDefaults.ServerSelectionTimeout;
  94. _socketTimeout = MongoDefaults.SocketTimeout;
  95. _sslSettings = null;
  96. _useSsl = false;
  97. _verifySslCertificate = true;
  98. _waitQueueSize = MongoDefaults.ComputedWaitQueueSize;
  99. _waitQueueTimeout = MongoDefaults.WaitQueueTimeout;
  100. _writeConcern = WriteConcern.Acknowledged;
  101. _writeEncoding = null;
  102. }
  103. // public properties
  104. /// <summary>
  105. /// Gets or sets the application name.
  106. /// </summary>
  107. public string ApplicationName
  108. {
  109. get { return _applicationName; }
  110. set
  111. {
  112. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  113. _applicationName = ApplicationNameHelper.EnsureApplicationNameIsValid(value, nameof(value));
  114. }
  115. }
  116. /// <summary>
  117. /// Gets or sets the cluster configurator.
  118. /// </summary>
  119. public Action<ClusterBuilder> ClusterConfigurator
  120. {
  121. get { return _clusterConfigurator; }
  122. set
  123. {
  124. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  125. _clusterConfigurator = value;
  126. }
  127. }
  128. /// <summary>
  129. /// Gets or sets the connection mode.
  130. /// </summary>
  131. public ConnectionMode ConnectionMode
  132. {
  133. get { return _connectionMode; }
  134. set
  135. {
  136. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  137. _connectionMode = value;
  138. }
  139. }
  140. /// <summary>
  141. /// Gets or sets the connect timeout.
  142. /// </summary>
  143. public TimeSpan ConnectTimeout
  144. {
  145. get { return _connectTimeout; }
  146. set
  147. {
  148. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  149. _connectTimeout = value;
  150. }
  151. }
  152. /// <summary>
  153. /// Gets or sets the credential.
  154. /// </summary>
  155. public MongoCredential Credential
  156. {
  157. get
  158. {
  159. return _credentials.SingleOrDefault();
  160. }
  161. set
  162. {
  163. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  164. if (value == null)
  165. {
  166. _credentials = new MongoCredentialStore(Enumerable.Empty<MongoCredential>());
  167. }
  168. else
  169. {
  170. _credentials = new MongoCredentialStore(new[] { value });
  171. }
  172. }
  173. }
  174. /// <summary>
  175. /// Gets or sets the credentials.
  176. /// </summary>
  177. [Obsolete("Use Credential instead. Using multiple credentials is deprecated.")]
  178. public IEnumerable<MongoCredential> Credentials
  179. {
  180. get { return _credentials; }
  181. set
  182. {
  183. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  184. if (value == null)
  185. {
  186. throw new ArgumentNullException("value");
  187. }
  188. _credentials = new MongoCredentialStore(value);
  189. }
  190. }
  191. /// <summary>
  192. /// Gets or sets the representation to use for Guids.
  193. /// </summary>
  194. public GuidRepresentation GuidRepresentation
  195. {
  196. get { return _guidRepresentation; }
  197. set
  198. {
  199. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  200. _guidRepresentation = value;
  201. }
  202. }
  203. /// <summary>
  204. /// Gets a value indicating whether the settings have been frozen to prevent further changes.
  205. /// </summary>
  206. public bool IsFrozen
  207. {
  208. get { return _isFrozen; }
  209. }
  210. /// <summary>
  211. /// Gets or sets the heartbeat interval.
  212. /// </summary>
  213. public TimeSpan HeartbeatInterval
  214. {
  215. get { return _heartbeatInterval; }
  216. set
  217. {
  218. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  219. _heartbeatInterval = Ensure.IsGreaterThanZero(value, nameof(value));
  220. }
  221. }
  222. /// <summary>
  223. /// Gets or sets the heartbeat timeout.
  224. /// </summary>
  225. public TimeSpan HeartbeatTimeout
  226. {
  227. get { return _heartbeatTimeout; }
  228. set
  229. {
  230. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  231. _heartbeatTimeout = Ensure.IsInfiniteOrGreaterThanZero(value, nameof(value));
  232. }
  233. }
  234. /// <summary>
  235. /// Gets or sets a value indicating whether to use IPv6.
  236. /// </summary>
  237. public bool IPv6
  238. {
  239. get { return _ipv6; }
  240. set
  241. {
  242. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  243. _ipv6 = value;
  244. }
  245. }
  246. /// <summary>
  247. /// Gets or sets the local threshold.
  248. /// </summary>
  249. public TimeSpan LocalThreshold
  250. {
  251. get { return _localThreshold; }
  252. set
  253. {
  254. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  255. _localThreshold = value;
  256. }
  257. }
  258. /// <summary>
  259. /// Gets or sets the max connection idle time.
  260. /// </summary>
  261. public TimeSpan MaxConnectionIdleTime
  262. {
  263. get { return _maxConnectionIdleTime; }
  264. set
  265. {
  266. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  267. _maxConnectionIdleTime = value;
  268. }
  269. }
  270. /// <summary>
  271. /// Gets or sets the max connection life time.
  272. /// </summary>
  273. public TimeSpan MaxConnectionLifeTime
  274. {
  275. get { return _maxConnectionLifeTime; }
  276. set
  277. {
  278. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  279. _maxConnectionLifeTime = value;
  280. }
  281. }
  282. /// <summary>
  283. /// Gets or sets the max connection pool size.
  284. /// </summary>
  285. public int MaxConnectionPoolSize
  286. {
  287. get { return _maxConnectionPoolSize; }
  288. set
  289. {
  290. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  291. _maxConnectionPoolSize = value;
  292. }
  293. }
  294. /// <summary>
  295. /// Gets or sets the min connection pool size.
  296. /// </summary>
  297. public int MinConnectionPoolSize
  298. {
  299. get { return _minConnectionPoolSize; }
  300. set
  301. {
  302. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  303. _minConnectionPoolSize = value;
  304. }
  305. }
  306. /// <summary>
  307. /// Gets or sets the read concern.
  308. /// </summary>
  309. public ReadConcern ReadConcern
  310. {
  311. get { return _readConcern; }
  312. set
  313. {
  314. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  315. _readConcern = Ensure.IsNotNull(value, nameof(value));
  316. }
  317. }
  318. /// <summary>
  319. /// Gets or sets the Read Encoding.
  320. /// </summary>
  321. public UTF8Encoding ReadEncoding
  322. {
  323. get { return _readEncoding; }
  324. set
  325. {
  326. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  327. _readEncoding = value;
  328. }
  329. }
  330. /// <summary>
  331. /// Gets or sets the read preferences.
  332. /// </summary>
  333. public ReadPreference ReadPreference
  334. {
  335. get { return _readPreference; }
  336. set
  337. {
  338. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  339. if (value == null)
  340. {
  341. throw new ArgumentNullException("value");
  342. }
  343. _readPreference = value;
  344. }
  345. }
  346. /// <summary>
  347. /// Gets or sets the name of the replica set.
  348. /// </summary>
  349. public string ReplicaSetName
  350. {
  351. get { return _replicaSetName; }
  352. set
  353. {
  354. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  355. _replicaSetName = value;
  356. }
  357. }
  358. /// <summary>
  359. /// Gets or sets whether to retry writes.
  360. /// </summary>
  361. public bool RetryWrites
  362. {
  363. get { return _retryWrites; }
  364. set
  365. {
  366. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  367. _retryWrites = value;
  368. }
  369. }
  370. /// <summary>
  371. /// Gets or set the name of the SDAM log file. Null turns logging off. stdout will log to console.
  372. /// </summary>
  373. public string SdamLogFilename
  374. {
  375. get { return _sdamLogFilename; }
  376. set
  377. {
  378. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  379. _sdamLogFilename = value;
  380. }
  381. }
  382. /// <summary>
  383. /// Gets or sets the address of the server (see also Servers if using more than one address).
  384. /// </summary>
  385. public MongoServerAddress Server
  386. {
  387. get { return _servers.Single(); }
  388. set
  389. {
  390. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  391. if (value == null)
  392. {
  393. throw new ArgumentNullException("value");
  394. }
  395. _servers = new List<MongoServerAddress> { value };
  396. }
  397. }
  398. /// <summary>
  399. /// Gets or sets the list of server addresses (see also Server if using only one address).
  400. /// </summary>
  401. public IEnumerable<MongoServerAddress> Servers
  402. {
  403. get { return new ReadOnlyCollection<MongoServerAddress>(_servers); }
  404. set
  405. {
  406. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  407. if (value == null)
  408. {
  409. throw new ArgumentNullException("value");
  410. }
  411. _servers = new List<MongoServerAddress>(value);
  412. }
  413. }
  414. /// <summary>
  415. /// Gets or sets the server selection timeout.
  416. /// </summary>
  417. public TimeSpan ServerSelectionTimeout
  418. {
  419. get { return _serverSelectionTimeout; }
  420. set
  421. {
  422. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  423. _serverSelectionTimeout = value;
  424. }
  425. }
  426. /// <summary>
  427. /// Gets or sets the socket timeout.
  428. /// </summary>
  429. public TimeSpan SocketTimeout
  430. {
  431. get { return _socketTimeout; }
  432. set
  433. {
  434. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  435. _socketTimeout = value;
  436. }
  437. }
  438. /// <summary>
  439. /// Gets or sets the SSL settings.
  440. /// </summary>
  441. public SslSettings SslSettings
  442. {
  443. get { return _sslSettings; }
  444. set
  445. {
  446. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  447. _sslSettings = value;
  448. }
  449. }
  450. /// <summary>
  451. /// Gets or sets a value indicating whether to use SSL.
  452. /// </summary>
  453. public bool UseSsl
  454. {
  455. get { return _useSsl; }
  456. set
  457. {
  458. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  459. _useSsl = value;
  460. }
  461. }
  462. /// <summary>
  463. /// Gets or sets a value indicating whether to verify an SSL certificate.
  464. /// </summary>
  465. public bool VerifySslCertificate
  466. {
  467. get { return _verifySslCertificate; }
  468. set
  469. {
  470. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  471. _verifySslCertificate = value;
  472. }
  473. }
  474. /// <summary>
  475. /// Gets or sets the wait queue size.
  476. /// </summary>
  477. public int WaitQueueSize
  478. {
  479. get { return _waitQueueSize; }
  480. set
  481. {
  482. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  483. _waitQueueSize = value;
  484. }
  485. }
  486. /// <summary>
  487. /// Gets or sets the wait queue timeout.
  488. /// </summary>
  489. public TimeSpan WaitQueueTimeout
  490. {
  491. get { return _waitQueueTimeout; }
  492. set
  493. {
  494. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  495. _waitQueueTimeout = value;
  496. }
  497. }
  498. /// <summary>
  499. /// Gets or sets the WriteConcern to use.
  500. /// </summary>
  501. public WriteConcern WriteConcern
  502. {
  503. get { return _writeConcern; }
  504. set
  505. {
  506. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  507. if (value == null)
  508. {
  509. throw new ArgumentNullException("value");
  510. }
  511. _writeConcern = value;
  512. }
  513. }
  514. /// <summary>
  515. /// Gets or sets the Write Encoding.
  516. /// </summary>
  517. public UTF8Encoding WriteEncoding
  518. {
  519. get { return _writeEncoding; }
  520. set
  521. {
  522. if (_isFrozen) { throw new InvalidOperationException("MongoClientSettings is frozen."); }
  523. _writeEncoding = value;
  524. }
  525. }
  526. // public operators
  527. /// <summary>
  528. /// Determines whether two <see cref="MongoClientSettings"/> instances are equal.
  529. /// </summary>
  530. /// <param name="lhs">The LHS.</param>
  531. /// <param name="rhs">The RHS.</param>
  532. /// <returns>
  533. /// <c>true</c> if the left hand side is equal to the right hand side; otherwise, <c>false</c>.
  534. /// </returns>
  535. public static bool operator ==(MongoClientSettings lhs, MongoClientSettings rhs)
  536. {
  537. return object.Equals(lhs, rhs); // handles lhs == null correctly
  538. }
  539. /// <summary>
  540. /// Determines whether two <see cref="MongoClientSettings"/> instances are not equal.
  541. /// </summary>
  542. /// <param name="lhs">The LHS.</param>
  543. /// <param name="rhs">The RHS.</param>
  544. /// <returns>
  545. /// <c>true</c> if the left hand side is not equal to the right hand side; otherwise, <c>false</c>.
  546. /// </returns>
  547. public static bool operator !=(MongoClientSettings lhs, MongoClientSettings rhs)
  548. {
  549. return !(lhs == rhs);
  550. }
  551. // public static methods
  552. /// <summary>
  553. /// Gets a MongoClientSettings object intialized with values from a connection string.
  554. /// </summary>
  555. /// <param name="connectionString">The connection string.</param>
  556. /// <returns>A MongoClientSettings.</returns>
  557. public static MongoClientSettings FromConnectionString(string connectionString)
  558. {
  559. return FromUrl(new MongoUrl(connectionString));
  560. }
  561. /// <summary>
  562. /// Gets a MongoClientSettings object intialized with values from a MongoURL.
  563. /// </summary>
  564. /// <param name="url">The MongoURL.</param>
  565. /// <returns>A MongoClientSettings.</returns>
  566. public static MongoClientSettings FromUrl(MongoUrl url)
  567. {
  568. if (url.Scheme == ConnectionStringScheme.MongoDBPlusSrv)
  569. {
  570. url = url.Resolve();
  571. }
  572. var credential = url.GetCredential();
  573. var clientSettings = new MongoClientSettings();
  574. clientSettings.ApplicationName = url.ApplicationName;
  575. clientSettings.ConnectionMode = url.ConnectionMode;
  576. clientSettings.ConnectTimeout = url.ConnectTimeout;
  577. if (credential != null)
  578. {
  579. foreach (var property in url.AuthenticationMechanismProperties)
  580. {
  581. if (property.Key.Equals("CANONICALIZE_HOST_NAME", StringComparison.OrdinalIgnoreCase))
  582. {
  583. credential = credential.WithMechanismProperty(property.Key, bool.Parse(property.Value));
  584. }
  585. else
  586. {
  587. credential = credential.WithMechanismProperty(property.Key, property.Value);
  588. }
  589. }
  590. clientSettings.Credential = credential;
  591. }
  592. clientSettings.GuidRepresentation = url.GuidRepresentation;
  593. clientSettings.HeartbeatInterval = url.HeartbeatInterval;
  594. clientSettings.HeartbeatTimeout = url.HeartbeatTimeout;
  595. clientSettings.IPv6 = url.IPv6;
  596. clientSettings.MaxConnectionIdleTime = url.MaxConnectionIdleTime;
  597. clientSettings.MaxConnectionLifeTime = url.MaxConnectionLifeTime;
  598. clientSettings.MaxConnectionPoolSize = url.MaxConnectionPoolSize;
  599. clientSettings.MinConnectionPoolSize = url.MinConnectionPoolSize;
  600. clientSettings.ReadConcern = new ReadConcern(url.ReadConcernLevel);
  601. clientSettings.ReadEncoding = null; // ReadEncoding must be provided in code
  602. clientSettings.ReadPreference = (url.ReadPreference == null) ? ReadPreference.Primary : url.ReadPreference;
  603. clientSettings.ReplicaSetName = url.ReplicaSetName;
  604. clientSettings.RetryWrites = url.RetryWrites.GetValueOrDefault(false);
  605. clientSettings.LocalThreshold = url.LocalThreshold;
  606. clientSettings.Servers = new List<MongoServerAddress>(url.Servers);
  607. clientSettings.ServerSelectionTimeout = url.ServerSelectionTimeout;
  608. clientSettings.SocketTimeout = url.SocketTimeout;
  609. clientSettings.SslSettings = null; // SSL settings must be provided in code
  610. clientSettings.UseSsl = url.UseSsl;
  611. clientSettings.VerifySslCertificate = url.VerifySslCertificate;
  612. clientSettings.WaitQueueSize = url.ComputedWaitQueueSize;
  613. clientSettings.WaitQueueTimeout = url.WaitQueueTimeout;
  614. clientSettings.WriteConcern = url.GetWriteConcern(true); // WriteConcern is enabled by default for MongoClient
  615. clientSettings.WriteEncoding = null; // WriteEncoding must be provided in code
  616. return clientSettings;
  617. }
  618. // public methods
  619. /// <summary>
  620. /// Creates a clone of the settings.
  621. /// </summary>
  622. /// <returns>A clone of the settings.</returns>
  623. public MongoClientSettings Clone()
  624. {
  625. var clone = new MongoClientSettings();
  626. clone._applicationName = _applicationName;
  627. clone._clusterConfigurator = _clusterConfigurator;
  628. clone._connectionMode = _connectionMode;
  629. clone._connectTimeout = _connectTimeout;
  630. clone._credentials = _credentials;
  631. clone._guidRepresentation = _guidRepresentation;
  632. clone._heartbeatInterval = _heartbeatInterval;
  633. clone._heartbeatTimeout = _heartbeatTimeout;
  634. clone._ipv6 = _ipv6;
  635. clone._maxConnectionIdleTime = _maxConnectionIdleTime;
  636. clone._maxConnectionLifeTime = _maxConnectionLifeTime;
  637. clone._maxConnectionPoolSize = _maxConnectionPoolSize;
  638. clone._minConnectionPoolSize = _minConnectionPoolSize;
  639. clone._readConcern = _readConcern;
  640. clone._readEncoding = _readEncoding;
  641. clone._readPreference = _readPreference;
  642. clone._replicaSetName = _replicaSetName;
  643. clone._retryWrites = _retryWrites;
  644. clone._localThreshold = _localThreshold;
  645. clone._sdamLogFilename = _sdamLogFilename;
  646. clone._servers = new List<MongoServerAddress>(_servers);
  647. clone._serverSelectionTimeout = _serverSelectionTimeout;
  648. clone._socketTimeout = _socketTimeout;
  649. clone._sslSettings = (_sslSettings == null) ? null : _sslSettings.Clone();
  650. clone._useSsl = _useSsl;
  651. clone._verifySslCertificate = _verifySslCertificate;
  652. clone._waitQueueSize = _waitQueueSize;
  653. clone._waitQueueTimeout = _waitQueueTimeout;
  654. clone._writeConcern = _writeConcern;
  655. clone._writeEncoding = _writeEncoding;
  656. return clone;
  657. }
  658. /// <summary>
  659. /// Determines whether the specified <see cref="MongoClientSettings" /> is equal to this instance.
  660. /// </summary>
  661. /// <param name="obj">The <see cref="MongoClientSettings" /> to compare with this instance.</param>
  662. /// <returns>
  663. /// <c>true</c> if the specified <see cref="MongoClientSettings" /> is equal to this instance; otherwise, <c>false</c>.
  664. /// </returns>
  665. public bool Equals(MongoClientSettings obj)
  666. {
  667. return Equals((object)obj); // handles obj == null correctly
  668. }
  669. /// <summary>
  670. /// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
  671. /// </summary>
  672. /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
  673. /// <returns>
  674. /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
  675. /// </returns>
  676. public override bool Equals(object obj)
  677. {
  678. if (object.ReferenceEquals(obj, null) || GetType() != obj.GetType()) { return false; }
  679. var rhs = (MongoClientSettings)obj;
  680. return
  681. _applicationName == rhs._applicationName &&
  682. object.ReferenceEquals(_clusterConfigurator, rhs._clusterConfigurator) &&
  683. _connectionMode == rhs._connectionMode &&
  684. _connectTimeout == rhs._connectTimeout &&
  685. _credentials == rhs._credentials &&
  686. _guidRepresentation == rhs._guidRepresentation &&
  687. _heartbeatInterval == rhs._heartbeatInterval &&
  688. _heartbeatTimeout == rhs._heartbeatTimeout &&
  689. _ipv6 == rhs._ipv6 &&
  690. _maxConnectionIdleTime == rhs._maxConnectionIdleTime &&
  691. _maxConnectionLifeTime == rhs._maxConnectionLifeTime &&
  692. _maxConnectionPoolSize == rhs._maxConnectionPoolSize &&
  693. _minConnectionPoolSize == rhs._minConnectionPoolSize &&
  694. object.Equals(_readEncoding, rhs._readEncoding) &&
  695. object.Equals(_readConcern, rhs._readConcern) &&
  696. _readPreference == rhs._readPreference &&
  697. _replicaSetName == rhs._replicaSetName &&
  698. _retryWrites == rhs._retryWrites &&
  699. _localThreshold == rhs._localThreshold &&
  700. _sdamLogFilename == rhs._sdamLogFilename &&
  701. _servers.SequenceEqual(rhs._servers) &&
  702. _serverSelectionTimeout == rhs._serverSelectionTimeout &&
  703. _socketTimeout == rhs._socketTimeout &&
  704. _sslSettings == rhs._sslSettings &&
  705. _useSsl == rhs._useSsl &&
  706. _verifySslCertificate == rhs._verifySslCertificate &&
  707. _waitQueueSize == rhs._waitQueueSize &&
  708. _waitQueueTimeout == rhs._waitQueueTimeout &&
  709. _writeConcern == rhs._writeConcern &&
  710. object.Equals(_writeEncoding, rhs._writeEncoding);
  711. }
  712. /// <summary>
  713. /// Freezes the settings.
  714. /// </summary>
  715. /// <returns>The frozen settings.</returns>
  716. public MongoClientSettings Freeze()
  717. {
  718. if (!_isFrozen)
  719. {
  720. _frozenHashCode = GetHashCode();
  721. _frozenStringRepresentation = ToString();
  722. _isFrozen = true;
  723. }
  724. return this;
  725. }
  726. /// <summary>
  727. /// Returns a frozen copy of the settings.
  728. /// </summary>
  729. /// <returns>A frozen copy of the settings.</returns>
  730. public MongoClientSettings FrozenCopy()
  731. {
  732. if (_isFrozen)
  733. {
  734. return this;
  735. }
  736. else
  737. {
  738. return Clone().Freeze();
  739. }
  740. }
  741. /// <summary>
  742. /// Gets the hash code.
  743. /// </summary>
  744. /// <returns>The hash code.</returns>
  745. public override int GetHashCode()
  746. {
  747. if (_isFrozen)
  748. {
  749. return _frozenHashCode;
  750. }
  751. return new Hasher()
  752. .Hash(_applicationName)
  753. .Hash(_clusterConfigurator)
  754. .Hash(_connectionMode)
  755. .Hash(_connectTimeout)
  756. .Hash(_credentials)
  757. .Hash(_guidRepresentation)
  758. .Hash(_heartbeatInterval)
  759. .Hash(_heartbeatTimeout)
  760. .Hash(_ipv6)
  761. .Hash(_maxConnectionIdleTime)
  762. .Hash(_maxConnectionLifeTime)
  763. .Hash(_maxConnectionPoolSize)
  764. .Hash(_minConnectionPoolSize)
  765. .Hash(_readConcern)
  766. .Hash(_readEncoding)
  767. .Hash(_readPreference)
  768. .Hash(_replicaSetName)
  769. .Hash(_retryWrites)
  770. .Hash(_localThreshold)
  771. .Hash(_sdamLogFilename)
  772. .HashElements(_servers)
  773. .Hash(_serverSelectionTimeout)
  774. .Hash(_socketTimeout)
  775. .Hash(_sslSettings)
  776. .Hash(_useSsl)
  777. .Hash(_verifySslCertificate)
  778. .Hash(_waitQueueSize)
  779. .Hash(_waitQueueTimeout)
  780. .Hash(_writeConcern)
  781. .Hash(_writeEncoding)
  782. .GetHashCode();
  783. }
  784. /// <summary>
  785. /// Returns a string representation of the settings.
  786. /// </summary>
  787. /// <returns>A string representation of the settings.</returns>
  788. public override string ToString()
  789. {
  790. if (_isFrozen)
  791. {
  792. return _frozenStringRepresentation;
  793. }
  794. var sb = new StringBuilder();
  795. if (_applicationName != null)
  796. {
  797. sb.AppendFormat("ApplicationName={0};", _applicationName);
  798. }
  799. sb.AppendFormat("ConnectionMode={0};", _connectionMode);
  800. sb.AppendFormat("ConnectTimeout={0};", _connectTimeout);
  801. sb.AppendFormat("Credentials={{{0}}};", _credentials);
  802. sb.AppendFormat("GuidRepresentation={0};", _guidRepresentation);
  803. sb.AppendFormat("HeartbeatInterval={0};", _heartbeatInterval);
  804. sb.AppendFormat("HeartbeatTimeout={0};", _heartbeatTimeout);
  805. sb.AppendFormat("IPv6={0};", _ipv6);
  806. sb.AppendFormat("MaxConnectionIdleTime={0};", _maxConnectionIdleTime);
  807. sb.AppendFormat("MaxConnectionLifeTime={0};", _maxConnectionLifeTime);
  808. sb.AppendFormat("MaxConnectionPoolSize={0};", _maxConnectionPoolSize);
  809. sb.AppendFormat("MinConnectionPoolSize={0};", _minConnectionPoolSize);
  810. if (_readEncoding != null)
  811. {
  812. sb.Append("ReadEncoding=UTF8Encoding;");
  813. }
  814. sb.AppendFormat("ReadConcern={0};", _readConcern);
  815. sb.AppendFormat("ReadPreference={0};", _readPreference);
  816. sb.AppendFormat("ReplicaSetName={0};", _replicaSetName);
  817. sb.AppendFormat("RetryWrites={0}", _retryWrites);
  818. sb.AppendFormat("LocalThreshold={0};", _localThreshold);
  819. if (_sdamLogFilename != null)
  820. {
  821. sb.AppendFormat("SDAMLogFileName={0};", _sdamLogFilename);
  822. }
  823. sb.AppendFormat("Servers={0};", string.Join(",", _servers.Select(s => s.ToString()).ToArray()));
  824. sb.AppendFormat("ServerSelectionTimeout={0};", _serverSelectionTimeout);
  825. sb.AppendFormat("SocketTimeout={0};", _socketTimeout);
  826. if (_sslSettings != null)
  827. {
  828. sb.AppendFormat("SslSettings={0};", _sslSettings);
  829. }
  830. sb.AppendFormat("Ssl={0};", _useSsl);
  831. sb.AppendFormat("SslVerifyCertificate={0};", _verifySslCertificate);
  832. sb.AppendFormat("WaitQueueSize={0};", _waitQueueSize);
  833. sb.AppendFormat("WaitQueueTimeout={0}", _waitQueueTimeout);
  834. sb.AppendFormat("WriteConcern={0};", _writeConcern);
  835. if (_writeEncoding != null)
  836. {
  837. sb.Append("WriteEncoding=UTF8Encoding;");
  838. }
  839. return sb.ToString();
  840. }
  841. // internal methods
  842. internal ClusterKey ToClusterKey()
  843. {
  844. return new ClusterKey(
  845. _applicationName,
  846. _clusterConfigurator,
  847. _connectionMode,
  848. _connectTimeout,
  849. _credentials.ToList(),
  850. _heartbeatInterval,
  851. _heartbeatTimeout,
  852. _ipv6,
  853. _localThreshold,
  854. _maxConnectionIdleTime,
  855. _maxConnectionLifeTime,
  856. _maxConnectionPoolSize,
  857. _minConnectionPoolSize,
  858. _replicaSetName,
  859. _sdamLogFilename,
  860. _servers.ToList(),
  861. _serverSelectionTimeout,
  862. _socketTimeout,
  863. _sslSettings,
  864. _useSsl,
  865. _verifySslCertificate,
  866. _waitQueueSize,
  867. _waitQueueTimeout);
  868. }
  869. }
  870. }