mongo 1.12.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CONTRIBUTING.md +64 -0
  4. data/LICENSE +1 -1
  5. data/README.md +21 -126
  6. data/Rakefile +39 -21
  7. data/bin/mongo_console +6 -38
  8. data/lib/mongo/address/ipv4.rb +85 -0
  9. data/lib/mongo/address/ipv6.rb +85 -0
  10. data/lib/mongo/address/unix.rb +76 -0
  11. data/lib/mongo/address.rb +111 -0
  12. data/lib/mongo/auth/cr/conversation.rb +119 -0
  13. data/lib/mongo/auth/cr.rb +44 -0
  14. data/lib/mongo/auth/executable.rb +52 -0
  15. data/lib/mongo/auth/ldap/conversation.rb +92 -0
  16. data/lib/mongo/auth/ldap.rb +48 -0
  17. data/lib/mongo/auth/roles.rb +104 -0
  18. data/lib/mongo/auth/scram/conversation.rb +450 -0
  19. data/lib/mongo/auth/scram.rb +53 -0
  20. data/lib/mongo/auth/user/view.rb +102 -0
  21. data/lib/mongo/auth/user.rb +159 -0
  22. data/lib/mongo/auth/x509/conversation.rb +92 -0
  23. data/lib/mongo/auth/x509.rb +48 -0
  24. data/lib/mongo/auth.rb +108 -0
  25. data/lib/mongo/bulk_write/bulk_writable.rb +191 -0
  26. data/lib/mongo/bulk_write/deletable.rb +60 -0
  27. data/lib/mongo/bulk_write/insertable.rb +52 -0
  28. data/lib/mongo/bulk_write/ordered_bulk_write.rb +48 -0
  29. data/lib/mongo/bulk_write/replacable.rb +57 -0
  30. data/lib/mongo/bulk_write/unordered_bulk_write.rb +46 -0
  31. data/lib/mongo/bulk_write/updatable.rb +68 -0
  32. data/lib/mongo/bulk_write.rb +52 -0
  33. data/lib/mongo/client.rb +246 -0
  34. data/lib/mongo/cluster/topology/replica_set.rb +160 -0
  35. data/lib/mongo/cluster/topology/sharded.rb +132 -0
  36. data/lib/mongo/cluster/topology/standalone.rb +132 -0
  37. data/lib/mongo/cluster/topology/unknown.rb +155 -0
  38. data/lib/mongo/cluster/topology.rb +60 -0
  39. data/lib/mongo/cluster.rb +203 -0
  40. data/lib/mongo/collection/view/aggregation.rb +108 -0
  41. data/lib/mongo/collection/view/explainable.rb +49 -0
  42. data/lib/mongo/collection/view/immutable.rb +43 -0
  43. data/lib/mongo/collection/view/iterable.rb +48 -0
  44. data/lib/mongo/collection/view/map_reduce.rb +191 -0
  45. data/lib/mongo/collection/view/readable.rb +363 -0
  46. data/lib/mongo/collection/view/writable.rb +185 -0
  47. data/lib/mongo/collection/view.rb +169 -0
  48. data/lib/mongo/collection.rb +130 -1101
  49. data/lib/mongo/cursor.rb +78 -681
  50. data/lib/mongo/database/view.rb +101 -0
  51. data/lib/mongo/database.rb +224 -0
  52. data/lib/mongo/error/bulk_write_error.rb +41 -0
  53. data/lib/mongo/error/invalid_bulk_operation.rb +36 -0
  54. data/lib/mongo/error/invalid_bulk_operation_type.rb +36 -0
  55. data/lib/mongo/error/invalid_collection_name.rb +39 -0
  56. data/lib/mongo/error/invalid_database_name.rb +39 -0
  57. data/{test/replica_set/ssl_test.rb → lib/mongo/error/invalid_document.rb} +21 -14
  58. data/lib/mongo/error/invalid_file.rb +38 -0
  59. data/lib/mongo/error/invalid_nonce.rb +46 -0
  60. data/lib/mongo/error/invalid_replacement_document.rb +39 -0
  61. data/lib/mongo/error/invalid_signature.rb +47 -0
  62. data/{test/functional/ssl_test.rb → lib/mongo/error/invalid_update_document.rb} +22 -12
  63. data/lib/mongo/error/max_bson_size.rb +40 -0
  64. data/lib/mongo/error/max_message_size.rb +42 -0
  65. data/{test/functional/db_connection_test.rb → lib/mongo/error/multi_index_drop.rb} +17 -8
  66. data/lib/mongo/{utils.rb → error/need_primary_server.rb} +10 -6
  67. data/lib/mongo/{connection.rb → error/operation_failure.rb} +10 -6
  68. data/lib/mongo/error/parser.rb +77 -0
  69. data/lib/mongo/{connection/socket.rb → error/socket_error.rb} +10 -5
  70. data/lib/mongo/error/socket_timeout_error.rb +23 -0
  71. data/lib/mongo/error/unsupported_features.rb +43 -0
  72. data/lib/mongo/error.rb +82 -0
  73. data/lib/mongo/event/listeners.rb +63 -0
  74. data/lib/mongo/event/primary_elected.rb +53 -0
  75. data/lib/mongo/event/publisher.rb +42 -0
  76. data/lib/mongo/event/server_added.rb +53 -0
  77. data/lib/mongo/event/server_removed.rb +53 -0
  78. data/lib/mongo/event/subscriber.rb +41 -0
  79. data/lib/mongo/event.rb +40 -0
  80. data/lib/mongo/grid/file/chunk.rb +184 -0
  81. data/lib/mongo/grid/file/metadata.rb +229 -0
  82. data/lib/mongo/grid/file.rb +106 -0
  83. data/lib/mongo/grid/fs.rb +149 -0
  84. data/lib/mongo/{gridfs.rb → grid.rb} +3 -5
  85. data/lib/mongo/index/view.rb +261 -0
  86. data/lib/mongo/index.rb +64 -0
  87. data/lib/mongo/loggable.rb +126 -0
  88. data/lib/mongo/logger.rb +132 -0
  89. data/lib/mongo/operation/aggregate/result.rb +88 -0
  90. data/lib/mongo/operation/aggregate.rb +100 -0
  91. data/lib/mongo/operation/command.rb +62 -0
  92. data/lib/mongo/operation/executable.rb +105 -0
  93. data/lib/mongo/operation/kill_cursors.rb +39 -0
  94. data/lib/mongo/operation/limited.rb +37 -0
  95. data/lib/mongo/operation/list_collections/result.rb +114 -0
  96. data/lib/mongo/operation/list_indexes/result.rb +118 -0
  97. data/lib/mongo/operation/map_reduce/result.rb +122 -0
  98. data/lib/mongo/operation/map_reduce.rb +96 -0
  99. data/lib/mongo/operation/read/collections_info.rb +67 -0
  100. data/lib/mongo/operation/read/get_more.rb +71 -0
  101. data/lib/mongo/operation/read/indexes.rb +68 -0
  102. data/lib/mongo/operation/read/list_collections.rb +75 -0
  103. data/lib/mongo/operation/read/list_indexes.rb +77 -0
  104. data/lib/mongo/operation/read/query.rb +71 -0
  105. data/lib/mongo/{functional.rb → operation/read.rb} +7 -7
  106. data/lib/mongo/operation/read_preferrable.rb +34 -0
  107. data/lib/mongo/operation/result.rb +259 -0
  108. data/lib/mongo/operation/specifiable.rb +397 -0
  109. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +75 -0
  110. data/lib/mongo/operation/write/bulk/bulk_delete.rb +144 -0
  111. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +68 -0
  112. data/lib/mongo/operation/write/bulk/bulk_insert.rb +129 -0
  113. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +67 -0
  114. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +162 -0
  115. data/lib/mongo/operation/write/bulk/bulk_update.rb +153 -0
  116. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +83 -0
  117. data/lib/mongo/operation/write/bulk.rb +17 -0
  118. data/lib/mongo/operation/write/command/create_index.rb +50 -0
  119. data/lib/mongo/operation/write/command/create_user.rb +43 -0
  120. data/lib/mongo/operation/write/command/delete.rb +56 -0
  121. data/lib/mongo/operation/write/command/drop_index.rb +51 -0
  122. data/lib/mongo/operation/write/command/insert.rb +55 -0
  123. data/lib/mongo/operation/write/command/remove_user.rb +42 -0
  124. data/lib/mongo/operation/write/command/update.rb +60 -0
  125. data/lib/mongo/operation/write/command/writable.rb +61 -0
  126. data/lib/mongo/operation/write/command.rb +22 -0
  127. data/lib/mongo/operation/write/create_index.rb +89 -0
  128. data/lib/mongo/operation/write/create_user.rb +75 -0
  129. data/lib/mongo/operation/write/delete/result.rb +40 -0
  130. data/lib/mongo/operation/write/delete.rb +93 -0
  131. data/lib/mongo/operation/write/drop_index.rb +62 -0
  132. data/lib/mongo/{utils/thread_local_variable_manager.rb → operation/write/insert/result.rb} +15 -8
  133. data/lib/mongo/operation/write/insert.rb +90 -0
  134. data/lib/mongo/operation/write/remove_user.rb +70 -0
  135. data/lib/mongo/operation/write/update/result.rb +160 -0
  136. data/lib/mongo/operation/write/update.rb +103 -0
  137. data/lib/mongo/{connection/socket/socket_util.rb → operation/write.rb} +10 -24
  138. data/lib/mongo/operation.rb +25 -0
  139. data/lib/mongo/options/mapper.rb +78 -0
  140. data/lib/mongo/options.rb +15 -0
  141. data/lib/mongo/protocol/bit_vector.rb +61 -0
  142. data/lib/mongo/protocol/delete.rb +94 -0
  143. data/lib/mongo/protocol/get_more.rb +99 -0
  144. data/lib/mongo/protocol/insert.rb +99 -0
  145. data/lib/mongo/protocol/kill_cursors.rb +74 -0
  146. data/lib/mongo/protocol/message.rb +252 -0
  147. data/lib/mongo/protocol/query.rb +147 -0
  148. data/lib/mongo/protocol/reply.rb +72 -0
  149. data/lib/mongo/protocol/serializers.rb +180 -0
  150. data/lib/mongo/protocol/update.rb +111 -0
  151. data/lib/mongo/protocol.rb +15 -0
  152. data/lib/mongo/server/connectable.rb +110 -0
  153. data/lib/mongo/server/connection.rb +134 -0
  154. data/lib/mongo/server/connection_pool/queue.rb +182 -0
  155. data/lib/mongo/server/connection_pool.rb +141 -0
  156. data/lib/mongo/server/context.rb +66 -0
  157. data/lib/mongo/server/description/features.rb +85 -0
  158. data/lib/mongo/server/description/inspector/primary_elected.rb +58 -0
  159. data/lib/mongo/server/description/inspector/server_added.rb +59 -0
  160. data/lib/mongo/server/description/inspector/server_removed.rb +59 -0
  161. data/lib/mongo/server/description/inspector.rb +79 -0
  162. data/lib/mongo/server/description.rb +450 -0
  163. data/lib/mongo/server/monitor/connection.rb +89 -0
  164. data/lib/mongo/server/monitor.rb +176 -0
  165. data/lib/mongo/server.rb +163 -0
  166. data/lib/mongo/server_selector/nearest.rb +94 -0
  167. data/lib/mongo/server_selector/primary.rb +88 -0
  168. data/lib/mongo/server_selector/primary_preferred.rb +94 -0
  169. data/lib/mongo/server_selector/secondary.rb +91 -0
  170. data/lib/mongo/server_selector/secondary_preferred.rb +96 -0
  171. data/lib/mongo/server_selector/selectable.rb +209 -0
  172. data/lib/mongo/server_selector.rb +81 -0
  173. data/lib/mongo/socket/ssl.rb +130 -0
  174. data/lib/mongo/socket/tcp.rb +69 -0
  175. data/lib/mongo/socket/unix.rb +64 -0
  176. data/lib/mongo/socket.rb +179 -0
  177. data/lib/mongo/uri.rb +504 -0
  178. data/lib/mongo/version.rb +21 -0
  179. data/lib/mongo/write_concern/acknowledged.rb +52 -0
  180. data/lib/mongo/write_concern/normalizable.rb +51 -0
  181. data/lib/mongo/write_concern/unacknowledged.rb +55 -0
  182. data/lib/mongo/write_concern.rb +99 -0
  183. data/lib/mongo.rb +24 -82
  184. data/mongo.gemspec +17 -14
  185. data/spec/certificates/ca.pem +17 -0
  186. data/spec/certificates/client.pem +101 -0
  187. data/spec/certificates/crl.pem +10 -0
  188. data/spec/certificates/crl_client_revoked.pem +12 -0
  189. data/spec/certificates/password_protected.pem +51 -0
  190. data/spec/certificates/server.pem +34 -0
  191. data/spec/mongo/address/ipv4_spec.rb +74 -0
  192. data/spec/mongo/address/ipv6_spec.rb +74 -0
  193. data/spec/mongo/address/unix_spec.rb +30 -0
  194. data/spec/mongo/address_spec.rb +206 -0
  195. data/spec/mongo/auth/cr_spec.rb +59 -0
  196. data/spec/mongo/auth/ldap_spec.rb +40 -0
  197. data/spec/mongo/auth/scram/conversation_spec.rb +197 -0
  198. data/spec/mongo/auth/scram_spec.rb +55 -0
  199. data/spec/mongo/auth/user/view_spec.rb +76 -0
  200. data/spec/mongo/auth/user_spec.rb +190 -0
  201. data/spec/mongo/auth/x509_spec.rb +40 -0
  202. data/spec/mongo/auth_spec.rb +65 -0
  203. data/spec/mongo/bulk/bulk_write_spec.rb +262 -0
  204. data/spec/mongo/client_spec.rb +564 -0
  205. data/spec/mongo/cluster/topology/replica_set_spec.rb +101 -0
  206. data/spec/mongo/cluster/topology/sharded_spec.rb +74 -0
  207. data/spec/mongo/cluster/topology/standalone_spec.rb +79 -0
  208. data/spec/mongo/cluster/topology_spec.rb +65 -0
  209. data/spec/mongo/cluster_spec.rb +129 -0
  210. data/spec/mongo/collection/view/aggregation_spec.rb +148 -0
  211. data/spec/mongo/collection/view/explainable_spec.rb +32 -0
  212. data/spec/mongo/collection/view/map_reduce_spec.rb +242 -0
  213. data/spec/mongo/collection/view/readable_spec.rb +603 -0
  214. data/spec/mongo/collection/view/writable_spec.rb +679 -0
  215. data/spec/mongo/collection/view_spec.rb +530 -0
  216. data/spec/mongo/collection_spec.rb +362 -0
  217. data/spec/mongo/crud_spec.rb +42 -0
  218. data/spec/mongo/cursor_spec.rb +295 -0
  219. data/spec/mongo/database_spec.rb +302 -0
  220. data/spec/mongo/error/parser_spec.rb +119 -0
  221. data/spec/mongo/event/publisher_spec.rb +50 -0
  222. data/spec/mongo/event/subscriber_spec.rb +34 -0
  223. data/spec/mongo/grid/file/chunk_spec.rb +226 -0
  224. data/spec/mongo/grid/file/metadata_spec.rb +92 -0
  225. data/spec/mongo/grid/file_spec.rb +172 -0
  226. data/spec/mongo/grid/fs_spec.rb +129 -0
  227. data/spec/mongo/index/view_spec.rb +330 -0
  228. data/spec/mongo/loggable_spec.rb +62 -0
  229. data/spec/mongo/logger_spec.rb +97 -0
  230. data/spec/mongo/operation/aggregate/result_spec.rb +80 -0
  231. data/spec/mongo/operation/aggregate_spec.rb +127 -0
  232. data/spec/mongo/operation/command_spec.rb +98 -0
  233. data/spec/mongo/operation/kill_cursors_spec.rb +66 -0
  234. data/spec/mongo/operation/limited_spec.rb +50 -0
  235. data/spec/mongo/operation/map_reduce_spec.rb +143 -0
  236. data/spec/mongo/operation/read/collections_info_spec.rb +40 -0
  237. data/spec/mongo/operation/read/get_more_spec.rb +81 -0
  238. data/spec/mongo/operation/read/indexes_spec.rb +31 -0
  239. data/spec/mongo/operation/read/query_spec.rb +84 -0
  240. data/spec/mongo/operation/result_spec.rb +275 -0
  241. data/spec/mongo/operation/specifiable_spec.rb +53 -0
  242. data/spec/mongo/operation/write/bulk_delete_spec.rb +235 -0
  243. data/spec/mongo/operation/write/bulk_insert_spec.rb +235 -0
  244. data/spec/mongo/operation/write/bulk_update_spec.rb +236 -0
  245. data/spec/mongo/operation/write/command/delete_spec.rb +103 -0
  246. data/spec/mongo/operation/write/command/insert_spec.rb +103 -0
  247. data/spec/mongo/operation/write/command/update_spec.rb +109 -0
  248. data/spec/mongo/operation/write/create_index_spec.rb +63 -0
  249. data/spec/mongo/operation/write/create_user_spec.rb +44 -0
  250. data/spec/mongo/operation/write/delete_spec.rb +186 -0
  251. data/spec/mongo/operation/write/drop_index_spec.rb +51 -0
  252. data/spec/mongo/operation/write/insert_spec.rb +244 -0
  253. data/spec/mongo/operation/write/remove_user_spec.rb +46 -0
  254. data/spec/mongo/operation/write/response_spec.rb +85 -0
  255. data/spec/mongo/operation/write/update_spec.rb +228 -0
  256. data/spec/mongo/protocol/delete_spec.rb +167 -0
  257. data/spec/mongo/protocol/get_more_spec.rb +146 -0
  258. data/spec/mongo/protocol/insert_spec.rb +161 -0
  259. data/spec/mongo/protocol/kill_cursors_spec.rb +101 -0
  260. data/spec/mongo/protocol/query_spec.rb +285 -0
  261. data/spec/mongo/protocol/reply_spec.rb +157 -0
  262. data/spec/mongo/protocol/update_spec.rb +186 -0
  263. data/spec/mongo/server/connection_pool/queue_spec.rb +170 -0
  264. data/spec/mongo/server/connection_pool_spec.rb +120 -0
  265. data/spec/mongo/server/connection_spec.rb +312 -0
  266. data/spec/mongo/server/description/features_spec.rb +138 -0
  267. data/spec/mongo/server/description/inspector/primary_elected_spec.rb +94 -0
  268. data/spec/mongo/server/description/inspector/server_added_spec.rb +92 -0
  269. data/spec/mongo/server/description/inspector/server_removed_spec.rb +95 -0
  270. data/spec/mongo/server/description_spec.rb +510 -0
  271. data/spec/mongo/server/monitor_spec.rb +144 -0
  272. data/spec/mongo/server_discovery_and_monitoring_spec.rb +103 -0
  273. data/spec/mongo/server_selection_rtt_spec.rb +104 -0
  274. data/spec/mongo/server_selection_spec.rb +89 -0
  275. data/spec/mongo/server_selector/nearest_spec.rb +250 -0
  276. data/spec/mongo/server_selector/primary_preferred_spec.rb +290 -0
  277. data/spec/mongo/server_selector/primary_spec.rb +114 -0
  278. data/spec/mongo/server_selector/secondary_preferred_spec.rb +252 -0
  279. data/spec/mongo/server_selector/secondary_spec.rb +196 -0
  280. data/spec/mongo/server_selector_spec.rb +101 -0
  281. data/spec/mongo/server_spec.rb +131 -0
  282. data/spec/mongo/uri_spec.rb +517 -0
  283. data/spec/mongo/write_concern/acknowledged_spec.rb +44 -0
  284. data/spec/mongo/write_concern/unacknowledged_spec.rb +15 -0
  285. data/spec/spec_helper.rb +133 -0
  286. data/spec/support/authorization.rb +247 -0
  287. data/spec/support/crud/read.rb +144 -0
  288. data/spec/support/crud/write.rb +214 -0
  289. data/spec/support/crud.rb +203 -0
  290. data/spec/support/crud_tests/read/aggregate.yml +43 -0
  291. data/spec/support/crud_tests/read/count.yml +37 -0
  292. data/spec/support/crud_tests/read/distinct.yml +33 -0
  293. data/spec/support/crud_tests/read/find.yml +50 -0
  294. data/spec/support/crud_tests/write/deleteMany.yml +36 -0
  295. data/spec/support/crud_tests/write/deleteOne.yml +49 -0
  296. data/spec/support/crud_tests/write/findOneAndDelete.yml +54 -0
  297. data/spec/support/crud_tests/write/findOneAndReplace.yml +153 -0
  298. data/spec/support/crud_tests/write/findOneAndUpdate.yml +161 -0
  299. data/spec/support/crud_tests/write/insertMany.yml +24 -0
  300. data/spec/support/crud_tests/write/insertOne.yml +19 -0
  301. data/spec/support/crud_tests/write/replaceOne.yml +96 -0
  302. data/spec/support/crud_tests/write/updateMany.yml +83 -0
  303. data/spec/support/crud_tests/write/updateOne.yml +80 -0
  304. data/spec/support/helpers.rb +140 -0
  305. data/spec/support/matchers.rb +37 -0
  306. data/spec/support/sdam/rs/discover_arbiters.yml +41 -0
  307. data/spec/support/sdam/rs/discover_passives.yml +41 -0
  308. data/spec/support/sdam/rs/discover_primary.yml +40 -0
  309. data/spec/support/sdam/rs/discover_secondary.yml +41 -0
  310. data/spec/support/sdam/rs/discovery.yml +195 -0
  311. data/spec/support/sdam/rs/ghost_discovered.yml +39 -0
  312. data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +34 -0
  313. data/spec/support/sdam/rs/member_reconfig.yml +68 -0
  314. data/spec/support/sdam/rs/member_standalone.yml +60 -0
  315. data/spec/support/sdam/rs/new_primary.yml +74 -0
  316. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +71 -0
  317. data/spec/support/sdam/rs/non_rs_member.yml +31 -0
  318. data/spec/support/sdam/rs/normalize_case.yml +49 -0
  319. data/spec/support/sdam/rs/primary_becomes_standalone.yml +52 -0
  320. data/spec/support/sdam/rs/primary_changes_set_name.yml +57 -0
  321. data/spec/support/sdam/rs/primary_disconnect.yml +56 -0
  322. data/spec/support/sdam/rs/primary_wrong_set_name.yml +27 -0
  323. data/spec/support/sdam/rs/response_from_removed.yml +63 -0
  324. data/spec/support/sdam/rs/rsother_discovered.yml +41 -0
  325. data/spec/support/sdam/rs/sec_not_auth.yml +49 -0
  326. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +28 -0
  327. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +69 -0
  328. data/spec/support/sdam/rs/unexpected_mongos.yml +26 -0
  329. data/spec/support/sdam/rs/wrong_set_name.yml +35 -0
  330. data/spec/support/sdam/sharded/multiple_mongoses.yml +46 -0
  331. data/spec/support/sdam/sharded/non_mongos_removed.yml +41 -0
  332. data/spec/support/sdam/sharded/normalize_uri_case.yml +32 -0
  333. data/spec/support/sdam/single/direct_connection_external_ip.yml +34 -0
  334. data/spec/support/sdam/single/direct_connection_mongos.yml +33 -0
  335. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +35 -0
  336. data/spec/support/sdam/single/direct_connection_rsprimary.yml +34 -0
  337. data/spec/support/sdam/single/direct_connection_rssecondary.yml +35 -0
  338. data/spec/support/sdam/single/direct_connection_slave.yml +32 -0
  339. data/spec/support/sdam/single/direct_connection_standalone.yml +32 -0
  340. data/spec/support/sdam/single/not_ok_response.yml +39 -0
  341. data/spec/support/sdam/single/standalone_removed.yml +32 -0
  342. data/spec/support/sdam/single/unavailable_seed.yml +28 -0
  343. data/spec/support/server_discovery_and_monitoring.rb +167 -0
  344. data/spec/support/server_selection/rtt/first_value.yml +4 -0
  345. data/spec/support/server_selection/rtt/first_value_zero.yml +4 -0
  346. data/spec/support/server_selection/rtt/value_test_1.yml +4 -0
  347. data/spec/support/server_selection/rtt/value_test_2.yml +4 -0
  348. data/spec/support/server_selection/rtt/value_test_3.yml +4 -0
  349. data/spec/support/server_selection/rtt/value_test_4.yml +4 -0
  350. data/spec/support/server_selection/rtt/value_test_5.yml +4 -0
  351. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest.yml +26 -0
  352. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +21 -0
  353. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Primary.yml +21 -0
  354. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +26 -0
  355. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +21 -0
  356. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary.yml +26 -0
  357. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +26 -0
  358. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +21 -0
  359. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +21 -0
  360. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest.yml +33 -0
  361. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +26 -0
  362. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Primary.yml +29 -0
  363. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +29 -0
  364. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +29 -0
  365. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary.yml +31 -0
  366. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred.yml +31 -0
  367. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml +29 -0
  368. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary_non_matching.yml +26 -0
  369. data/spec/support/server_selection/selection/Sharded/read/SecondaryPreferred.yml +26 -0
  370. data/spec/support/server_selection/selection/Single/read/SecondaryPreferred.yml +19 -0
  371. data/spec/support/server_selection/selection/Unknown/read/SecondaryPreferred.yml +11 -0
  372. data/spec/support/server_selection.rb +157 -0
  373. data/spec/support/server_selection_rtt.rb +41 -0
  374. data/spec/support/shared/bulk_write.rb +535 -0
  375. data/spec/support/shared/cursor.rb +38 -0
  376. data/spec/support/shared/operation.rb +77 -0
  377. data/spec/support/shared/protocol.rb +31 -0
  378. data/spec/support/shared/server_selector.rb +111 -0
  379. data/spec/support/shared/socket.rb +82 -0
  380. data/spec/support/travis.rb +14 -0
  381. data.tar.gz.sig +2 -3
  382. metadata +583 -186
  383. metadata.gz.sig +0 -0
  384. data/VERSION +0 -1
  385. data/lib/mongo/bulk_write_collection_view.rb +0 -387
  386. data/lib/mongo/collection_writer.rb +0 -364
  387. data/lib/mongo/connection/node.rb +0 -249
  388. data/lib/mongo/connection/pool.rb +0 -340
  389. data/lib/mongo/connection/pool_manager.rb +0 -320
  390. data/lib/mongo/connection/sharding_pool_manager.rb +0 -67
  391. data/lib/mongo/connection/socket/ssl_socket.rb +0 -95
  392. data/lib/mongo/connection/socket/tcp_socket.rb +0 -87
  393. data/lib/mongo/connection/socket/unix_socket.rb +0 -39
  394. data/lib/mongo/db.rb +0 -808
  395. data/lib/mongo/exception.rb +0 -145
  396. data/lib/mongo/functional/authentication.rb +0 -455
  397. data/lib/mongo/functional/logging.rb +0 -85
  398. data/lib/mongo/functional/read_preference.rb +0 -183
  399. data/lib/mongo/functional/scram.rb +0 -556
  400. data/lib/mongo/functional/uri_parser.rb +0 -409
  401. data/lib/mongo/functional/write_concern.rb +0 -66
  402. data/lib/mongo/gridfs/grid.rb +0 -112
  403. data/lib/mongo/gridfs/grid_ext.rb +0 -53
  404. data/lib/mongo/gridfs/grid_file_system.rb +0 -163
  405. data/lib/mongo/gridfs/grid_io.rb +0 -484
  406. data/lib/mongo/legacy.rb +0 -140
  407. data/lib/mongo/mongo_client.rb +0 -697
  408. data/lib/mongo/mongo_replica_set_client.rb +0 -535
  409. data/lib/mongo/mongo_sharded_client.rb +0 -159
  410. data/lib/mongo/networking.rb +0 -372
  411. data/lib/mongo/utils/conversions.rb +0 -110
  412. data/lib/mongo/utils/core_ext.rb +0 -70
  413. data/lib/mongo/utils/server_version.rb +0 -69
  414. data/lib/mongo/utils/support.rb +0 -80
  415. data/test/functional/authentication_test.rb +0 -39
  416. data/test/functional/bulk_api_stress_test.rb +0 -133
  417. data/test/functional/bulk_write_collection_view_test.rb +0 -1198
  418. data/test/functional/client_test.rb +0 -627
  419. data/test/functional/collection_test.rb +0 -2175
  420. data/test/functional/collection_writer_test.rb +0 -83
  421. data/test/functional/conversions_test.rb +0 -163
  422. data/test/functional/cursor_fail_test.rb +0 -57
  423. data/test/functional/cursor_message_test.rb +0 -56
  424. data/test/functional/cursor_test.rb +0 -683
  425. data/test/functional/db_api_test.rb +0 -835
  426. data/test/functional/db_test.rb +0 -348
  427. data/test/functional/grid_file_system_test.rb +0 -285
  428. data/test/functional/grid_io_test.rb +0 -252
  429. data/test/functional/grid_test.rb +0 -273
  430. data/test/functional/pool_test.rb +0 -136
  431. data/test/functional/safe_test.rb +0 -98
  432. data/test/functional/support_test.rb +0 -62
  433. data/test/functional/timeout_test.rb +0 -60
  434. data/test/functional/uri_test.rb +0 -446
  435. data/test/functional/write_concern_test.rb +0 -118
  436. data/test/helpers/general.rb +0 -50
  437. data/test/helpers/test_unit.rb +0 -476
  438. data/test/replica_set/authentication_test.rb +0 -37
  439. data/test/replica_set/basic_test.rb +0 -189
  440. data/test/replica_set/client_test.rb +0 -393
  441. data/test/replica_set/connection_test.rb +0 -138
  442. data/test/replica_set/count_test.rb +0 -66
  443. data/test/replica_set/cursor_test.rb +0 -220
  444. data/test/replica_set/insert_test.rb +0 -157
  445. data/test/replica_set/max_values_test.rb +0 -151
  446. data/test/replica_set/pinning_test.rb +0 -105
  447. data/test/replica_set/query_test.rb +0 -73
  448. data/test/replica_set/read_preference_test.rb +0 -219
  449. data/test/replica_set/refresh_test.rb +0 -211
  450. data/test/replica_set/replication_ack_test.rb +0 -95
  451. data/test/sharded_cluster/basic_test.rb +0 -203
  452. data/test/shared/authentication/basic_auth_shared.rb +0 -260
  453. data/test/shared/authentication/bulk_api_auth_shared.rb +0 -249
  454. data/test/shared/authentication/gssapi_shared.rb +0 -176
  455. data/test/shared/authentication/sasl_plain_shared.rb +0 -96
  456. data/test/shared/authentication/scram_shared.rb +0 -92
  457. data/test/shared/ssl_shared.rb +0 -235
  458. data/test/test_helper.rb +0 -61
  459. data/test/threading/basic_test.rb +0 -120
  460. data/test/tools/mongo_config.rb +0 -708
  461. data/test/tools/mongo_config_test.rb +0 -160
  462. data/test/unit/client_test.rb +0 -381
  463. data/test/unit/collection_test.rb +0 -166
  464. data/test/unit/connection_test.rb +0 -335
  465. data/test/unit/cursor_test.rb +0 -307
  466. data/test/unit/db_test.rb +0 -136
  467. data/test/unit/grid_test.rb +0 -76
  468. data/test/unit/mongo_sharded_client_test.rb +0 -48
  469. data/test/unit/node_test.rb +0 -93
  470. data/test/unit/pool_manager_test.rb +0 -111
  471. data/test/unit/read_pref_test.rb +0 -406
  472. data/test/unit/read_test.rb +0 -159
  473. data/test/unit/safe_test.rb +0 -158
  474. data/test/unit/sharding_pool_manager_test.rb +0 -84
  475. data/test/unit/write_concern_test.rb +0 -175
