mongo 2.11.6 → 2.12.0.rc0

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 (327) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -2
  3. data.tar.gz.sig +0 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/lib/mongo.rb +3 -0
  6. data/lib/mongo/address.rb +13 -2
  7. data/lib/mongo/auth.rb +1 -0
  8. data/lib/mongo/auth/credential_cache.rb +51 -0
  9. data/lib/mongo/auth/scram/conversation.rb +20 -16
  10. data/lib/mongo/auth/user.rb +0 -8
  11. data/lib/mongo/auth/user/view.rb +4 -4
  12. data/lib/mongo/background_thread.rb +1 -1
  13. data/lib/mongo/bulk_write.rb +5 -5
  14. data/lib/mongo/client.rb +126 -11
  15. data/lib/mongo/client_encryption.rb +103 -0
  16. data/lib/mongo/cluster.rb +2 -2
  17. data/lib/mongo/cluster/reapers/cursor_reaper.rb +18 -6
  18. data/lib/mongo/cluster/sdam_flow.rb +54 -58
  19. data/lib/mongo/cluster/srv_monitor.rb +1 -1
  20. data/lib/mongo/collection.rb +3 -3
  21. data/lib/mongo/collection/view.rb +1 -1
  22. data/lib/mongo/collection/view/aggregation.rb +1 -1
  23. data/lib/mongo/collection/view/change_stream.rb +12 -3
  24. data/lib/mongo/collection/view/iterable.rb +14 -5
  25. data/lib/mongo/collection/view/map_reduce.rb +2 -2
  26. data/lib/mongo/collection/view/readable.rb +7 -9
  27. data/lib/mongo/collection/view/writable.rb +7 -7
  28. data/lib/mongo/crypt.rb +33 -0
  29. data/lib/mongo/crypt/auto_decryption_context.rb +42 -0
  30. data/lib/mongo/crypt/auto_encrypter.rb +169 -0
  31. data/lib/mongo/crypt/auto_encryption_context.rb +44 -0
  32. data/lib/mongo/crypt/binary.rb +155 -0
  33. data/lib/mongo/crypt/binding.rb +1162 -0
  34. data/lib/mongo/crypt/context.rb +135 -0
  35. data/lib/mongo/crypt/data_key_context.rb +162 -0
  36. data/lib/mongo/crypt/encryption_io.rb +283 -0
  37. data/lib/mongo/crypt/explicit_decryption_context.rb +40 -0
  38. data/lib/mongo/crypt/explicit_encrypter.rb +117 -0
  39. data/lib/mongo/crypt/explicit_encryption_context.rb +89 -0
  40. data/lib/mongo/crypt/handle.rb +293 -0
  41. data/lib/mongo/crypt/hooks.rb +90 -0
  42. data/lib/mongo/crypt/kms_context.rb +67 -0
  43. data/lib/mongo/crypt/status.rb +131 -0
  44. data/lib/mongo/cursor.rb +64 -32
  45. data/lib/mongo/database.rb +13 -6
  46. data/lib/mongo/database/view.rb +13 -4
  47. data/lib/mongo/dbref.rb +9 -2
  48. data/lib/mongo/error.rb +5 -1
  49. data/lib/mongo/error/crypt_error.rb +31 -0
  50. data/lib/mongo/error/{failed_stringprep_validation.rb → failed_string_prep_validation.rb} +0 -0
  51. data/lib/mongo/error/invalid_cursor_operation.rb +27 -0
  52. data/lib/mongo/error/kms_error.rb +22 -0
  53. data/lib/mongo/error/max_bson_size.rb +14 -3
  54. data/lib/mongo/error/mongocryptd_spawn_error.rb +22 -0
  55. data/lib/mongo/error/no_server_available.rb +8 -3
  56. data/lib/mongo/error/operation_failure.rb +1 -0
  57. data/lib/mongo/grid/file.rb +0 -5
  58. data/lib/mongo/grid/file/chunk.rb +0 -2
  59. data/lib/mongo/grid/file/info.rb +2 -1
  60. data/lib/mongo/grid/fs_bucket.rb +13 -15
  61. data/lib/mongo/grid/stream/write.rb +3 -9
  62. data/lib/mongo/index/view.rb +3 -3
  63. data/lib/mongo/monitoring/event/command_started.rb +6 -1
  64. data/lib/mongo/operation/collections_info.rb +6 -3
  65. data/lib/mongo/operation/delete/op_msg.rb +1 -1
  66. data/lib/mongo/operation/find/op_msg.rb +4 -1
  67. data/lib/mongo/operation/get_more/op_msg.rb +4 -1
  68. data/lib/mongo/operation/insert/command.rb +2 -2
  69. data/lib/mongo/operation/insert/legacy.rb +2 -2
  70. data/lib/mongo/operation/insert/op_msg.rb +3 -3
  71. data/lib/mongo/operation/result.rb +36 -27
  72. data/lib/mongo/operation/shared/executable.rb +10 -8
  73. data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
  74. data/lib/mongo/operation/shared/op_msg_or_command.rb +2 -2
  75. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +2 -2
  76. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +2 -2
  77. data/lib/mongo/operation/shared/write.rb +17 -10
  78. data/lib/mongo/operation/update/op_msg.rb +1 -1
  79. data/lib/mongo/protocol/compressed.rb +6 -5
  80. data/lib/mongo/protocol/insert.rb +3 -1
  81. data/lib/mongo/protocol/message.rb +72 -8
  82. data/lib/mongo/protocol/msg.rb +191 -37
  83. data/lib/mongo/protocol/query.rb +7 -9
  84. data/lib/mongo/protocol/serializers.rb +6 -2
  85. data/lib/mongo/server.rb +10 -4
  86. data/lib/mongo/server/connection.rb +20 -9
  87. data/lib/mongo/server/connection_base.rb +81 -12
  88. data/lib/mongo/server/connection_common.rb +61 -0
  89. data/lib/mongo/server/connection_pool.rb +37 -1
  90. data/lib/mongo/server/description.rb +9 -11
  91. data/lib/mongo/server/monitor.rb +2 -0
  92. data/lib/mongo/server/monitor/connection.rb +3 -18
  93. data/lib/mongo/server/pending_connection.rb +2 -1
  94. data/lib/mongo/session.rb +2 -2
  95. data/lib/mongo/session/session_pool.rb +8 -3
  96. data/lib/mongo/socket.rb +29 -16
  97. data/lib/mongo/socket/ssl.rb +23 -8
  98. data/lib/mongo/socket/tcp.rb +12 -3
  99. data/lib/mongo/timeout.rb +49 -0
  100. data/lib/mongo/uri.rb +30 -1
  101. data/lib/mongo/version.rb +1 -1
  102. data/mongo.gemspec +1 -1
  103. data/spec/README.md +134 -7
  104. data/spec/integration/auth_spec.rb +53 -0
  105. data/spec/integration/{client_options_spec.rb → client_authentication_options_spec.rb} +10 -10
  106. data/spec/integration/client_construction_spec.rb +76 -1
  107. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +351 -0
  108. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +301 -0
  109. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +71 -0
  110. data/spec/integration/client_side_encryption/auto_encryption_old_wire_version_spec.rb +76 -0
  111. data/spec/integration/client_side_encryption/auto_encryption_reconnect_spec.rb +216 -0
  112. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +600 -0
  113. data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +183 -0
  114. data/spec/integration/client_side_encryption/bypass_mongocryptd_spawn_spec.rb +74 -0
  115. data/spec/integration/client_side_encryption/client_close_spec.rb +59 -0
  116. data/spec/integration/client_side_encryption/corpus_spec.rb +228 -0
  117. data/spec/integration/client_side_encryption/custom_endpoint_spec.rb +132 -0
  118. data/spec/integration/client_side_encryption/data_key_spec.rb +163 -0
  119. data/spec/integration/client_side_encryption/explicit_encryption_spec.rb +114 -0
  120. data/spec/integration/client_side_encryption/external_key_vault_spec.rb +137 -0
  121. data/spec/integration/client_side_encryption/views_spec.rb +42 -0
  122. data/spec/integration/client_update_spec.rb +120 -0
  123. data/spec/integration/command_monitoring_spec.rb +3 -1
  124. data/spec/integration/command_spec.rb +44 -10
  125. data/spec/integration/connection_spec.rb +57 -0
  126. data/spec/integration/reconnect_spec.rb +7 -6
  127. data/spec/integration/size_limit_spec.rb +94 -0
  128. data/spec/integration/srv_monitoring_spec.rb +14 -6
  129. data/spec/lite_spec_helper.rb +31 -22
  130. data/spec/mongo/auth/cr_spec.rb +8 -0
  131. data/spec/mongo/auth/ldap_spec.rb +5 -1
  132. data/spec/mongo/auth/scram/conversation_spec.rb +5 -6
  133. data/spec/mongo/auth/scram/negotiation_spec.rb +74 -75
  134. data/spec/mongo/auth/scram_spec.rb +45 -35
  135. data/spec/mongo/auth/x509_spec.rb +5 -1
  136. data/spec/mongo/client_construction_spec.rb +206 -3
  137. data/spec/mongo/client_encryption_spec.rb +408 -0
  138. data/spec/mongo/cluster/cursor_reaper_spec.rb +12 -8
  139. data/spec/mongo/cluster/socket_reaper_spec.rb +14 -3
  140. data/spec/mongo/collection/view/aggregation_spec.rb +0 -2
  141. data/spec/mongo/collection/view/change_stream_spec.rb +7 -7
  142. data/spec/mongo/collection/view/map_reduce_spec.rb +3 -3
  143. data/spec/mongo/collection/view_spec.rb +1 -1
  144. data/spec/mongo/collection_spec.rb +4 -33
  145. data/spec/mongo/crypt/auto_decryption_context_spec.rb +90 -0
  146. data/spec/mongo/crypt/auto_encrypter_spec.rb +182 -0
  147. data/spec/mongo/crypt/auto_encryption_context_spec.rb +107 -0
  148. data/spec/mongo/crypt/binary_spec.rb +115 -0
  149. data/spec/mongo/crypt/binding/binary_spec.rb +56 -0
  150. data/spec/mongo/crypt/binding/context_spec.rb +257 -0
  151. data/spec/mongo/crypt/binding/helpers_spec.rb +46 -0
  152. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +144 -0
  153. data/spec/mongo/crypt/binding/status_spec.rb +99 -0
  154. data/spec/mongo/crypt/binding/version_spec.rb +22 -0
  155. data/spec/mongo/crypt/binding_unloaded_spec.rb +20 -0
  156. data/spec/mongo/crypt/data_key_context_spec.rb +213 -0
  157. data/spec/mongo/crypt/encryption_io_spec.rb +136 -0
  158. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +72 -0
  159. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +170 -0
  160. data/spec/mongo/crypt/handle_spec.rb +198 -0
  161. data/spec/mongo/crypt/helpers/mongo_crypt_spec_helper.rb +108 -0
  162. data/spec/mongo/crypt/status_spec.rb +152 -0
  163. data/spec/mongo/cursor_spec.rb +24 -4
  164. data/spec/mongo/database_spec.rb +20 -0
  165. data/spec/mongo/error/crypt_error_spec.rb +26 -0
  166. data/spec/mongo/error/max_bson_size_spec.rb +35 -0
  167. data/spec/mongo/error/no_server_available_spec.rb +11 -1
  168. data/spec/mongo/error/operation_failure_spec.rb +6 -6
  169. data/spec/mongo/operation/aggregate_spec.rb +1 -1
  170. data/spec/mongo/operation/collections_info_spec.rb +1 -1
  171. data/spec/mongo/operation/command_spec.rb +3 -3
  172. data/spec/mongo/operation/create_index_spec.rb +3 -3
  173. data/spec/mongo/operation/create_user_spec.rb +3 -3
  174. data/spec/mongo/operation/delete/bulk_spec.rb +6 -6
  175. data/spec/mongo/operation/delete/op_msg_spec.rb +1 -6
  176. data/spec/mongo/operation/delete_spec.rb +7 -7
  177. data/spec/mongo/operation/drop_index_spec.rb +2 -2
  178. data/spec/mongo/operation/find/legacy_spec.rb +1 -1
  179. data/spec/mongo/operation/get_more_spec.rb +1 -1
  180. data/spec/mongo/operation/indexes_spec.rb +1 -1
  181. data/spec/mongo/operation/insert/bulk_spec.rb +7 -7
  182. data/spec/mongo/operation/insert/op_msg_spec.rb +3 -6
  183. data/spec/mongo/operation/insert_spec.rb +12 -12
  184. data/spec/mongo/operation/map_reduce_spec.rb +2 -2
  185. data/spec/mongo/operation/remove_user_spec.rb +3 -3
  186. data/spec/mongo/operation/update/bulk_spec.rb +6 -6
  187. data/spec/mongo/operation/update/op_msg_spec.rb +3 -6
  188. data/spec/mongo/operation/update_spec.rb +7 -7
  189. data/spec/mongo/operation/update_user_spec.rb +1 -1
  190. data/spec/mongo/protocol/compressed_spec.rb +2 -3
  191. data/spec/mongo/protocol/delete_spec.rb +9 -8
  192. data/spec/mongo/protocol/get_more_spec.rb +9 -8
  193. data/spec/mongo/protocol/insert_spec.rb +9 -8
  194. data/spec/mongo/protocol/kill_cursors_spec.rb +6 -5
  195. data/spec/mongo/protocol/msg_spec.rb +57 -53
  196. data/spec/mongo/protocol/query_spec.rb +12 -12
  197. data/spec/mongo/protocol/registry_spec.rb +1 -1
  198. data/spec/mongo/protocol/reply_spec.rb +1 -1
  199. data/spec/mongo/protocol/update_spec.rb +10 -9
  200. data/spec/mongo/server/connection_pool_spec.rb +1 -1
  201. data/spec/mongo/server/connection_spec.rb +28 -7
  202. data/spec/mongo/socket_spec.rb +1 -1
  203. data/spec/mongo/timeout_spec.rb +85 -0
  204. data/spec/mongo/uri/srv_protocol_spec.rb +2 -2
  205. data/spec/mongo/uri_spec.rb +52 -5
  206. data/spec/mongo/write_concern_spec.rb +13 -1
  207. data/spec/{support → runners}/auth.rb +14 -1
  208. data/spec/{support → runners}/change_streams.rb +1 -1
  209. data/spec/{support → runners}/change_streams/operation.rb +0 -0
  210. data/spec/{support → runners}/cmap.rb +1 -1
  211. data/spec/{support → runners}/cmap/verifier.rb +0 -0
  212. data/spec/{support → runners}/command_monitoring.rb +0 -0
  213. data/spec/runners/connection_string.rb +358 -4
  214. data/spec/{support → runners}/crud.rb +9 -9
  215. data/spec/{support → runners}/crud/context.rb +0 -0
  216. data/spec/{support → runners}/crud/operation.rb +7 -3
  217. data/spec/{support → runners}/crud/outcome.rb +0 -0
  218. data/spec/{support → runners}/crud/requirement.rb +1 -1
  219. data/spec/{support → runners}/crud/spec.rb +12 -1
  220. data/spec/{support → runners}/crud/test.rb +0 -0
  221. data/spec/{support → runners}/crud/test_base.rb +0 -0
  222. data/spec/{support → runners}/crud/verifier.rb +10 -12
  223. data/spec/{support → runners}/gridfs.rb +0 -0
  224. data/spec/{support → runners}/sdam_monitoring.rb +0 -0
  225. data/spec/{support → runners}/server_discovery_and_monitoring.rb +0 -0
  226. data/spec/{support → runners}/server_selection.rb +0 -0
  227. data/spec/{support → runners}/server_selection_rtt.rb +0 -0
  228. data/spec/{support → runners}/transactions.rb +4 -4
  229. data/spec/{support → runners}/transactions/context.rb +0 -0
  230. data/spec/{support → runners}/transactions/operation.rb +0 -0
  231. data/spec/{support → runners}/transactions/spec.rb +0 -0
  232. data/spec/{support → runners}/transactions/test.rb +37 -5
  233. data/spec/spec_helper.rb +0 -5
  234. data/spec/spec_tests/auth_spec.rb +3 -3
  235. data/spec/spec_tests/client_side_encryption_spec.rb +13 -0
  236. data/spec/spec_tests/connection_string_spec.rb +1 -1
  237. data/spec/spec_tests/data/auth/connection-string.yml +13 -0
  238. data/spec/spec_tests/data/client_side_encryption/aggregate.yml +134 -0
  239. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +526 -0
  240. data/spec/spec_tests/data/client_side_encryption/badSchema.yml +73 -0
  241. data/spec/spec_tests/data/client_side_encryption/basic.yml +116 -0
  242. data/spec/spec_tests/data/client_side_encryption/bulk.yml +85 -0
  243. data/spec/spec_tests/data/client_side_encryption/bypassAutoEncryption.yml +100 -0
  244. data/spec/spec_tests/data/client_side_encryption/bypassedCommand.yml +42 -0
  245. data/spec/spec_tests/data/client_side_encryption/count.yml +61 -0
  246. data/spec/spec_tests/data/client_side_encryption/countDocuments.yml +59 -0
  247. data/spec/spec_tests/data/client_side_encryption/delete.yml +105 -0
  248. data/spec/spec_tests/data/client_side_encryption/distinct.yml +73 -0
  249. data/spec/spec_tests/data/client_side_encryption/explain.yml +64 -0
  250. data/spec/spec_tests/data/client_side_encryption/find.yml +119 -0
  251. data/spec/spec_tests/data/client_side_encryption/findOneAndDelete.yml +57 -0
  252. data/spec/spec_tests/data/client_side_encryption/findOneAndReplace.yml +57 -0
  253. data/spec/spec_tests/data/client_side_encryption/findOneAndUpdate.yml +57 -0
  254. data/spec/spec_tests/data/client_side_encryption/getMore.yml +68 -0
  255. data/spec/spec_tests/data/client_side_encryption/insert.yml +102 -0
  256. data/spec/spec_tests/data/client_side_encryption/keyAltName.yml +71 -0
  257. data/spec/spec_tests/data/client_side_encryption/localKMS.yml +54 -0
  258. data/spec/spec_tests/data/client_side_encryption/localSchema.yml +72 -0
  259. data/spec/spec_tests/data/client_side_encryption/malformedCiphertext.yml +69 -0
  260. data/spec/spec_tests/data/client_side_encryption/maxWireVersion.yml +20 -0
  261. data/spec/spec_tests/data/client_side_encryption/missingKey.yml +49 -0
  262. data/spec/spec_tests/data/client_side_encryption/replaceOne.yml +61 -0
  263. data/spec/spec_tests/data/client_side_encryption/types.yml +527 -0
  264. data/spec/spec_tests/data/client_side_encryption/unsupportedCommand.yml +25 -0
  265. data/spec/spec_tests/data/client_side_encryption/updateMany.yml +77 -0
  266. data/spec/spec_tests/data/client_side_encryption/updateOne.yml +168 -0
  267. data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +1 -4
  268. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +21 -0
  269. data/spec/spec_tests/data/sdam/rs/incompatible_ghost.yml +2 -4
  270. data/spec/spec_tests/data/sdam/rs/incompatible_other.yml +1 -1
  271. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me_not_removed.yml +73 -0
  272. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +1 -2
  273. data/spec/spec_tests/data/sdam/rs/repeated.yml +101 -0
  274. data/spec/spec_tests/data/sdam/rs/{primary_address_change.yml → ruby_primary_address_change.yml} +2 -0
  275. data/spec/spec_tests/data/sdam/rs/{secondary_wrong_set_name_with_primary_second.yml → ruby_secondary_wrong_set_name_with_primary_second.yml} +0 -0
  276. data/spec/spec_tests/data/sdam/sharded/ruby_discovered_single_mongos.yml +27 -0
  277. data/spec/spec_tests/data/sdam/sharded/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
  278. data/spec/spec_tests/data/sdam/sharded/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
  279. data/spec/spec_tests/data/sdam/single/{primary_address_change.yml → ruby_primary_different_address.yml} +1 -1
  280. data/spec/spec_tests/data/sdam/single/{primary_mismatched_me.yml → ruby_primary_mismatched_me.yml} +1 -1
  281. data/spec/spec_tests/data/sdam_monitoring/{replica_set_with_primary_change.yml → replica_set_primary_address_change.yml} +27 -5
  282. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +26 -74
  283. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_removal.yml +20 -16
  284. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +73 -0
  285. data/spec/spec_tests/data/transactions/pin-mongos.yml +2 -3
  286. data/spec/spec_tests/data/uri_options/auth-options.yml +10 -0
  287. data/spec/spec_tests/data/uri_options/tls-options.yml +75 -4
  288. data/spec/spec_tests/read_write_concern_connection_string_spec.rb +1 -1
  289. data/spec/spec_tests/uri_options_spec.rb +6 -8
  290. data/spec/stress/connection_pool_timing_spec.rb +6 -3
  291. data/spec/support/certificates/README.md +4 -0
  292. data/spec/support/certificates/server-second-level-bundle.pem +77 -77
  293. data/spec/support/certificates/server-second-level.crt +52 -52
  294. data/spec/support/certificates/server-second-level.key +25 -25
  295. data/spec/support/certificates/server-second-level.pem +77 -77
  296. data/spec/support/client_registry.rb +19 -3
  297. data/spec/support/cluster_config.rb +9 -1
  298. data/spec/support/common_shortcuts.rb +12 -0
  299. data/spec/support/constraints.rb +16 -0
  300. data/spec/support/crypt.rb +140 -0
  301. data/spec/support/crypt/corpus/corpus-key-aws.json +33 -0
  302. data/spec/support/crypt/corpus/corpus-key-local.json +31 -0
  303. data/spec/support/crypt/corpus/corpus-schema.json +2057 -0
  304. data/spec/support/crypt/corpus/corpus.json +3657 -0
  305. data/spec/support/crypt/corpus/corpus_encrypted.json +4152 -0
  306. data/spec/support/crypt/data_keys/key_document_aws.json +34 -0
  307. data/spec/support/crypt/data_keys/key_document_local.json +31 -0
  308. data/spec/support/crypt/external/external-key.json +31 -0
  309. data/spec/support/crypt/external/external-schema.json +19 -0
  310. data/spec/support/crypt/limits/limits-doc.json +102 -0
  311. data/spec/support/crypt/limits/limits-key.json +31 -0
  312. data/spec/support/crypt/limits/limits-schema.json +1405 -0
  313. data/spec/support/crypt/schema_maps/schema_map_aws.json +17 -0
  314. data/spec/support/crypt/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  315. data/spec/support/crypt/schema_maps/schema_map_local.json +18 -0
  316. data/spec/support/crypt/schema_maps/schema_map_local_key_alt_names.json +12 -0
  317. data/spec/support/lite_constraints.rb +17 -1
  318. data/spec/support/matchers.rb +19 -0
  319. data/spec/support/shared/protocol.rb +2 -0
  320. data/spec/support/spec_config.rb +43 -13
  321. data/spec/support/utils.rb +132 -10
  322. metadata +277 -81
  323. metadata.gz.sig +0 -0
  324. data/spec/integration/grid_fs_bucket_spec.rb +0 -48
  325. data/spec/integration/zlib_compression_spec.rb +0 -25
  326. data/spec/spec_tests/data/sdam/sharded/single_mongos.yml +0 -33
  327. data/spec/support/connection_string.rb +0 -354
