mongo 2.13.0.beta1 → 2.14.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 (339) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -5
  4. data/Rakefile +50 -9
  5. data/lib/mongo.rb +13 -2
  6. data/lib/mongo/address.rb +1 -1
  7. data/lib/mongo/address/ipv4.rb +1 -1
  8. data/lib/mongo/address/ipv6.rb +1 -1
  9. data/lib/mongo/auth/aws/request.rb +31 -5
  10. data/lib/mongo/bulk_write.rb +18 -0
  11. data/lib/mongo/caching_cursor.rb +74 -0
  12. data/lib/mongo/client.rb +238 -31
  13. data/lib/mongo/cluster.rb +56 -20
  14. data/lib/mongo/cluster/sdam_flow.rb +13 -10
  15. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +3 -2
  16. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  17. data/lib/mongo/cluster/topology/single.rb +2 -2
  18. data/lib/mongo/collection.rb +66 -24
  19. data/lib/mongo/collection/view.rb +24 -20
  20. data/lib/mongo/collection/view/aggregation.rb +25 -4
  21. data/lib/mongo/collection/view/builder/find_command.rb +38 -18
  22. data/lib/mongo/collection/view/explainable.rb +27 -8
  23. data/lib/mongo/collection/view/iterable.rb +72 -12
  24. data/lib/mongo/collection/view/readable.rb +19 -3
  25. data/lib/mongo/collection/view/writable.rb +55 -5
  26. data/lib/mongo/crypt/encryption_io.rb +6 -6
  27. data/lib/mongo/cursor.rb +16 -3
  28. data/lib/mongo/database.rb +37 -4
  29. data/lib/mongo/database/view.rb +18 -3
  30. data/lib/mongo/distinguishing_semaphore.rb +55 -0
  31. data/lib/mongo/error.rb +5 -0
  32. data/lib/mongo/error/invalid_read_concern.rb +28 -0
  33. data/lib/mongo/error/invalid_server_auth_host.rb +22 -0
  34. data/lib/mongo/error/invalid_session.rb +2 -1
  35. data/lib/mongo/error/operation_failure.rb +11 -5
  36. data/lib/mongo/error/server_certificate_revoked.rb +22 -0
  37. data/lib/mongo/error/sessions_not_supported.rb +35 -0
  38. data/lib/mongo/error/unsupported_option.rb +14 -12
  39. data/lib/mongo/event/base.rb +6 -0
  40. data/lib/mongo/grid/file.rb +5 -0
  41. data/lib/mongo/grid/file/chunk.rb +2 -0
  42. data/lib/mongo/grid/fs_bucket.rb +15 -13
  43. data/lib/mongo/grid/stream/write.rb +9 -3
  44. data/lib/mongo/index/view.rb +3 -0
  45. data/lib/mongo/lint.rb +2 -1
  46. data/lib/mongo/logger.rb +3 -3
  47. data/lib/mongo/monitoring.rb +38 -0
  48. data/lib/mongo/monitoring/command_log_subscriber.rb +10 -2
  49. data/lib/mongo/monitoring/event/command_failed.rb +11 -0
  50. data/lib/mongo/monitoring/event/command_started.rb +37 -2
  51. data/lib/mongo/monitoring/event/command_succeeded.rb +11 -0
  52. data/lib/mongo/monitoring/event/server_closed.rb +1 -1
  53. data/lib/mongo/monitoring/event/server_description_changed.rb +27 -4
  54. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +9 -2
  55. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +9 -2
  56. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +9 -2
  57. data/lib/mongo/monitoring/event/server_opening.rb +1 -1
  58. data/lib/mongo/monitoring/event/topology_changed.rb +1 -1
  59. data/lib/mongo/monitoring/event/topology_closed.rb +1 -1
  60. data/lib/mongo/monitoring/event/topology_opening.rb +1 -1
  61. data/lib/mongo/monitoring/publishable.rb +6 -3
  62. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +9 -1
  63. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
  64. data/lib/mongo/operation.rb +2 -0
  65. data/lib/mongo/operation/aggregate/result.rb +9 -8
  66. data/lib/mongo/operation/collections_info/command.rb +5 -0
  67. data/lib/mongo/operation/collections_info/result.rb +18 -1
  68. data/lib/mongo/operation/delete/bulk_result.rb +2 -0
  69. data/lib/mongo/operation/delete/result.rb +3 -0
  70. data/lib/mongo/operation/explain/command.rb +4 -0
  71. data/lib/mongo/operation/explain/legacy.rb +4 -0
  72. data/lib/mongo/operation/explain/op_msg.rb +6 -0
  73. data/lib/mongo/operation/explain/result.rb +3 -0
  74. data/lib/mongo/operation/find/legacy/result.rb +2 -0
  75. data/lib/mongo/operation/find/result.rb +13 -0
  76. data/lib/mongo/operation/get_more/result.rb +3 -0
  77. data/lib/mongo/operation/indexes/result.rb +5 -0
  78. data/lib/mongo/operation/insert/bulk_result.rb +5 -0
  79. data/lib/mongo/operation/insert/result.rb +5 -0
  80. data/lib/mongo/operation/list_collections/result.rb +5 -0
  81. data/lib/mongo/operation/map_reduce/result.rb +10 -0
  82. data/lib/mongo/operation/parallel_scan/result.rb +4 -0
  83. data/lib/mongo/operation/result.rb +35 -6
  84. data/lib/mongo/operation/shared/bypass_document_validation.rb +1 -0
  85. data/lib/mongo/operation/shared/causal_consistency_supported.rb +1 -0
  86. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +2 -0
  87. data/lib/mongo/operation/shared/executable.rb +1 -0
  88. data/lib/mongo/operation/shared/idable.rb +2 -1
  89. data/lib/mongo/operation/shared/limited.rb +1 -0
  90. data/lib/mongo/operation/shared/object_id_generator.rb +1 -0
  91. data/lib/mongo/operation/shared/result/aggregatable.rb +1 -0
  92. data/lib/mongo/operation/shared/sessions_supported.rb +1 -0
  93. data/lib/mongo/operation/shared/specifiable.rb +1 -0
  94. data/lib/mongo/operation/shared/write.rb +1 -0
  95. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -0
  96. data/lib/mongo/operation/update/legacy/result.rb +7 -0
  97. data/lib/mongo/operation/update/result.rb +8 -0
  98. data/lib/mongo/operation/users_info/result.rb +3 -0
  99. data/lib/mongo/protocol/message.rb +47 -10
  100. data/lib/mongo/protocol/msg.rb +34 -1
  101. data/lib/mongo/protocol/query.rb +36 -0
  102. data/lib/mongo/protocol/serializers.rb +5 -2
  103. data/lib/mongo/query_cache.rb +242 -0
  104. data/lib/mongo/retryable.rb +8 -1
  105. data/lib/mongo/server.rb +15 -4
  106. data/lib/mongo/server/app_metadata.rb +27 -3
  107. data/lib/mongo/server/connection.rb +4 -4
  108. data/lib/mongo/server/connection_base.rb +38 -12
  109. data/lib/mongo/server/connection_common.rb +2 -2
  110. data/lib/mongo/server/connection_pool.rb +3 -0
  111. data/lib/mongo/server/description.rb +13 -1
  112. data/lib/mongo/server/monitor.rb +76 -44
  113. data/lib/mongo/server/monitor/connection.rb +57 -9
  114. data/lib/mongo/server/pending_connection.rb +14 -4
  115. data/lib/mongo/server/push_monitor.rb +173 -0
  116. data/{spec/runners/transactions/context.rb → lib/mongo/server/push_monitor/connection.rb} +9 -14
  117. data/lib/mongo/server_selector.rb +0 -1
  118. data/lib/mongo/server_selector/base.rb +583 -1
  119. data/lib/mongo/server_selector/nearest.rb +1 -6
  120. data/lib/mongo/server_selector/primary.rb +1 -6
  121. data/lib/mongo/server_selector/primary_preferred.rb +7 -10
  122. data/lib/mongo/server_selector/secondary.rb +1 -6
  123. data/lib/mongo/server_selector/secondary_preferred.rb +1 -7
  124. data/lib/mongo/session.rb +7 -1
  125. data/lib/mongo/socket.rb +26 -12
  126. data/lib/mongo/socket/ocsp_cache.rb +97 -0
  127. data/lib/mongo/socket/ocsp_verifier.rb +368 -0
  128. data/lib/mongo/socket/ssl.rb +46 -25
  129. data/lib/mongo/socket/tcp.rb +1 -1
  130. data/lib/mongo/srv/monitor.rb +7 -13
  131. data/lib/mongo/srv/resolver.rb +14 -10
  132. data/lib/mongo/timeout.rb +2 -0
  133. data/lib/mongo/topology_version.rb +9 -0
  134. data/lib/mongo/uri.rb +21 -390
  135. data/lib/mongo/uri/options_mapper.rb +582 -0
  136. data/lib/mongo/uri/srv_protocol.rb +3 -2
  137. data/lib/mongo/utils.rb +73 -0
  138. data/lib/mongo/version.rb +1 -1
  139. data/spec/NOTES.aws-auth.md +12 -7
  140. data/spec/README.aws-auth.md +2 -2
  141. data/spec/README.md +63 -1
  142. data/spec/integration/awaited_ismaster_spec.rb +28 -0
  143. data/spec/integration/bson_symbol_spec.rb +4 -2
  144. data/spec/integration/bulk_write_spec.rb +67 -0
  145. data/spec/integration/change_stream_examples_spec.rb +6 -2
  146. data/spec/integration/change_stream_spec.rb +1 -1
  147. data/spec/integration/check_clean_slate_spec.rb +16 -0
  148. data/spec/integration/client_authentication_options_spec.rb +92 -28
  149. data/spec/integration/client_construction_spec.rb +1 -0
  150. data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +9 -5
  151. data/spec/integration/connect_single_rs_name_spec.rb +5 -2
  152. data/spec/integration/connection_pool_populator_spec.rb +4 -2
  153. data/spec/integration/connection_spec.rb +7 -4
  154. data/spec/integration/crud_spec.rb +4 -4
  155. data/spec/integration/cursor_reaping_spec.rb +54 -18
  156. data/spec/integration/docs_examples_spec.rb +6 -0
  157. data/spec/integration/fork_reconnect_spec.rb +56 -1
  158. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  159. data/spec/integration/heartbeat_events_spec.rb +4 -23
  160. data/spec/integration/ocsp_connectivity_spec.rb +26 -0
  161. data/spec/integration/ocsp_verifier_cache_spec.rb +188 -0
  162. data/spec/integration/ocsp_verifier_spec.rb +334 -0
  163. data/spec/integration/query_cache_spec.rb +1045 -0
  164. data/spec/integration/query_cache_transactions_spec.rb +190 -0
  165. data/spec/integration/read_concern_spec.rb +1 -1
  166. data/spec/integration/retryable_errors_spec.rb +1 -1
  167. data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -0
  168. data/spec/integration/retryable_writes/shared/performs_legacy_retries.rb +4 -2
  169. data/spec/integration/retryable_writes/shared/performs_modern_retries.rb +3 -3
  170. data/spec/integration/retryable_writes/shared/performs_no_retries.rb +2 -2
  171. data/spec/integration/sdam_error_handling_spec.rb +122 -15
  172. data/spec/integration/sdam_events_spec.rb +80 -6
  173. data/spec/integration/sdam_prose_spec.rb +64 -0
  174. data/spec/integration/server_monitor_spec.rb +25 -1
  175. data/spec/integration/server_selection_spec.rb +36 -0
  176. data/spec/integration/size_limit_spec.rb +23 -5
  177. data/spec/integration/srv_monitoring_spec.rb +38 -3
  178. data/spec/integration/srv_spec.rb +56 -0
  179. data/spec/integration/ssl_uri_options_spec.rb +2 -2
  180. data/spec/integration/transactions_examples_spec.rb +17 -7
  181. data/spec/integration/zlib_compression_spec.rb +25 -0
  182. data/spec/lite_spec_helper.rb +20 -9
  183. data/spec/mongo/address_spec.rb +1 -1
  184. data/spec/mongo/auth/aws/request_region_spec.rb +42 -0
  185. data/spec/mongo/auth/aws/request_spec.rb +76 -0
  186. data/spec/mongo/auth/scram_spec.rb +1 -1
  187. data/spec/mongo/auth/user_spec.rb +1 -1
  188. data/spec/mongo/bulk_write_spec.rb +2 -2
  189. data/spec/mongo/caching_cursor_spec.rb +70 -0
  190. data/spec/mongo/client_construction_spec.rb +386 -3
  191. data/spec/mongo/client_encryption_spec.rb +16 -10
  192. data/spec/mongo/client_spec.rb +85 -3
  193. data/spec/mongo/cluster/topology/replica_set_spec.rb +53 -10
  194. data/spec/mongo/cluster/topology/sharded_spec.rb +1 -1
  195. data/spec/mongo/cluster/topology/single_spec.rb +19 -8
  196. data/spec/mongo/cluster/topology/unknown_spec.rb +1 -1
  197. data/spec/mongo/cluster/topology_spec.rb +1 -1
  198. data/spec/mongo/cluster_spec.rb +37 -35
  199. data/spec/mongo/collection/view/change_stream_resume_spec.rb +7 -7
  200. data/spec/mongo/collection/view/explainable_spec.rb +87 -4
  201. data/spec/mongo/collection/view/map_reduce_spec.rb +2 -0
  202. data/spec/mongo/collection/view/readable_spec.rb +36 -0
  203. data/spec/mongo/collection_spec.rb +572 -0
  204. data/spec/mongo/crypt/auto_decryption_context_spec.rb +1 -1
  205. data/spec/mongo/crypt/auto_encryption_context_spec.rb +1 -1
  206. data/spec/mongo/crypt/binary_spec.rb +1 -6
  207. data/spec/mongo/crypt/binding/binary_spec.rb +1 -6
  208. data/spec/mongo/crypt/binding/context_spec.rb +2 -7
  209. data/spec/mongo/crypt/binding/helpers_spec.rb +1 -6
  210. data/spec/mongo/crypt/binding/mongocrypt_spec.rb +2 -7
  211. data/spec/mongo/crypt/binding/status_spec.rb +1 -6
  212. data/spec/mongo/crypt/binding/version_spec.rb +1 -6
  213. data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
  214. data/spec/mongo/crypt/explicit_decryption_context_spec.rb +1 -1
  215. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +1 -1
  216. data/spec/mongo/crypt/status_spec.rb +1 -6
  217. data/spec/mongo/database_spec.rb +353 -8
  218. data/spec/mongo/distinguishing_semaphore_spec.rb +63 -0
  219. data/spec/mongo/error/no_server_available_spec.rb +1 -1
  220. data/spec/mongo/error/operation_failure_spec.rb +40 -0
  221. data/spec/mongo/index/view_spec.rb +148 -2
  222. data/spec/mongo/logger_spec.rb +13 -11
  223. data/spec/mongo/monitoring/event/server_closed_spec.rb +1 -1
  224. data/spec/mongo/monitoring/event/server_description_changed_spec.rb +1 -4
  225. data/spec/mongo/monitoring/event/server_opening_spec.rb +1 -1
  226. data/spec/mongo/monitoring/event/topology_changed_spec.rb +1 -1
  227. data/spec/mongo/monitoring/event/topology_closed_spec.rb +1 -1
  228. data/spec/mongo/monitoring/event/topology_opening_spec.rb +1 -1
  229. data/spec/mongo/operation/delete/op_msg_spec.rb +3 -3
  230. data/spec/mongo/operation/insert/command_spec.rb +2 -2
  231. data/spec/mongo/operation/insert/op_msg_spec.rb +3 -3
  232. data/spec/mongo/operation/read_preference_op_msg_spec.rb +1 -1
  233. data/spec/mongo/operation/update/command_spec.rb +2 -2
  234. data/spec/mongo/operation/update/op_msg_spec.rb +3 -3
  235. data/spec/mongo/protocol/msg_spec.rb +10 -0
  236. data/spec/mongo/query_cache_spec.rb +280 -0
  237. data/spec/mongo/semaphore_spec.rb +51 -0
  238. data/spec/mongo/server/app_metadata_shared.rb +82 -2
  239. data/spec/mongo/server/connection_auth_spec.rb +2 -2
  240. data/spec/mongo/server/connection_pool_spec.rb +7 -3
  241. data/spec/mongo/server/connection_spec.rb +15 -8
  242. data/spec/mongo/server/description_spec.rb +18 -0
  243. data/spec/mongo/server_selector/nearest_spec.rb +23 -23
  244. data/spec/mongo/server_selector/primary_preferred_spec.rb +26 -26
  245. data/spec/mongo/server_selector/primary_spec.rb +9 -9
  246. data/spec/mongo/server_selector/secondary_preferred_spec.rb +22 -22
  247. data/spec/mongo/server_selector/secondary_spec.rb +18 -18
  248. data/spec/mongo/server_selector_spec.rb +6 -6
  249. data/spec/mongo/session_spec.rb +35 -0
  250. data/spec/mongo/socket/ssl_spec.rb +4 -4
  251. data/spec/mongo/socket_spec.rb +1 -1
  252. data/spec/mongo/uri/srv_protocol_spec.rb +64 -33
  253. data/spec/mongo/uri_option_parsing_spec.rb +11 -11
  254. data/spec/mongo/uri_spec.rb +68 -41
  255. data/spec/mongo/utils_spec.rb +39 -0
  256. data/spec/runners/auth.rb +3 -0
  257. data/spec/runners/change_streams/test.rb +3 -3
  258. data/spec/runners/cmap.rb +1 -1
  259. data/spec/runners/command_monitoring.rb +3 -34
  260. data/spec/runners/connection_string.rb +35 -124
  261. data/spec/runners/crud/context.rb +9 -5
  262. data/spec/runners/crud/operation.rb +59 -27
  263. data/spec/runners/crud/spec.rb +0 -8
  264. data/spec/runners/crud/test.rb +1 -1
  265. data/spec/runners/crud/test_base.rb +0 -19
  266. data/spec/runners/sdam.rb +2 -2
  267. data/spec/runners/server_selection.rb +242 -28
  268. data/spec/runners/transactions.rb +12 -12
  269. data/spec/runners/transactions/operation.rb +151 -25
  270. data/spec/runners/transactions/test.rb +62 -18
  271. data/spec/shared/LICENSE +20 -0
  272. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  273. data/spec/shared/lib/mrss/constraints.rb +303 -0
  274. data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
  275. data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
  276. data/spec/spec_helper.rb +3 -1
  277. data/spec/spec_tests/cmap_spec.rb +7 -3
  278. data/spec/spec_tests/command_monitoring_spec.rb +22 -12
  279. data/spec/spec_tests/crud_spec.rb +1 -1
  280. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +4 -9
  281. data/spec/spec_tests/data/change_streams/change-streams-resume-whitelist.yml +66 -0
  282. data/spec/spec_tests/data/change_streams/change-streams.yml +0 -1
  283. data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +6 -2
  284. data/spec/spec_tests/data/cmap/pool-create-min-size.yml +3 -0
  285. data/spec/spec_tests/data/connection_string/valid-warnings.yml +24 -0
  286. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/MaxStalenessTooSmall.yml +15 -0
  287. data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/NoKnownServers.yml +4 -3
  288. data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -0
  289. data/spec/spec_tests/data/sdam_integration/cancel-server-check.yml +96 -0
  290. data/spec/spec_tests/data/sdam_integration/connectTimeoutMS.yml +88 -0
  291. data/spec/spec_tests/data/sdam_integration/find-network-error.yml +83 -0
  292. data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +116 -0
  293. data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +86 -0
  294. data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +115 -0
  295. data/spec/spec_tests/data/sdam_integration/isMaster-command-error.yml +168 -0
  296. data/spec/spec_tests/data/sdam_integration/isMaster-network-error.yml +162 -0
  297. data/spec/spec_tests/data/sdam_integration/isMaster-timeout.yml +229 -0
  298. data/spec/spec_tests/data/sdam_integration/rediscover-quickly-after-step-down.yml +87 -0
  299. data/spec/spec_tests/data/sdam_monitoring/discovered_standalone.yml +1 -3
  300. data/spec/spec_tests/data/sdam_monitoring/standalone.yml +2 -2
  301. data/spec/spec_tests/data/sdam_monitoring/standalone_repeated.yml +2 -2
  302. data/spec/spec_tests/data/sdam_monitoring/standalone_suppress_equal_description_changes.yml +2 -2
  303. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +2 -2
  304. data/spec/spec_tests/data/uri_options/auth-options.yml +25 -0
  305. data/spec/spec_tests/data/uri_options/compression-options.yml +6 -3
  306. data/spec/spec_tests/data/uri_options/read-preference-options.yml +24 -0
  307. data/spec/spec_tests/data/uri_options/ruby-connection-options.yml +1 -0
  308. data/spec/spec_tests/data/uri_options/tls-options.yml +160 -4
  309. data/spec/spec_tests/dns_seedlist_discovery_spec.rb +9 -1
  310. data/spec/spec_tests/max_staleness_spec.rb +4 -142
  311. data/spec/spec_tests/retryable_reads_spec.rb +2 -2
  312. data/spec/spec_tests/sdam_integration_spec.rb +13 -0
  313. data/spec/spec_tests/sdam_monitoring_spec.rb +1 -2
  314. data/spec/spec_tests/server_selection_spec.rb +4 -116
  315. data/spec/spec_tests/uri_options_spec.rb +31 -33
  316. data/spec/stress/cleanup_spec.rb +17 -2
  317. data/spec/stress/connection_pool_stress_spec.rb +10 -8
  318. data/spec/stress/fork_reconnect_stress_spec.rb +1 -1
  319. data/spec/support/certificates/atlas-ocsp-ca.crt +28 -0
  320. data/spec/support/certificates/atlas-ocsp.crt +41 -0
  321. data/spec/support/client_registry.rb +1 -0
  322. data/spec/support/client_registry_macros.rb +11 -2
  323. data/spec/support/cluster_config.rb +4 -0
  324. data/spec/support/common_shortcuts.rb +45 -0
  325. data/spec/support/constraints.rb +6 -253
  326. data/spec/support/event_subscriber.rb +123 -33
  327. data/spec/support/keyword_struct.rb +26 -0
  328. data/spec/support/matchers.rb +16 -0
  329. data/spec/support/ocsp +1 -0
  330. data/spec/support/session_registry.rb +52 -0
  331. data/spec/support/shared/server_selector.rb +13 -1
  332. data/spec/support/spec_config.rb +60 -13
  333. data/spec/support/spec_setup.rb +1 -1
  334. data/spec/support/utils.rb +84 -1
  335. metadata +1027 -937
  336. metadata.gz.sig +0 -0
  337. data/lib/mongo/server_selector/selectable.rb +0 -560
  338. data/spec/runners/sdam_monitoring.rb +0 -89
  339. data/spec/support/lite_constraints.rb +0 -141
