You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.2 KiB

  1. /* Copyright 2010 10gen 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.Linq;
  18. using System.Text;
  19. using System.Threading;
  20. using MongoDB.Bson;
  21. namespace MongoDB.Driver.Internal {
  22. internal class DirectConnector {
  23. #region private fields
  24. private MongoUrl url;
  25. private MongoServerAddress address;
  26. private MongoConnection connection;
  27. private bool isPrimary;
  28. #endregion
  29. #region constructors
  30. public DirectConnector(
  31. MongoUrl url
  32. ) {
  33. this.url = url;
  34. }
  35. #endregion
  36. #region public properties
  37. public MongoServerAddress Address {
  38. get { return address; }
  39. }
  40. public MongoConnection Connection {
  41. get { return connection; }
  42. }
  43. public bool IsPrimary {
  44. get { return isPrimary; }
  45. }
  46. #endregion
  47. #region public methods
  48. public void Connect(
  49. TimeSpan timeout
  50. ) {
  51. var exceptions = new List<Exception>();
  52. foreach (var address in url.Servers) {
  53. try {
  54. Connect(address, timeout);
  55. return;
  56. } catch (Exception ex) {
  57. exceptions.Add(ex);
  58. }
  59. }
  60. var innerException = exceptions.FirstOrDefault();
  61. var connectionException = new MongoConnectionException("Unable to connect to server", innerException);
  62. if (exceptions.Count > 1) {
  63. connectionException.Data.Add("exceptions", exceptions);
  64. }
  65. throw connectionException;
  66. }
  67. #endregion
  68. #region private methods
  69. private void Connect(
  70. MongoServerAddress address,
  71. TimeSpan timeout
  72. ) {
  73. var connection = new MongoConnection(null, address); // no connection pool
  74. bool isPrimary;
  75. try {
  76. var isMasterCommand = new BsonDocument("ismaster", 1);
  77. var isMasterResult = connection.RunCommand("admin.$cmd", QueryFlags.SlaveOk, isMasterCommand);
  78. isPrimary = isMasterResult["ismaster", false].ToBoolean();
  79. if (!isPrimary && !url.SlaveOk) {
  80. throw new MongoConnectionException("Server is not a primary and SlaveOk is false");
  81. }
  82. } catch {
  83. try { connection.Close(); } catch { } // ignore exceptions
  84. throw;
  85. }
  86. this.address = address;
  87. this.connection = connection;
  88. this.isPrimary = isPrimary;
  89. }
  90. #endregion
  91. }
  92. }