@@ -313,6 +313,8 @@ module Mongo
313
313
  #
314
314
  # @since 2.5.0
315
315
  def self.deserialize(buffer)
316
+ raise NotImplementedError
317
+
316
318
  start_size = buffer.length
317
319
  section_size = buffer.get_int32 # get the size
318
320
  end_size = start_size - section_size
@@ -340,8 +342,10 @@ module Mongo
340
342
  def self.serialize(buffer, value, max_bson_size = nil, validating_keys = BSON::Config.validating_keys?)
341
343
  start_size = buffer.length
342
344
  value.to_bson(buffer, validating_keys)
343
- if max_bson_size && buffer.length - start_size > max_bson_size
344
- raise Error::MaxBSONSize.new(max_bson_size)
345
+ serialized_size = buffer.length - start_size
346
+ if max_bson_size && serialized_size > max_bson_size
347
+ raise Error::MaxBSONSize,
348
+ "The document exceeds maximum allowed BSON object size after serialization. Serialized size: #{serialized_size} bytes, maximum allowed size: #{max_bson_size} bytes"
345
349
  end
346
350
  end
347
351
 
@@ -124,11 +124,16 @@ module Mongo
124
124
  # @deprecated
125
125
  def_delegators :monitor, :scan!
126
126
 
127
- # The last compressor discovered by the server monitor.
127
+ # The compressor negotiated by the server monitor, if any.
128
128
  #