@@ -0,0 +1,91 @@
1
+ # Copyright (C) 2014-2015 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
+ module Mongo
16
+
17
+ module ServerSelector
18
+
19
+ # Encapsulates specifications for selecting secondary servers given a list
20
+ # of candidates.
21
+ #
22
+ # @since 2.0.0
23
+ class Secondary
24
+ include Selectable
25
+
26
+ # Get the name of the server mode type.
27
+ #
28
+ # @example Get the name of the server mode for this preference.
29
+ # preference.name
30
+ #
31
+ # @return [ Symbol ] :secondary
32
+ #
33
+ # @since 2.0.0
34
+ def name
35
+ :secondary
36
+ end
37
+
38
+ # Whether the slaveOk bit should be set on wire protocol messages.
39
+ # I.e. whether the operation can be performed on a secondary server.
40
+ #
41
+ # @return [ true ] true
42
+ #
43
+ # @since 2.0.0
44
+ def slave_ok?
45
+ true
46
+ end
47
+
48
+ # Whether tag sets are allowed to be defined for this server preference.
49
+ #
50
+ # @return [ true ] true
51
+ #
52
+ # @since 2.0.0
53
+ def tags_allowed?
54
+ true
55
+ end
56
+
57
+ # Convert this server preference definition into a format appropriate
58
+ # for a mongos server.
59
+ #
60
+ # @example Convert this server preference definition into a format
61
+ # for mongos.
62
+ # preference = Mongo::ServerSelector::Secondary.new
63
+ # preference.to_mongos
64
+ #
65
+ # @return [ Hash ] The server preference formatted for a mongos server.
66
+ #
67
+ # @since 2.0.0
68
+ def to_mongos
69
+ preference = { :mode => 'secondary' }
70
+ preference.merge!({ :tags => tag_sets }) unless tag_sets.empty?
71
+ preference
72
+ end
73
+
74
+ private
75
+
76
+ # Select the secondary servers taking into account any defined tag sets and
77
+ # local threshold between the nearest secondary and other secondaries.
78
+ #
79
+ # @example Select secondary servers given a list of candidates.
80
+ # preference = Mongo::ServerSelector::Secondary.new
81
+ # preference.select([candidate_1, candidate_2])
82
+ #
83
+ # @return [ Array ] The secondary servers from the list of candidates.
84
+ #
85
+ # @since 2.0.0
86
+ def select(candidates)
87
+ near_servers(secondaries(candidates))
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,96 @@
1
+ # Copyright (C) 2014-2015 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
+ module Mongo
16
+
17
+ module ServerSelector
18
+
19
+ # Encapsulates specifications for selecting servers, with
20
+ # secondaries preferred, given a list of candidates.
21
+ #
22
+ # @since 2.0.0
23
+ class SecondaryPreferred
24
+ include Selectable
25
+
26
+ # Get the name of the server mode type.
27
+ #
28
+ # @example Get the name of the server mode for this preference.
29
+ # preference.name
30
+ #
31
+ # @return [ Symbol ] :secondary_preferred
32
+ #
33
+ # @since 2.0.0
34
+ def name
35
+ :secondary_preferred
36
+ end
37
+
38
+ # Whether the slaveOk bit should be set on wire protocol messages.
39
+ # I.e. whether the operation can be performed on a secondary server.
40
+ #
41
+ # @return [ true ] true
42
+ #
43
+ # @since 2.0.0
44
+ def slave_ok?
45
+ true
46
+ end
47
+
48
+ # Whether tag sets are allowed to be defined for this server preference.
49
+ #
50
+ # @return [ true ] true
51
+ #
52
+ # @since 2.0.0
53
+ def tags_allowed?
54
+ true
55
+ end
56
+
57
+ # Convert this server preference definition into a format appropriate
58
+ # for a mongos server.
59
+ # Note that the server preference is not sent to mongos as part of the query
60
+ # selector if there are no tag sets, for maximum backwards compatibility.
61
+ #
62
+ # @example Convert this server preference definition into a format
63
+ # for mongos.
64
+ # preference = Mongo::ServerSelector::SecondaryPreferred.new
65
+ # preference.to_mongos
66
+ #
67
+ # @return [ Hash ] The server preference formatted for a mongos server.
68
+ #
69
+ # @since 2.0.0
70
+ def to_mongos
71
+ return nil if tag_sets.empty?
72
+ preference = { mode: 'secondaryPreferred' }
73
+ preference.merge!({ tags: tag_sets })
74
+ preference
75
+ end
76
+
77
+ private
78
+
79
+ # Select servers taking into account any defined tag sets and
80
+ # local threshold, with secondaries.
81
+ #
82
+ # @example Select servers given a list of candidates,
83
+ # with secondaries preferred.
84
+ # preference = Mongo::ServerSelector::SecondaryPreferred.new
85
+ # preference.select([candidate_1, candidate_2])
86
+ #
87
+ # @return [ Array ] A list of servers matching tag sets and acceptable
88
+ # latency with secondaries preferred.
89
+ #
90
+ # @since 2.0.0
91
+ def select(candidates)
92
+ near_servers(secondaries(candidates)) + primary(candidates)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,209 @@
1
+ # Copyright (C) 2014-2015 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
+ module Mongo
16
+ module ServerSelector
17
+
18
+ # Provides common behavior for filtering a list of servers by server mode or tag set.
19
+ #
20
+ # @since 2.0.0
21
+ module Selectable
22
+
23
+ # The max latency in seconds between the closest server and other servers
24
+ # considered for selection.
25
+ #
26
+ # @since 2.0.0
27
+ LOCAL_THRESHOLD = 0.015.freeze
28
+
29
+ # How long to block for server selection before throwing an exception.
30
+ #
31
+ # @since 2.0.0
32
+ SERVER_SELECTION_TIMEOUT = 30.freeze
33
+
34
+ # @return [ Hash ] options The options.
35
+ attr_reader :options
36
+
37
+ # @return [ Array ] tag_sets The tag sets used to select servers.
38
+ attr_reader :tag_sets
39
+
40
+ # Check equality of two server selector.
41
+ #
42
+ # @example Check server selector equality.
43
+ # preference == other
44
+ #
45
+ # @param [ Object ] other The other preference.
46
+ #
47
+ # @return [ true, false ] Whether the objects are equal.
48
+ #
49
+ # @since 2.0.0
50
+ def ==(other)
51
+ name == other.name && tag_sets == other.tag_sets
52
+ end
53
+
54
+ # Initialize the server selector.
55
+ #
56
+ # @example Initialize the preference with tag sets.
57
+ # Mongo::ServerSelector::Secondary.new([{ 'tag' => 'set' }])
58
+ #
59
+ # @example Initialize the preference with no options.
60
+ # Mongo::ServerSelector::Secondary.new
61
+ #
62
+ # @param [ Array ] tag_sets The tag sets used to select servers.
63
+ #
64
+ # @todo: document specific error
65
+ # @raise [ Exception ] If tag sets are specified but not allowed.
66
+ #
67
+ # @since 2.0.0
68
+ def initialize(tag_sets = [], options = {})
69
+ if !tag_sets.all? { |set| set.empty? } && !tags_allowed?
70
+ raise ServerSelector::InvalidServerPreference.new(name)
71
+ end
72
+ @tag_sets = tag_sets
73
+ @options = options
74
+ end
75
+
76
+ # Select a server from eligible candidates.
77
+ #
78
+ # @example Select a server from the cluster.
79
+ # selector.select_server(cluster)
80
+ #
81
+ # @param [ Mongo::Cluster ] cluster The cluster from which to select an eligible server.
82
+ #
83
+ # @return [ Mongo::Server ] A server matching the server preference.
84
+ #
85
+ # @since 2.0.0
86
+ def select_server(cluster)
87
+ deadline = Time.now + server_selection_timeout
88
+ while (deadline - Time.now) > 0
89
+ if cluster.standalone?
90
+ servers = cluster.servers
91
+ elsif cluster.sharded?
92
+ servers = near_servers(cluster.servers)
93
+ else
94
+ servers = select(cluster.servers)
95
+ end
96
+ return servers.first if servers && !servers.compact.empty?
97
+ cluster.scan!
98
+ end
99
+ raise NoServerAvailable.new(self)
100
+ end
101
+
102
+ # Get the timeout for server selection.
103
+ #
104
+ # @example Get the server selection timeout, in seconds.
105
+ # selector.server_selection_timeout
106
+ #
107
+ # @return [ Float ] The timeout.
108
+ #
109
+ # @since 2.0.0
110
+ def server_selection_timeout
111
+ @server_selection_timeout ||=
112
+ (options[:server_selection_timeout] || SERVER_SELECTION_TIMEOUT)
113
+ end
114
+
115
+ # Get the local threshold boundary for nearest selection in seconds.
116
+ #
117
+ # @example Get the local threshold.
118
+ # selector.local_threshold
119
+ #
120
+ # @return [ Float ] The local threshold.
121
+ #
122
+ # @since 2.0.0
123
+ def local_threshold
124
+ @local_threshold ||= (options[:local_threshold] || LOCAL_THRESHOLD)
125
+ end
126
+
127
+ private
128
+
129
+ # Select the primary from a list of provided candidates.
130
+ #
131
+ # @param [ Array ] candidates List of candidate servers to select the
132
+ # primary from.
133
+ #
134
+ # @return [ Array ] The primary.
135
+ #
136
+ # @since 2.0.0
137
+ def primary(candidates)
138
+ candidates.select do |server|
139
+ server.primary? || server.standalone?
140
+ end
141
+ end
142
+
143
+ # Select the secondaries from a list of provided candidates.
144
+ #
145
+ # @param [ Array ] candidates List of candidate servers to select the
146
+ # secondaries from.
147
+ #
148
+ # @return [ Array ] The secondary servers.
149
+ #
150
+ # @since 2.0.0
151
+ def secondaries(candidates)
152
+ matching_servers = candidates.select(&:secondary?)
153
+ matching_servers = match_tag_sets(matching_servers) unless tag_sets.empty?
154
+ matching_servers
155
+ end
156
+
157
+ # Select the near servers from a list of provided candidates, taking the
158
+ # local threshold into account.
159
+ #
160
+ # @param [ Array ] candidates List of candidate servers to select the
161
+ # near servers from.
162
+ #
163
+ # @return [ Array ] The near servers.
164
+ #
165
+ # @since 2.0.0
166
+ def near_servers(candidates = [])
167
+ return candidates if candidates.empty?
168
+ nearest_server = candidates.min_by(&:average_round_trip_time)
169
+ threshold = nearest_server.average_round_trip_time + (local_threshold * 1000)
170
+ candidates.select { |server| server.average_round_trip_time <= threshold }.shuffle!
171
+ end
172
+
173
+ # Select the servers matching the defined tag sets.
174
+ #
175
+ # @param [ Array ] candidates List of candidate servers from which those
176
+ # matching the defined tag sets should be selected.
177
+ #
178
+ # @return [ Array ] The servers matching the defined tag sets.
179
+ #
180
+ # @since 2.0.0
181
+ def match_tag_sets(candidates)
182
+ matches = []
183
+ tag_sets.find do |tag_set|
184
+ matches = candidates.select { |server| server.matches_tag_set?(tag_set) }
185
+ !matches.empty?
186
+ end
187
+ matches || []
188
+ end
189
+ end
190
+
191
+ # Raised when an invalid server preference is provided.
192
+ #
193
+ # @since 2.0.0
194
+ class InvalidServerPreference < Error
195
+
196
+ # Instantiate the new exception.
197
+ #
198
+ # @example Instantiate the exception.
199
+ # Mongo::ServerSelector::InvalidServerPreference.new
200
+ #
201
+ # @param [ String ] name The preference name.
202
+ #
203
+ # @since 2.0.0
204
+ def initialize(name)
205
+ super("This server preference #{name} cannot be combined with tags.")
206
+ end
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,81 @@
1
+ # Copyright (C) 2014-2015 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
+ require 'mongo/server_selector/selectable'
16
+ require 'mongo/server_selector/nearest'
17
+ require 'mongo/server_selector/primary'
18
+ require 'mongo/server_selector/primary_preferred'
19
+ require 'mongo/server_selector/secondary'
20
+ require 'mongo/server_selector/secondary_preferred'
21
+
22
+ module Mongo
23
+
24
+ # Functionality for getting an object able to select a server, given a preference.
25
+ #
26
+ # @since 2.0.0
27
+ module ServerSelector
28
+ extend self
29
+
30
+ # Hash lookup for the selector classes based off the symbols
31
+ # provided in configuration.
32
+ #
33
+ # @since 2.0.0
34
+ PREFERENCES = {
35
+ nearest: Nearest,
36
+ primary: Primary,
37
+ primary_preferred: PrimaryPreferred,
38
+ secondary: Secondary,
39
+ secondary_preferred: SecondaryPreferred
40
+ }.freeze
41
+
42
+ # Create a server selector object.
43
+ #
44
+ # @example Get a server selector object for selecting a secondary with
45
+ # specific tag sets.
46
+ # Mongo::ServerSelector.get({ :mode => :secondary, :tag_sets => [{'dc' => 'nyc'}] })
47
+ #
48
+ # @param [ Hash ] preference The server preference.
49
+ # @param [ Hash ] options The preference options.
50
+ #
51
+ # @option preference :mode [ Symbol ] The preference mode.
52
+ # @option preference :tag_sets [ Array<Hash> ] The tag sets.
53
+ #
54
+ # @since 2.0.0
55
+ def get(preference = {}, options = {})
56
+ PREFERENCES.fetch(preference[:mode] || :primary).new(
57
+ preference[:tag_sets] || [],
58
+ options
59
+ )
60
+ end
61
+
62
+ # Exception raised if there are no servers available matching the preference.
63
+ #
64
+ # @since 2.0.0
65
+ class NoServerAvailable < Error
66
+
67
+ # Instantiate the new exception.
68
+ #
69
+ # @example Instantiate the exception.
70
+ # Mongo::ServerSelector::NoServerAvailable.new(server_selector)
71
+ #
72
+ # @param [ Hash ] server_selector The server preference that could not be
73
+ # satisfied.
74
+ #
75
+ # @since 2.0.0
76
+ def initialize(server_selector)
77
+ super("No server is available matching preference: #{server_selector.inspect}")
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,130 @@
1
+ # Copyright (C) 2014-2015 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
+ require 'openssl'
16
+
17
+ module Mongo
18
+ class Socket
19
+
20
+ # Wrapper for SSL sockets.
21
+ #
22
+ # @since 2.0.0
23
+ class SSL < Socket
24
+ include OpenSSL
25
+
26
+ # @return [ SSLContext ] context The ssl context.
27
+ attr_reader :context
28
+
29
+ # @return [ String ] host The host to connect to.
30
+ attr_reader :host
31
+
32
+ # @return [ Hash ] The ssl options.
33
+ attr_reader :options
34
+
35
+ # @return [ Integer ] port The port to connect to.
36
+ attr_reader :port
37
+
38
+ # @return [ Float ] timeout The connection timeout.
39
+ attr_reader :timeout
40
+
41
+ # Establishes a socket connection.
42
+ #
43
+ # @example Connect the socket.
44
+ # sock.connect!
45
+ #
46
+ # @note This method mutates the object by setting the socket
47
+ # internally.
48
+ #
49
+ # @return [ SSL ] The connected socket instance.
50
+ #
51
+ # @since 2.0.0
52
+ def connect!
53
+ Timeout.timeout(timeout, Error::SocketTimeoutError) do
54
+ @tcp_socket.connect(::Socket.pack_sockaddr_in(port, host))
55
+ @socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
56
+ @socket.sync_close = true
57
+ @socket.connect
58
+ verify_certificate!(@socket)
59
+ self
60
+ end
61
+ end
62
+
63
+ # Initializes a new SSL socket.
64
+ #
65
+ # @example Create the SSL socket.
66
+ # SSL.new('::1', 27017, 30)
67
+ #
68
+ # @param [ String ] host The hostname or IP address.
69
+ # @param [ Integer ] port The port number.
70
+ # @param [ Float ] timeout The socket timeout value.
71
+ # @param [ Integer ] family The socket family.
72
+ # @param [ Hash ] options The ssl options.
73
+ #
74
+ # @since 2.0.0
75
+ def initialize(host, port, timeout, family, options = {})
76
+ @host, @port, @timeout, @options = host, port, timeout, options
77
+ @context = create_context(options)
78
+ @family = family
79
+ @tcp_socket = ::Socket.new(family, SOCK_STREAM, 0)
80
+ @tcp_socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
81
+ encoded_timeout = [ timeout, 0 ].pack(TIMEOUT_PACK)
82
+ @tcp_socket.set_encoding(BSON::BINARY)
83
+ @tcp_socket.setsockopt(SOL_SOCKET, SO_RCVTIMEO, encoded_timeout)
84
+ @tcp_socket.setsockopt(SOL_SOCKET, SO_SNDTIMEO, encoded_timeout)
85
+ end
86
+
87
+ # Read a single byte from the socket.
88
+ #
89
+ # @example Read a single byte.
90
+ # socket.readbyte
91
+ #
92
+ # @return [ Object ] The read byte.
93
+ #
94
+ # @since 2.0.0
95
+ def readbyte
96
+ handle_errors { socket.read(1) }
97
+ end
98
+
99
+ private
100
+
101
+ def create_context(options)
102
+ context = OpenSSL::SSL::SSLContext.new
103
+ if options[:ssl_cert]
104
+ context.cert = OpenSSL::X509::Certificate.new(File.open(options[:ssl_cert]))
105
+ end
106
+ if options[:ssl_key]
107
+ if options[:ssl_key_pass_phrase]
108
+ context.key = OpenSSL::PKey::RSA.new(File.open(options[:ssl_key]),
109
+ options[:ssl_key_pass_phrase])
110
+ else
111
+ context.key = OpenSSL::PKey::RSA.new(File.open(options[:ssl_key]))
112
+ end
113
+ end
114
+ if options[:ssl_verify] || options[:ssl_ca_cert]
115
+ context.ca_file = options[:ssl_ca_cert]
116
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
117
+ end
118
+ context
119
+ end
120
+
121
+ def verify_certificate!(socket)
122
+ if context.verify_mode == OpenSSL::SSL::VERIFY_PEER
123
+ unless OpenSSL::SSL.verify_certificate_identity(socket.peer_cert, host)
124
+ raise Error::SocketError, 'SSL handshake failed due to a hostname mismatch.'
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,69 @@
1
+ # Copyright (C) 2014-2015 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
+ module Mongo
16
+ class Socket
17
+
18
+ # Wrapper for TCP sockets.
19
+ #
20
+ # @since 2.0.0
21
+ class TCP < Socket
22
+
23
+ # @return [ String ] host The host to connect to.
24
+ attr_reader :host
25
+
26
+ # @return [ Integer ] port The port to connect to.
27
+ attr_reader :port
28
+
29
+ # @return [ Float ] timeout The connection timeout.
30
+ attr_reader :timeout
31
+
32
+ # Establishes a socket connection.
33
+ #
34
+ # @example Connect the socket.
35
+ # sock.connect!
36
+ #
37
+ # @note This method mutates the object by setting the socket
38
+ # internally.
39
+ #
40
+ # @return [ TCP ] The connected socket instance.
41
+ #
42
+ # @since 2.0.0
43
+ def connect!
44
+ Timeout.timeout(timeout, Error::SocketTimeoutError) do
45
+ socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
46
+ socket.connect(::Socket.pack_sockaddr_in(port, host))
47
+ self
48
+ end
49
+ end
50
+
51
+ # Initializes a new TCP socket.
52
+ #
53
+ # @example Create the TCP socket.
54
+ # TCP.new('::1', 27017, 30)
55
+ # TCP.new('127.0.0.1', 27017, 30)
56
+ #
57
+ # @param [ String ] host The hostname or IP address.
58
+ # @param [ Integer ] port The port number.
59
+ # @param [ Float ] timeout The socket timeout value.
60
+ # @param [ Integer ] family The socket family.
61
+ #
62
+ # @since 2.0.0
63
+ def initialize(host, port, timeout, family)
64
+ @host, @port, @timeout = host, port, timeout
65
+ super(family)
66
+ end
67
+ end
68
+ end
69
+ end