@@ -0,0 +1,582 @@
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 URI
17
+
18
+ # Performs mapping between URI options and Ruby options.
19
+ #
20
+ # This class contains:
21
+ #
22
+ # - The mapping defining how URI options are converted to Ruby options.
23
+ # - The mapping from downcased URI option names to canonical-cased URI
24
+ # option names.
25
+ # - Methods to perform conversion of URI option values to Ruby option
26
+ # values (the convert_* methods). These generally warn and return nil
27
+ # when input given is invalid.
28
+ # - Methods to perform conversion of Ruby option values to standardized
29
+ # MongoClient options (revert_* methods). These assume the input is valid
30
+ # and generally do not perform validation.
31
+ #
32
+ # URI option names are case insensitive. Ruby options are specified as
33
+ # symbols (though in Client options use indifferent access).
34
+ #
35
+ # @api private
36
+ class OptionsMapper
37
+
38
+ include Loggable
39
+
40
+ # Instantates the options mapper.
41
+ #
42
+ # @option opts [ Logger ] :logger A custom logger to use.
43
+ def initialize(**opts)
44
+ @options = opts
45
+ end
46
+
47
+ # @return [ Hash ] The options.
48
+ attr_reader :options
49
+
50
+ # Adds an option to the uri options hash.
51
+ #
52
+ # Acquires a target for the option based on group.
53
+ # Transforms the value.
54
+ # Merges the option into the target.
55
+ #
56
+ # @param [ String ] key URI option name.
57
+ # @param [ String ] value The value of the option.
58
+ # @param [ Hash ] uri_options The base option target.
59
+ def add_uri_option(key, value, uri_options)
60
+ strategy = URI_OPTION_MAP[key.downcase]
61
+ if strategy.nil?
62
+ log_warn("Unsupported URI option '#{key}' on URI '#{@string}'. It will be ignored.")
63
+ return
64
+ end
65
+
66
+ group = strategy[:group]
67
+ target = if group
68
+ uri_options[group] || {}
69
+ else
70
+ uri_options
71
+ end
72
+ value = apply_transform(key, value, strategy[:type])
73
+ # Sometimes the value here would be nil, for example if we are processing
74
+ # read preference tags or auth mechanism properties and all of the
75
+ # data within is invalid. Ignore such options.
76
+ unless value.nil?
77
+ merge_uri_option(target, value, strategy[:name])
78
+ end
79
+
80
+ if group && !target.empty? && !uri_options.key?(group)
81
+ uri_options[group] = target
82
+ end
83
+ end
84
+
85
+ # Converts Ruby options provided to "standardized MongoClient options".
86
+ #
87
+ # @param [ Hash ] opts Ruby options to convert.
88
+ #
89
+ # @return [ Hash ] Standardized MongoClient options.
90
+ def ruby_to_smc(opts)
91
+ rv = {}
92
+ URI_OPTION_MAP.each do |uri_key, spec|
93
+ if spec[:group]
94
+ v = opts[spec[:group]]
95
+ v = v && v[spec[:name]]
96
+ else
97
+ v = opts[spec[:name]]
98
+ end
99
+ unless v.nil?
100
+ if spec[:type]
101
+ v = send("revert_#{spec[:type]}", v)
102
+ end
103
+ canonical_key = URI_OPTION_CANONICAL_NAMES[uri_key]
104
+ unless canonical_key
105
+ raise ArgumentError, "Option #{uri_key} is not known"
106
+ end
107
+ rv[canonical_key] = v
108
+ end
109
+ end
110
+ # For options that default to true, remove the value if it is true.
111
+ %w(retryReads retryWrites).each do |k|
112
+ if rv[k]
113
+ rv.delete(k)
114
+ end
115
+ end
116
+ # Remove auth source when it is $external for mechanisms that default
117
+ # (or require) that auth source.
118
+ if %w(MONGODB-AWS).include?(rv['authMechanism']) && rv['authSource'] == '$external'
119
+ rv.delete('authSource')
120
+ end
121
+ # ssl and tls are aliases, remove ssl ones
122
+ rv.delete('ssl')
123
+ # TODO remove authSource if it is the same as the database,
124
+ # requires this method to know the database specified in the client.
125
+ rv
126
+ end
127
+
128
+ private
129
+
130
+ # Applies URI value transformation by either using the default cast
131
+ # or a transformation appropriate for the given type.
132
+ #
133
+ # @param key [String] URI option name.
134
+ # @param value [String] The value to be transformed.
135
+ # @param type [Symbol] The transform method.
136
+ def apply_transform(key, value, type)
137
+ if type
138
+ send("convert_#{type}", key, value)
139
+ else
140
+ value
141
+ end
142
+ end
143
+
144
+ # Merges a new option into the target.
145
+ #
146
+ # If the option exists at the target destination the merge will
147
+ # be an addition.
148
+ #
149
+ # Specifically required to append an additional tag set
150
+ # to the array of tag sets without overwriting the original.
151
+ #
152
+ # @param target [Hash] The destination.
153
+ # @param value [Object] The value to be merged.
154
+ # @param name [Symbol] The name of the option.
155
+ def merge_uri_option(target, value, name)
156
+ if target.key?(name)
157
+ if REPEATABLE_OPTIONS.include?(name)
158
+ target[name] += value
159
+ else
160
+ log_warn("Repeated option key: #{name}.")
161
+ end
162
+ else
163
+ target.merge!(name => value)
164
+ end
165
+ end
166
+
167
+ # Hash for storing map of URI option parameters to conversion strategies
168
+ URI_OPTION_MAP = {}
169
+
170
+ # @return [ Hash<String, String> ] Map from lowercased to canonical URI
171
+ # option names.
172
+ URI_OPTION_CANONICAL_NAMES = {}
173
+
174
+ # Simple internal dsl to register a MongoDB URI option in the URI_OPTION_MAP.
175
+ #
176
+ # @param uri_key [String] The MongoDB URI option to register.
177
+ # @param name [Symbol] The name of the option in the driver.
178
+ # @param extra [Hash] Extra options.
179
+ # * :group [Symbol] Nested hash where option will go.
180
+ # * :type [Symbol] Name of function to transform value.
181
+ def self.uri_option(uri_key, name, **extra)
182
+ URI_OPTION_MAP[uri_key.downcase] = { name: name }.update(extra)
183
+ URI_OPTION_CANONICAL_NAMES[uri_key.downcase] = uri_key
184
+ end
185
+
186
+ # Replica Set Options
187
+ uri_option 'replicaSet', :replica_set
188
+
189
+ # Timeout Options
190
+ uri_option 'connectTimeoutMS', :connect_timeout, type: :ms
191
+ uri_option 'socketTimeoutMS', :socket_timeout, type: :ms
192
+ uri_option 'serverSelectionTimeoutMS', :server_selection_timeout, type: :ms
193
+ uri_option 'localThresholdMS', :local_threshold, type: :ms
194
+ uri_option 'heartbeatFrequencyMS', :heartbeat_frequency, type: :ms
195
+ uri_option 'maxIdleTimeMS', :max_idle_time, type: :ms
196
+
197
+ # Write Options
198
+ uri_option 'w', :w, group: :write_concern, type: :w
199
+ uri_option 'journal', :j, group: :write_concern, type: :bool
200
+ uri_option 'fsync', :fsync, group: :write_concern, type: :bool
201
+ uri_option 'wTimeoutMS', :wtimeout, group: :write_concern, type: :integer
202
+
203
+ # Read Options
204
+ uri_option 'readPreference', :mode, group: :read, type: :read_mode
205
+ uri_option 'readPreferenceTags', :tag_sets, group: :read, type: :read_tags
206
+ uri_option 'maxStalenessSeconds', :max_staleness, group: :read, type: :max_staleness
207
+
208
+ # Pool options
209
+ uri_option 'minPoolSize', :min_pool_size, type: :integer
210
+ uri_option 'maxPoolSize', :max_pool_size, type: :integer
211
+ uri_option 'waitQueueTimeoutMS', :wait_queue_timeout, type: :ms
212
+
213
+ # Security Options
214
+ uri_option 'ssl', :ssl, type: :repeated_bool
215
+ uri_option 'tls', :ssl, type: :repeated_bool
216
+ uri_option 'tlsAllowInvalidCertificates', :ssl_verify_certificate,
217
+ type: :inverse_bool
218
+ uri_option 'tlsAllowInvalidHostnames', :ssl_verify_hostname,
219
+ type: :inverse_bool
220
+ uri_option 'tlsCAFile', :ssl_ca_cert
221
+ uri_option 'tlsCertificateKeyFile', :ssl_cert
222
+ uri_option 'tlsCertificateKeyFilePassword', :ssl_key_pass_phrase
223
+ uri_option 'tlsInsecure', :ssl_verify, type: :inverse_bool
224
+ uri_option 'tlsDisableOCSPEndpointCheck', :ssl_verify_ocsp_endpoint,
225
+ type: :inverse_bool
226
+
227
+ # Topology options
228
+ uri_option 'directConnection', :direct_connection, type: :bool
229
+ uri_option 'connect', :connect, type: :symbol
230
+
231
+ # Auth Options
232
+ uri_option 'authSource', :auth_source
233
+ uri_option 'authMechanism', :auth_mech, type: :auth_mech
234
+ uri_option 'authMechanismProperties', :auth_mech_properties, type: :auth_mech_props
235
+
236
+ # Client Options
237
+ uri_option 'appName', :app_name
238
+ uri_option 'compressors', :compressors, type: :array
239
+ uri_option 'readConcernLevel', :level, group: :read_concern, type: :symbol
240
+ uri_option 'retryReads', :retry_reads, type: :bool
241
+ uri_option 'retryWrites', :retry_writes, type: :bool
242
+ uri_option 'zlibCompressionLevel', :zlib_compression_level, type: :zlib_compression_level
243
+
244
+ # Converts +value+ to a boolean.
245
+ #
246
+ # Returns true for 'true', false for 'false', otherwise nil.
247
+ #
248
+ # @param [ String ] name Name of the URI option being processed.
249
+ # @param value [ String ] URI option value.
250
+ #
251
+ # @return [ true | false | nil ] Converted value.
252
+ def convert_bool(name, value)
253
+ case value
254
+ when "true", 'TRUE'
255
+ true
256
+ when "false", 'FALSE'
257
+ false
258
+ else
259
+ log_warn("invalid boolean option for #{name}: #{value}")
260
+ nil
261
+ end
262
+ end
263
+
264
+ def revert_bool(value)
265
+ value
266
+ end
267
+
268
+ # Converts the value into a boolean and returns it wrapped in an array.
269
+ #
270
+ # @param name [ String ] Name of the URI option being processed.
271
+ # @param value [ String ] URI option value.
272
+ #
273
+ # @return [ Array<true | false> ] The boolean value parsed and wraped
274
+ # in an array.
275
+ def convert_repeated_bool(name, value)
276
+ [convert_bool(name, value)]
277
+ end
278
+
279
+ def revert_repeated_bool(value)
280
+ value
281
+ end
282
+
283
+ # Parses a boolean value and returns its inverse.
284
+ #
285
+ # @param [ String ] name Name of the URI option being processed.
286
+ # @param value [ String ] The URI option value.
287
+ #
288
+ # @return [ true | false | nil ] The inverse of the boolean value parsed out, otherwise nil
289
+ # (and a warning will be logged).
290
+ def convert_inverse_bool(name, value)
291
+ b = convert_bool(name, value)
292
+
293
+ if b.nil?
294
+ nil
295
+ else
296
+ !b
297
+ end
298
+ end
299
+
300
+ def revert_inverse_bool(value)
301
+ !value
302
+ end
303
+
304
+ # Converts +value+ into an integer.
305
+ #
306
+ # If the value is not a valid integer, warns and returns nil.
307
+ #
308
+ # @param [ String ] name Name of the URI option being processed.
309
+ # @param value [ String ] URI option value.
310
+ #
311
+ # @return [ nil | Integer ] Converted value.
312
+ def convert_integer(name, value)
313
+ unless /\A\d+\z/ =~ value
314
+ log_warn("#{value} is not a valid integer for #{name}")
315
+ return nil
316
+ end
317
+
318
+ value.to_i
319
+ end
320
+
321
+ def revert_integer(value)
322
+ value
323
+ end
324
+
325
+ # Ruby's convention is to provide timeouts in seconds, not milliseconds and
326
+ # to use fractions where more precision is necessary. The connection string
327
+ # options are always in MS so we provide an easy conversion type.
328
+ #
329
+ # @param [ String ] name Name of the URI option being processed.
330
+ # @param [ Integer ] value The millisecond value.
331
+ #
332
+ # @return [ Float ] The seconds value.
333
+ #
334
+ # @since 2.0.0
335
+ def convert_ms(name, value)
336
+ unless /\A-?\d+(\.\d+)?\z/ =~ value
337
+ log_warn("Invalid ms value for #{name}: #{value}")
338
+ return nil
339
+ end
340
+
341
+ if value[0] == '-'
342
+ log_warn("#{name} cannot be a negative number")
343
+ return nil
344
+ end
345
+
346
+ value.to_f / 1000
347
+ end
348
+
349
+ def revert_ms(value)
350
+ (value * 1000).round
351
+ end
352
+
353
+ # Converts +value+ into a symbol.
354
+ #
355
+ # @param [ String ] name Name of the URI option being processed.
356
+ # @param value [ String ] URI option value.
357
+ #
358
+ # @return [ Symbol ] Converted value.
359
+ def convert_symbol(name, value)
360
+ value.to_sym
361
+ end
362
+
363
+ def revert_symbol(value)
364
+ value.to_s
365
+ end
366
+
367
+ # Extract values from the string and put them into an array.
368
+ #
369
+ # @param [ String ] name Name of the URI option being processed.
370
+ # @param [ String ] value The string to build an array from.
371
+ #
372
+ # @return [ Array ] The array built from the string.
373
+ def convert_array(name, value)
374
+ value.split(',')
375
+ end
376
+
377
+ def revert_array(value)
378
+ value
379
+ end
380
+
381
+ # Authentication mechanism transformation.
382
+ #
383
+ # @param [ String ] name Name of the URI option being processed.
384
+ # @param value [String] The authentication mechanism.
385
+ #
386
+ # @return [Symbol] The transformed authentication mechanism.
387
+ def convert_auth_mech(name, value)
388
+ (AUTH_MECH_MAP[value.upcase] || value).tap do |mech|
389
+ log_warn("#{value} is not a valid auth mechanism") unless mech
390
+ end
391
+ end
392
+
393
+ def revert_auth_mech(value)
394
+ found = AUTH_MECH_MAP.detect do |k, v|
395
+ v == value
396
+ end
397
+ if found
398
+ found.first
399
+ else
400
+ raise ArgumentError, "Unknown auth mechanism #{value}"
401
+ end
402
+ end
403
+
404
+ # Auth mechanism properties extractor.
405
+ #
406
+ # @param [ String ] name Name of the URI option being processed.
407
+ # @param value [ String ] The auth mechanism properties string.
408
+ #
409
+ # @return [ Hash ] The auth mechanism properties hash.
410
+ def convert_auth_mech_props(name, value)
411
+ properties = hash_extractor('authMechanismProperties', value)
412
+ if properties
413
+ properties.each do |k, v|
414
+ if k.to_s.downcase == 'canonicalize_host_name' && v
415
+ properties[k] = (v.downcase == 'true')
416
+ end
417
+ end
418
+ end
419
+ properties
420
+ end
421
+
422
+ def revert_auth_mech_props(value)
423
+ value
424
+ end
425
+
426
+ # Parses the max staleness value, which must be either "0" or an integer
427
+ # greater or equal to 90.
428
+ #
429
+ # @param [ String ] name Name of the URI option being processed.
430
+ # @param value [ String ] The max staleness string.
431
+ #
432
+ # @return [ Integer | nil ] The max staleness integer parsed out if it is valid, otherwise nil
433
+ # (and a warning will be logged).
434
+ def convert_max_staleness(name, value)
435
+ if /\A-?\d+\z/ =~ value
436
+ int = value.to_i
437
+
438
+ if int == -1
439
+ int = nil
440
+ end
441
+
442
+ if int && (int >= 0 && int < 90 || int < 0)
443
+ log_warn("max staleness should be either 0 or greater than 90: #{value}")
444
+ int = nil
445
+ end
446
+
447
+ return int
448
+ end
449
+
450
+ log_warn("Invalid max staleness value: #{value}")
451
+ nil
452
+ end
453
+
454
+ def revert_max_staleness(value)
455
+ value
456
+ end
457
+
458
+ # Read preference mode transformation.
459
+ #
460
+ # @param [ String ] name Name of the URI option being processed.
461
+ # @param value [String] The read mode string value.
462
+ #
463
+ # @return [Symbol] The read mode symbol.
464
+ def convert_read_mode(name, value)
465
+ READ_MODE_MAP[value.downcase] || value
466
+ end
467
+
468
+ def revert_read_mode(value)
469
+ value.to_s.gsub(/_(\w)/) { $1.upcase }
470
+ end
471
+
472
+ # Read preference tags transformation.
473
+ #
474
+ # @param [ String ] name Name of the URI option being processed.
475
+ # @param value [String] The string representing tag set.
476
+ #
477
+ # @return [Array<Hash>] Array with tag set.
478
+ def convert_read_tags(name, value)
479
+ converted = convert_read_set(name, value)
480
+ if converted
481
+ [converted]
482
+ else
483
+ nil
484
+ end
485
+ end
486
+
487
+ def revert_read_tags(value)
488
+ value
489
+ end
490
+
491
+ # Read preference tag set extractor.
492
+ #
493
+ # @param [ String ] name Name of the URI option being processed.
494
+ # @param value [String] The tag set string.
495
+ #
496
+ # @return [Hash] The tag set hash.
497
+ def convert_read_set(name, value)
498
+ hash_extractor('readPreferenceTags', value)
499
+ end
500
+
501
+ # Converts +value+ as a write concern.
502
+ #
503
+ # If +value+ is the word "majority", returns the symbol :majority.
504
+ # If +value+ is a number, returns the number as an integer.
505
+ # Otherwise returns the string +value+ unchanged.
506
+ #
507
+ # @param [ String ] name Name of the URI option being processed.
508
+ # @param value [ String ] URI option value.
509
+ #
510
+ # @return [ Integer | Symbol | String ] Converted value.
511
+ def convert_w(name, value)
512
+ case value
513
+ when 'majority'
514
+ :majority
515
+ when /\A[0-9]+\z/
516
+ value.to_i
517
+ else
518
+ value
519
+ end
520
+ end
521
+
522
+ def revert_w(value)
523
+ case value
524
+ when Symbol
525
+ value.to_s
526
+ else
527
+ value
528
+ end
529
+ end
530
+
531
+ # Parses the zlib compression level.
532
+ #
533
+ # @param [ String ] name Name of the URI option being processed.
534
+ # @param value [ String ] The zlib compression level string.
535
+ #
536
+ # @return [ Integer | nil ] The compression level value if it is between -1 and 9 (inclusive),
537
+ # otherwise nil (and a warning will be logged).
538
+ def convert_zlib_compression_level(name, value)
539
+ if /\A-?\d+\z/ =~ value
540
+ i = value.to_i
541
+
542
+ if i >= -1 && i <= 9
543
+ return i
544
+ end
545
+ end
546
+
547
+ log_warn("#{value} is not a valid zlibCompressionLevel")
548
+ nil
549
+ end
550
+
551
+ def revert_zlib_compression_level(value)
552
+ value
553
+ end
554
+
555
+ # Extract values from the string and put them into a nested hash.
556
+ #
557
+ # @param [ String ] name Name of the URI option being processed.
558
+ # @param value [ String ] The string to build a hash from.
559
+ #
560
+ # @return [ Hash ] The hash built from the string.
561
+ def hash_extractor(name, value)
562
+ h = {}
563
+ value.split(',').each do |tag|
564
+ k, v = tag.split(':')
565
+ if v.nil?
566
+ log_warn("Invalid hash value for #{name}: key `#{k}` does not have a value: #{value}")
567
+ next
568
+ end
569
+
570
+ h[k.to_sym] = v
571
+ end
572
+ if h.empty?
573
+ nil
574
+ else
575
+ h
576
+ end
577
+ end
578
+
579
+ end
580
+
581
+ end
582
+ end