129
- # The compressor state should be determined for each individual
130
- # connection rather than kept per server. A future version of the
131
- # driver will change how compressors are tracked and used.
129
+ # This attribute is nil if no server check has not yet completed, and if
130
+ # no compression was negatiated.
131
+ #
132
+ # @note Compression is negotiated for each connection separately.
133
+ #
134
+ # @return [ String | nil ] The negotiated compressor.
135
+ #
136
+ # @deprecated
132
137
  def compressor
133
138
  if monitor
134
139
  monitor.compressor
@@ -523,6 +528,7 @@ end
523
528
 
524
529
  require 'mongo/server/app_metadata'
525
530
  require 'mongo/server/connectable'
531
+ require 'mongo/server/connection_common'
526
532
  require 'mongo/server/connection_base'
527
533
  require 'mongo/server/pending_connection'
528
534
  require 'mongo/server/connection'
@@ -174,7 +174,7 @@ module Mongo
174
174
  unless @socket
175
175
  # When @socket is assigned, the socket should have handshaken and
176
176
  # authenticated and be usable.
177
- @socket = do_connect
177
+ @socket, @description = do_connect
178
178
 
179
179
  publish_cmap_event(
180
180
  Monitoring::Event::Cmap::ConnectionReady.new(address, id)
@@ -186,13 +186,17 @@ module Mongo
186
186
  end
187
187
 
188
188
  # Separate method to permit easier mocking in the test suite.
189
+ #
190
+ # @return [ Array<Socket, Server::Description> ] Connected socket and
191
+ # a server description instance from the ismaster response of the
192
+ # returned socket.
189
193
  def do_connect
190
194
  socket = address.socket(socket_timeout, ssl_options, address.options)
191
195
 
192
196
  begin
193
- handshake!(socket)
194
- unless description.arbiter?
195
- pending_connection = PendingConnection.new(socket, @server, monitoring, options.merge(id: id))
197
+ new_description = handshake!(socket)
198
+ unless new_description.arbiter?
199
+ pending_connection = PendingConnection.new(socket, new_description, @server, monitoring, options.merge(id: id))
196
200
  authenticate!(pending_connection)
197
201
  end
198
202
  rescue Exception
@@ -200,7 +204,7 @@ module Mongo
200
204
  raise
201
205
  end
202
206
 
203
- socket
207
+ [socket, new_description]
204
208
  end
205
209
  private :do_connect
206
210
 
@@ -303,6 +307,8 @@ module Mongo
303
307
 
304
308
  private
305
309
 
310
+ # @return [ Server::Description ] The server description calculated from
311
+ # ismaster response for this particular connection.
306
312
  def handshake!(socket)
307
313
  unless socket
308
314
  raise Error::HandshakeError, "Cannot handshake because there is no usable socket (for #{address})"
@@ -314,7 +320,7 @@ module Mongo
314
320
  response, exc, rtt, average_rtt =
315
321
  @server.round_trip_time_averager.measure do
316
322
  socket.write(app_metadata.ismaster_bytes)
317
- Protocol::Message.deserialize(socket, max_message_size).documents[0]
323
+ Protocol::Message.deserialize(socket, Protocol::Message::MAX_MESSAGE_SIZE).documents[0]
318
324
  end
319
325
 
320
326
  if exc
@@ -330,6 +336,9 @@ module Mongo
330
336
  end
331
337
 
332
338
  # This is a separate method to keep the nesting level down.
339
+ #
340
+ # @return [ Server::Description ] The server description calculated from
341
+ # ismaster response for this particular connection.
333
342
  def post_handshake(response, average_rtt)
334
343
  if response["ok"] == 1
335
344
  # Auth mechanism is entirely dependent on the contents of
@@ -359,12 +368,14 @@ module Mongo
359
368
  :mongodb_cr
360
369
  end
361
370
  end
371
+ set_compressor!(response)
362
372
  else
363
373
  @auth_mechanism = nil
364
374
  end
365
375
 
366
- @description = Description.new(address, response, average_rtt)
367
- @server.cluster.run_sdam_flow(@server.description, @description)
376
+ Description.new(address, response, average_rtt).tap do |new_description|
377
+ @server.cluster.run_sdam_flow(@server.description, new_description)
378
+ end
368
379
  end
369
380
 
370
381
  def authenticate!(pending_connection)
@@ -389,7 +400,7 @@ module Mongo
389
400
  @auth_mechanism || (@server.features.scram_sha_1_enabled? ? :scram : :mongodb_cr)
390
401
  end
391
402
 
392
- def deliver(message)
403
+ def deliver(message, client)
393
404
  begin
394
405
  super
395
406
  # Important: timeout errors are not handled here
@@ -22,10 +22,30 @@ module Mongo
22
22
  # the classes which include this module is not part of the public API.
23
23
  #
24
24
  # @api semipublic
25
- class ConnectionBase
25
+ class ConnectionBase < ConnectionCommon
26
26
  extend Forwardable
27
27
  include Monitoring::Publishable
28
28
 
29
+ # The maximum allowed size in bytes that a user-supplied document may
30
+ # take up when serialized, if the server's ismaster response does not
31
+ # include maxBsonObjectSize field.
32
+ #
33
+ # The commands that are sent to the server may exceed this size by
34
+ # MAX_BSON_COMMAND_OVERHEAD.
35
+ #
36
+ # @api private
37
+ DEFAULT_MAX_BSON_OBJECT_SIZE = 16777216
38
+
39
+ # The additional overhead allowed for command data (i.e. fields added
40
+ # to the command document by the driver, as opposed to documents
41
+ # provided by the user) when serializing a complete command to BSON.
42
+ #
43
+ # @api private
44
+ MAX_BSON_COMMAND_OVERHEAD = 16384
45
+
46
+ # @api private
47
+ REDUCED_MAX_BSON_SIZE = 2097152
48
+
29
49
  # @return [ Hash ] options The passed in options.
30
50
  attr_reader :options
31
51
 
@@ -38,14 +58,31 @@ module Mongo
38
58
  def_delegators :server, :address
39
59
 
40
60
  def_delegators :server,
41
- :features,
42
- :max_bson_object_size,
43
- :max_message_size,
44
- :mongos?,
45
- :compressor,
46
61
  :cluster_time,
47
62
  :update_cluster_time
48
63
 
64
+ # Returns the server description for this connection, derived from
65
+ # the isMaster response for the handshake performed on this connection.
66
+ #
67
+ # @note A connection object that hasn't yet connected (handshaken and
68
+ # authenticated, if authentication is required) does not have a
69
+ # description. While handshaking and authenticating the driver must
70
+ # be using global defaults, in particular not assuming that the
71
+ # properties of a particular connection are the same as properties
72
+ # of other connections made to the same address (since the server
73
+ # on the other end could have been shut down and a different server
74
+ # version could have been launched).
75
+ #
76
+ # @return [ Server::Description ] Server description for this connection.
77
+ # @api private
78
+ attr_reader :description
79
+
80
+ def_delegators :description,
81
+ :features,
82
+ :max_bson_object_size,
83
+ :max_message_size,
84
+ :mongos?
85
+
49
86
  def app_metadata
50
87
  @app_metadata ||= begin
51
88
  same = true
@@ -82,7 +119,7 @@ module Mongo
82
119
  # @return [ Protocol::Message | nil ] The reply if needed.
83
120
  #
84
121
  # @since 2.0.0
85
- def dispatch(messages, operation_id = nil)
122
+ def dispatch(messages, operation_id = nil, client = nil)
86
123
  # The monitoring code does not correctly handle multiple messages,
87
124
  # and the driver internally does not send more than one message at
88
125
  # a time ever. Thus prohibit multiple message use for now.
@@ -90,13 +127,16 @@ module Mongo
90
127
  raise ArgumentError, 'Can only dispatch one message at a time'
91
128
  end
92
129
  message = messages.first
93
- deliver(message)
130
+ deliver(message, client)
94
131
  end
95
132
 
96
133
  private
97
134
 
98
- def deliver(message)
99
- buffer = serialize(message)
135
+ def deliver(message, client)
136
+ if Lint.enabled? && !@socket
137
+ raise Error::LintError, "Trying to deliver a message over a disconnected connection (to #{address})"
138
+ end
139
+ buffer = serialize(message, client)
100
140
  ensure_connected do |socket|
101
141
  operation_id = Monitoring.next_operation_id
102
142
  command_started(address, operation_id, message.payload,
@@ -118,13 +158,42 @@ module Mongo
118
158
  total_duration = Time.now - start
119
159
  command_completed(result, address, operation_id, message.payload, total_duration)
120
160
  end
161
+ if client && result
162
+ result = result.maybe_decrypt(client)
163
+ end
121
164
  result
122
165
  end
123
166
  end
124
167
 
125
- def serialize(message, buffer = BSON::ByteBuffer.new)
168
+ def serialize(message, client, buffer = BSON::ByteBuffer.new)
126
169
  start_size = 0
127
- message.compress!(compressor, options[:zlib_compression_level]).serialize(buffer, max_bson_object_size)
170
+ final_message = message.maybe_compress(compressor, options[:zlib_compression_level])
171
+
172
+ # Driver specifications only mandate the fixed 16MiB limit for
173
+ # serialized BSON documents. However, the server returns its
174
+ # active serialized BSON document size limit in the ismaster response,
175
+ # which is +max_bson_object_size+ below. The +DEFAULT_MAX_BSON_OBJECT_SIZE+
176
+ # is the 16MiB value mandated by the specifications which we use
177
+ # only as the default if the server's ismaster did not contain
178
+ # maxBsonObjectSize.
179
+ max_bson_size = max_bson_object_size || DEFAULT_MAX_BSON_OBJECT_SIZE
180
+ if client && client.encrypter && client.encrypter.encrypt?
181
+ # The client-side encryption specification requires bulk writes to
182
+ # be split at a reduced maxBsonObjectSize. If this message is a bulk
183
+ # write and its size exceeds the reduced size limit, the serializer
184
+ # will raise an exception, which is caught by BulkWrite. BulkWrite
185
+ # will split the operation into individual writes, which will
186
+ # not be subject to the reduced maxBsonObjectSize.
187
+ if message.bulk_write?
188
+ # Make the new maximum size equal to the specified reduced size
189
+ # limit plus the 16KiB overhead allowance.
190
+ max_bson_size = REDUCED_MAX_BSON_SIZE + MAX_BSON_COMMAND_OVERHEAD
191
+ end
192
+ else
193
+ max_bson_size += MAX_BSON_COMMAND_OVERHEAD
194
+ end
195
+
196
+ final_message.serialize(buffer, max_bson_size)
128
197
  if max_message_size &&
129
198
  (buffer.length - start_size) > max_message_size
130
199
  then
@@ -0,0 +1,61 @@
1
+ # Copyright (C) 2020 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 Server
17
+
18
+ # Common methods used by both monitoring and non-monitoring connections.
19
+ #
20
+ # @note Although methods of this module are part of the public API,
21
+ # the fact that these methods are defined on this module and not on
22
+ # the classes which include this module is not part of the public API.
23
+ #
24
+ # @api semipublic
25
+ class ConnectionCommon
26
+
27
+ # The compressor negotiated during the handshake for this connection,
28
+ # if any.
29
+ #
30
+ # This attribute is nil for connections that haven't completed the
31
+ # handshake yet, and for connections that negotiated no compression.
32
+ #
33
+ # @return [ String | nil ] The compressor.
34
+ attr_reader :compressor
35
+
36
+ private
37
+
38
+ def set_compressor!(reply)
39
+ server_compressors = reply['compression']
40
+
41
+ if options[:compressors]
42
+ if intersection = (server_compressors & options[:compressors])
43
+ @compressor = intersection.first
44
+ else
45
+ msg = if server_compressors
46
+ "The server at #{address} has no compression algorithms in common with those requested. " +
47
+ "Server algorithms: #{server_compressors.join(', ')}; " +
48
+ "Requested algorithms: #{options[:compressors].join(', ')}. " +
49
+ "Compression will not be used"
50
+ else
51
+ "The server at #{address} did not advertise compression support. " +
52
+ "Requested algorithms: #{options[:compressors].join(', ')}. " +
53
+ "Compression will not be used"
54
+ end
55
+ log_warn(msg)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -275,6 +275,8 @@ module Mongo
275
275
  #
276
276
  # @since 2.9.0
277
277
  def check_out
278
+ check_invariants
279
+
278
280
  publish_cmap_event(
279
281
  Monitoring::Event::Cmap::ConnectionCheckOutStarted.new(@server.address)
280
282
  )
@@ -345,7 +347,8 @@ module Mongo
345
347
  "from pool for #{@server.address} after #{wait_timeout} sec. " +
346
348
  "Connections in pool: #{@available_connections.length} available, " +
347
349
  "#{@checked_out_connections.length} checked out, " +
348
- "#{@pending_connections.length} pending"
350
+ "#{@pending_connections.length} pending " +
351
+ "(max size: #{max_size})"
349
352
  end
350
353
  raise Error::ConnectionCheckOutTimeout.new(msg, address: @server.address)
351
354
  end
@@ -379,7 +382,10 @@ module Mongo
379
382
  publish_cmap_event(
380
383
  Monitoring::Event::Cmap::ConnectionCheckedOut.new(@server.address, connection.id, self),
381
384
  )
385
+
382
386
  connection
387
+ ensure
388
+ check_invariants
383
389
  end
384
390
 
385
391
  # Check a connection back into the pool.
@@ -390,6 +396,8 @@ module Mongo
390
396
  #
391
397
  # @since 2.9.0
392
398
  def check_in(connection)
399
+ check_invariants
400
+
393
401
  @lock.synchronize do
394
402
  unless connection.connection_pool == self
395
403
  raise ArgumentError, "Trying to check in a connection which was not checked out by this pool: #{connection} checked out from pool #{connection.connection_pool} (for #{self})"
@@ -431,6 +439,8 @@ module Mongo
431
439
  @available_semaphore.signal
432
440
  end
433
441
  end
442
+ ensure
443
+ check_invariants
434
444
  end
435
445
 
436
446
  # Closes all idle connections in the pool and schedules currently checked
@@ -450,6 +460,8 @@ module Mongo
450
460
  def clear(options = nil)
451
461
  raise_if_closed!
452
462
 
463
+ check_invariants
464
+
453
465
  if options && options[:stop_populator]
454
466
  stop_populator
455
467
  end
@@ -471,6 +483,8 @@ module Mongo
471
483
  end
472
484
 
473
485
  true
486
+ ensure
487
+ check_invariants
474
488
  end
475
489
 
476
490
  # @since 2.1.0
@@ -734,6 +748,28 @@ module Mongo
734
748
  raise
735
749
  end
736
750
  end
751
+
752
+ def check_invariants
753
+ return unless Lint.enabled?
754
+
755
+ # Server summary calls pool summary which requires pool lock -> deadlock.
756
+ # Obtain the server summary ahead of time.
757
+ server_summary = @server.summary
758
+
759
+ @lock.synchronize do
760
+ @available_connections.each do |connection|
761
+ if connection.closed?
762
+ raise Error::LintError, "Available connection is closed: #{connection} for #{server_summary}"
763
+ end
764
+ end
765
+
766
+ @pending_connections.each do |connection|
767
+ if connection.closed?
768
+ raise Error::LintError, "Pending connection is closed: #{connection} for #{server_summary}"
769
+ end
770
+ end
771
+ end
772
+ end
737
773
  end
738
774
  end
739
775
  end
@@ -370,8 +370,11 @@ module Mongo
370
370
 
371
371
  # Get the me field value.
372
372
  #
373
- # @example Get the me field value.
374
- # description.me
373
+ # @note The value in me field may differ from the server description's
374
+ # address. This can happen, for example, in split horizon configurations.
375
+ # The SDAM spec only requires removing servers whose me does not match
376
+ # their address in some of the situations (e.g. when the server in
377
+ # question is an RS member but not a primary).
375
378
  #
376
379
  # @return [ String ] The me field.
377
380
  #
@@ -723,7 +726,10 @@ module Mongo
723
726
  def ==(other)
724
727
  return false if self.class != other.class
725
728
  return false if unknown? || other.unknown?
726
- compare_config(other)
729
+
730
+ (config.keys + other.config.keys).uniq.all? do |k|
731
+ config[k] == other.config[k] || EXCLUDE_FOR_COMPARISON.include?(k)
732
+ end
727
733
  end
728
734
  alias_method :eql?, :==
729
735
 
@@ -750,14 +756,6 @@ module Mongo
750
756
 
751
757
  required_wv >= min_wire_version && required_wv <= max_wire_version
752
758
  end
753
-
754
- private
755
-
756
- def compare_config(other)
757
- (config.keys + other.config.keys).uniq.all? do |k|
758
- config[k] == other.config[k] || EXCLUDE_FOR_COMPARISON.include?(k)
759
- end
760
- end
761
759
  end
762
760
  end
763
761
  end