mongo 2.0.6 → 2.1.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 (317) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -2
  3. data/lib/mongo/address/ipv4.rb +6 -1
  4. data/lib/mongo/address/unix.rb +2 -2
  5. data/lib/mongo/address.rb +18 -10
  6. data/lib/mongo/auth/cr/conversation.rb +1 -1
  7. data/lib/mongo/auth/ldap/conversation.rb +7 -3
  8. data/lib/mongo/auth/scram/conversation.rb +9 -3
  9. data/lib/mongo/auth/user/view.rb +23 -2
  10. data/lib/mongo/auth/x509/conversation.rb +1 -1
  11. data/lib/mongo/bulk_write/combineable.rb +51 -0
  12. data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
  13. data/lib/mongo/bulk_write/result.rb +191 -0
  14. data/lib/mongo/bulk_write/result_combiner.rb +117 -0
  15. data/lib/mongo/bulk_write/transformable.rb +132 -0
  16. data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
  17. data/lib/mongo/bulk_write/validatable.rb +62 -0
  18. data/lib/mongo/bulk_write.rb +159 -23
  19. data/lib/mongo/client.rb +52 -16
  20. data/lib/mongo/cluster/topology/replica_set.rb +27 -9
  21. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  22. data/lib/mongo/cluster/topology/unknown.rb +5 -2
  23. data/lib/mongo/cluster.rb +42 -7
  24. data/lib/mongo/collection/view/aggregation.rb +48 -9
  25. data/lib/mongo/collection/view/immutable.rb +6 -6
  26. data/lib/mongo/collection/view/iterable.rb +18 -4
  27. data/lib/mongo/collection/view/map_reduce.rb +58 -17
  28. data/lib/mongo/collection/view/readable.rb +173 -42
  29. data/lib/mongo/collection/view/writable.rb +37 -23
  30. data/lib/mongo/collection/view.rb +2 -2
  31. data/lib/mongo/collection.rb +370 -33
  32. data/lib/mongo/cursor.rb +15 -3
  33. data/lib/mongo/database/view.rb +5 -4
  34. data/lib/mongo/database.rb +14 -4
  35. data/lib/mongo/dbref.rb +113 -0
  36. data/lib/mongo/error/closed_stream.rb +34 -0
  37. data/lib/mongo/error/extra_file_chunk.rb +34 -0
  38. data/lib/mongo/error/{invalid_uri_option.rb → file_not_found.rb} +11 -12
  39. data/lib/mongo/error/invalid_file.rb +2 -2
  40. data/lib/mongo/error/invalid_file_revision.rb +37 -0
  41. data/lib/mongo/error/invalid_uri.rb +5 -4
  42. data/lib/mongo/error/missing_file_chunk.rb +38 -0
  43. data/lib/mongo/error/operation_failure.rb +1 -1
  44. data/lib/mongo/error/parser.rb +1 -1
  45. data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
  46. data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
  47. data/lib/mongo/error.rb +13 -2
  48. data/lib/mongo/event/description_changed.rb +1 -1
  49. data/lib/mongo/grid/file/chunk.rb +6 -6
  50. data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
  51. data/lib/mongo/grid/file.rb +13 -10
  52. data/lib/mongo/grid/fs_bucket.rb +448 -0
  53. data/lib/mongo/grid/stream/read.rb +208 -0
  54. data/lib/mongo/grid/stream/write.rb +187 -0
  55. data/lib/mongo/grid/stream.rb +64 -0
  56. data/lib/mongo/grid.rb +2 -1
  57. data/lib/mongo/index/view.rb +3 -3
  58. data/lib/mongo/index.rb +5 -0
  59. data/lib/mongo/loggable.rb +34 -57
  60. data/lib/mongo/logger.rb +16 -78
  61. data/lib/mongo/monitoring/command_log_subscriber.rb +112 -0
  62. data/lib/mongo/monitoring/event/command_failed.rb +96 -0
  63. data/lib/mongo/monitoring/event/command_started.rb +89 -0
  64. data/lib/mongo/monitoring/event/command_succeeded.rb +118 -0
  65. data/lib/mongo/monitoring/event/secure.rb +58 -0
  66. data/lib/mongo/monitoring/event.rb +18 -0
  67. data/lib/mongo/monitoring/publishable.rb +106 -0
  68. data/lib/mongo/monitoring.rb +195 -0
  69. data/lib/mongo/operation/{aggregate.rb → commands/aggregate.rb} +3 -41
  70. data/lib/mongo/operation/commands/collections_info/result.rb +39 -0
  71. data/lib/mongo/operation/commands/collections_info.rb +68 -0
  72. data/lib/mongo/operation/{command.rb → commands/command.rb} +2 -18
  73. data/lib/mongo/operation/commands/indexes.rb +70 -0
  74. data/lib/mongo/operation/commands/list_collections/result.rb +112 -0
  75. data/lib/mongo/operation/commands/list_collections.rb +54 -0
  76. data/lib/mongo/operation/commands/list_indexes/result.rb +116 -0
  77. data/lib/mongo/operation/commands/list_indexes.rb +56 -0
  78. data/lib/mongo/operation/{map_reduce → commands/map_reduce}/result.rb +1 -1
  79. data/lib/mongo/operation/{map_reduce.rb → commands/map_reduce.rb} +3 -41
  80. data/lib/mongo/operation/commands/parallel_scan/result.rb +72 -0
  81. data/lib/mongo/operation/commands/parallel_scan.rb +56 -0
  82. data/lib/mongo/operation/commands/user_query.rb +69 -0
  83. data/lib/mongo/{bulk_write/ordered_bulk_write.rb → operation/commands/users_info/result.rb} +18 -30
  84. data/lib/mongo/operation/commands/users_info.rb +53 -0
  85. data/lib/mongo/operation/commands.rb +24 -0
  86. data/lib/mongo/operation/executable.rb +4 -68
  87. data/lib/mongo/operation/kill_cursors.rb +3 -3
  88. data/lib/mongo/operation/read/get_more.rb +2 -22
  89. data/lib/mongo/{bulk_write/unordered_bulk_write.rb → operation/read/query/result.rb} +20 -26
  90. data/lib/mongo/operation/read/query.rb +4 -21
  91. data/lib/mongo/operation/read.rb +0 -4
  92. data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
  93. data/lib/mongo/operation/result.rb +13 -1
  94. data/lib/mongo/operation/specifiable.rb +42 -0
  95. data/lib/mongo/operation/write/bulk/bulkable.rb +82 -0
  96. data/lib/mongo/operation/write/bulk/delete/result.rb +74 -0
  97. data/lib/mongo/operation/write/bulk/delete.rb +71 -0
  98. data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
  99. data/lib/mongo/operation/write/bulk/insert.rb +96 -0
  100. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
  101. data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
  102. data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
  103. data/lib/mongo/operation/write/bulk/update.rb +81 -0
  104. data/lib/mongo/operation/write/bulk.rb +6 -3
  105. data/lib/mongo/operation/write/command/create_index.rb +0 -1
  106. data/lib/mongo/operation/write/command/create_user.rb +0 -1
  107. data/lib/mongo/operation/write/command/delete.rb +0 -1
  108. data/lib/mongo/operation/write/command/drop_index.rb +0 -1
  109. data/lib/mongo/operation/write/command/insert.rb +0 -1
  110. data/lib/mongo/operation/write/command/remove_user.rb +0 -1
  111. data/lib/mongo/operation/write/command/update.rb +0 -1
  112. data/lib/mongo/operation/write/command/update_user.rb +0 -1
  113. data/lib/mongo/operation/write/command/writable.rb +13 -18
  114. data/lib/mongo/operation/write/create_index.rb +4 -27
  115. data/lib/mongo/operation/write/create_user.rb +4 -30
  116. data/lib/mongo/operation/write/delete.rb +6 -29
  117. data/lib/mongo/operation/write/drop_index.rb +3 -3
  118. data/lib/mongo/operation/write/gle.rb +48 -0
  119. data/lib/mongo/operation/write/idable.rb +5 -0
  120. data/lib/mongo/operation/write/insert.rb +2 -24
  121. data/lib/mongo/operation/write/remove_user.rb +4 -27
  122. data/lib/mongo/operation/write/update.rb +13 -36
  123. data/lib/mongo/operation/write/update_user.rb +4 -30
  124. data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
  125. data/lib/mongo/operation/write.rb +2 -0
  126. data/lib/mongo/operation.rb +32 -4
  127. data/lib/mongo/options/mapper.rb +4 -2
  128. data/lib/mongo/options/redacted.rb +156 -0
  129. data/lib/mongo/options.rb +1 -0
  130. data/lib/mongo/protocol/delete.rb +75 -15
  131. data/lib/mongo/protocol/get_more.rb +65 -13
  132. data/lib/mongo/protocol/insert.rb +85 -13
  133. data/lib/mongo/protocol/kill_cursors.rb +59 -14
  134. data/lib/mongo/protocol/message.rb +12 -12
  135. data/lib/mongo/protocol/query.rb +163 -37
  136. data/lib/mongo/protocol/reply.rb +103 -0
  137. data/lib/mongo/protocol/serializers.rb +1 -1
  138. data/lib/mongo/protocol/update.rb +82 -14
  139. data/lib/mongo/retryable.rb +83 -0
  140. data/lib/mongo/server/connectable.rb +21 -25
  141. data/lib/mongo/server/connection.rb +75 -4
  142. data/lib/mongo/server/connection_pool/queue.rb +15 -0
  143. data/lib/mongo/server/connection_pool.rb +12 -0
  144. data/lib/mongo/server/description/features.rb +2 -1
  145. data/lib/mongo/server/description.rb +52 -1
  146. data/lib/mongo/server/monitor/connection.rb +26 -2
  147. data/lib/mongo/server/monitor.rb +19 -3
  148. data/lib/mongo/server.rb +39 -5
  149. data/lib/mongo/server_selector/selectable.rb +40 -31
  150. data/lib/mongo/server_selector.rb +19 -10
  151. data/lib/mongo/socket/ssl.rb +28 -16
  152. data/lib/mongo/socket/tcp.rb +3 -3
  153. data/lib/mongo/socket/unix.rb +5 -8
  154. data/lib/mongo/socket.rb +11 -4
  155. data/lib/mongo/uri.rb +248 -137
  156. data/lib/mongo/version.rb +1 -1
  157. data/lib/mongo.rb +5 -3
  158. data/spec/mongo/address/unix_spec.rb +1 -1
  159. data/spec/mongo/address_spec.rb +25 -0
  160. data/spec/mongo/auth/cr_spec.rb +9 -1
  161. data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
  162. data/spec/mongo/auth/ldap_spec.rb +9 -1
  163. data/spec/mongo/auth/scram_spec.rb +9 -1
  164. data/spec/mongo/auth/user/view_spec.rb +26 -1
  165. data/spec/mongo/auth/x509_spec.rb +9 -1
  166. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +271 -0
  167. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
  168. data/spec/mongo/bulk_write_spec.rb +428 -0
  169. data/spec/mongo/client_spec.rb +167 -17
  170. data/spec/mongo/cluster/topology/replica_set_spec.rb +18 -9
  171. data/spec/mongo/cluster/topology/sharded_spec.rb +11 -3
  172. data/spec/mongo/cluster/topology/single_spec.rb +12 -4
  173. data/spec/mongo/cluster_spec.rb +55 -10
  174. data/spec/mongo/collection/view/aggregation_spec.rb +188 -1
  175. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  176. data/spec/mongo/collection/view/immutable_spec.rb +103 -0
  177. data/spec/mongo/collection/view/map_reduce_spec.rb +99 -4
  178. data/spec/mongo/collection/view/readable_spec.rb +238 -6
  179. data/spec/mongo/collection/view/writable_spec.rb +4 -4
  180. data/spec/mongo/collection/view_spec.rb +459 -71
  181. data/spec/mongo/collection_spec.rb +1291 -9
  182. data/spec/mongo/command_monitoring_spec.rb +51 -0
  183. data/spec/mongo/connection_string_spec.rb +115 -0
  184. data/spec/mongo/crud_spec.rb +2 -2
  185. data/spec/mongo/cursor_spec.rb +3 -3
  186. data/spec/mongo/database_spec.rb +47 -11
  187. data/spec/mongo/dbref_spec.rb +149 -0
  188. data/spec/mongo/grid/file/chunk_spec.rb +5 -5
  189. data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
  190. data/spec/mongo/grid/file_spec.rb +8 -8
  191. data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
  192. data/spec/mongo/grid/stream/read_spec.rb +275 -0
  193. data/spec/mongo/grid/stream/write_spec.rb +440 -0
  194. data/spec/mongo/grid/stream_spec.rb +48 -0
  195. data/spec/mongo/gridfs_spec.rb +50 -0
  196. data/spec/mongo/logger_spec.rb +0 -40
  197. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
  198. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -0
  199. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +26 -0
  200. data/spec/mongo/monitoring/event/secure_spec.rb +57 -0
  201. data/spec/mongo/monitoring_spec.rb +168 -0
  202. data/spec/mongo/operation/commands/aggregate_spec.rb +69 -0
  203. data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
  204. data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +0 -18
  205. data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
  206. data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +1 -19
  207. data/spec/mongo/operation/kill_cursors_spec.rb +1 -17
  208. data/spec/mongo/operation/read/get_more_spec.rb +0 -16
  209. data/spec/mongo/operation/read/query_spec.rb +19 -16
  210. data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
  211. data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +18 -29
  212. data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +3 -14
  213. data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +8 -19
  214. data/spec/mongo/operation/write/command/delete_spec.rb +0 -16
  215. data/spec/mongo/operation/write/command/insert_spec.rb +0 -16
  216. data/spec/mongo/operation/write/command/update_spec.rb +0 -16
  217. data/spec/mongo/operation/write/delete_spec.rb +4 -4
  218. data/spec/mongo/operation/write/insert_spec.rb +2 -13
  219. data/spec/mongo/operation/write/update_spec.rb +7 -7
  220. data/spec/mongo/options/redacted_spec.rb +350 -0
  221. data/spec/mongo/protocol/kill_cursors_spec.rb +5 -3
  222. data/spec/mongo/protocol/query_spec.rb +15 -30
  223. data/spec/mongo/retryable_spec.rb +147 -0
  224. data/spec/mongo/server/connection_pool/queue_spec.rb +16 -0
  225. data/spec/mongo/server/connection_pool_spec.rb +50 -6
  226. data/spec/mongo/server/connection_spec.rb +49 -4
  227. data/spec/mongo/server/description_spec.rb +49 -3
  228. data/spec/mongo/server/monitor_spec.rb +51 -0
  229. data/spec/mongo/server_discovery_and_monitoring_spec.rb +32 -59
  230. data/spec/mongo/server_selection_rtt_spec.rb +37 -57
  231. data/spec/mongo/server_selection_spec.rb +19 -9
  232. data/spec/mongo/server_selector/nearest_spec.rb +35 -27
  233. data/spec/mongo/server_selector/primary_preferred_spec.rb +32 -30
  234. data/spec/mongo/server_selector/primary_spec.rb +21 -14
  235. data/spec/mongo/server_selector/secondary_preferred_spec.rb +28 -26
  236. data/spec/mongo/server_selector/secondary_spec.rb +24 -22
  237. data/spec/mongo/server_selector_spec.rb +87 -24
  238. data/spec/mongo/server_spec.rb +94 -8
  239. data/spec/mongo/socket/ssl_spec.rb +123 -13
  240. data/spec/mongo/socket/unix_spec.rb +52 -0
  241. data/spec/mongo/uri_spec.rb +295 -67
  242. data/spec/spec_helper.rb +40 -24
  243. data/spec/support/authorization.rb +23 -9
  244. data/spec/support/certificates/client.pem +4 -4
  245. data/spec/support/command_monitoring/bulkWrite.yml +73 -0
  246. data/spec/support/command_monitoring/command.yml +42 -0
  247. data/spec/support/command_monitoring/deleteMany.yml +55 -0
  248. data/spec/support/command_monitoring/deleteOne.yml +55 -0
  249. data/spec/support/command_monitoring/find.yml +219 -0
  250. data/spec/support/command_monitoring/insertMany.yml +81 -0
  251. data/spec/support/command_monitoring/insertOne.yml +51 -0
  252. data/spec/support/command_monitoring/updateMany.yml +67 -0
  253. data/spec/support/command_monitoring/updateOne.yml +95 -0
  254. data/spec/support/command_monitoring.rb +365 -0
  255. data/spec/support/connection_string.rb +228 -0
  256. data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
  257. data/spec/support/connection_string_tests/valid-auth.yml +256 -0
  258. data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
  259. data/spec/support/connection_string_tests/valid-options.yml +30 -0
  260. data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
  261. data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
  262. data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
  263. data/spec/support/crud/read.rb +22 -19
  264. data/spec/support/crud/write.rb +58 -27
  265. data/spec/support/crud.rb +10 -2
  266. data/spec/support/gridfs.rb +637 -0
  267. data/spec/support/gridfs_tests/delete.yml +157 -0
  268. data/spec/support/gridfs_tests/download.yml +210 -0
  269. data/spec/support/gridfs_tests/download_by_name.yml +113 -0
  270. data/spec/support/gridfs_tests/upload.yml +158 -0
  271. data/spec/support/matchers.rb +1 -1
  272. data/spec/support/sdam/rs/equal_electionids.yml +44 -0
  273. data/spec/support/sdam/rs/new_primary_new_electionid.yml +95 -0
  274. data/spec/support/sdam/rs/null_election_id.yml +144 -0
  275. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +124 -0
  276. data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
  277. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
  278. data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
  279. data/spec/support/sdam/sharded/mongos_disconnect.yml +104 -0
  280. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  281. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  282. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  283. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  284. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  285. data/spec/support/sdam/single/not_ok_response.yml +0 -1
  286. data/spec/support/server_discovery_and_monitoring.rb +22 -3
  287. data/spec/support/server_selection.rb +3 -1
  288. data/spec/support/shared/bulk_write.rb +218 -22
  289. data/spec/support/shared/server_selector.rb +80 -14
  290. data.tar.gz.sig +0 -0
  291. metadata +188 -59
  292. metadata.gz.sig +0 -0
  293. data/lib/mongo/bulk_write/bulk_writable.rb +0 -196
  294. data/lib/mongo/bulk_write/deletable.rb +0 -56
  295. data/lib/mongo/bulk_write/insertable.rb +0 -48
  296. data/lib/mongo/bulk_write/replacable.rb +0 -57
  297. data/lib/mongo/bulk_write/updatable.rb +0 -68
  298. data/lib/mongo/grid/fs.rb +0 -149
  299. data/lib/mongo/operation/list_collections/result.rb +0 -114
  300. data/lib/mongo/operation/list_indexes/result.rb +0 -118
  301. data/lib/mongo/operation/read/collections_info.rb +0 -68
  302. data/lib/mongo/operation/read/indexes.rb +0 -69
  303. data/lib/mongo/operation/read/list_collections.rb +0 -76
  304. data/lib/mongo/operation/read/list_indexes.rb +0 -78
  305. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
  306. data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
  307. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
  308. data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
  309. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
  310. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -162
  311. data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
  312. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
  313. data/spec/mongo/bulk/bulk_write_spec.rb +0 -262
  314. data/spec/mongo/grid/fs_spec.rb +0 -160
  315. data/spec/mongo/loggable_spec.rb +0 -63
  316. data/spec/mongo/operation/aggregate_spec.rb +0 -127
  317. /data/lib/mongo/operation/{aggregate → commands/aggregate}/result.rb +0 -0
@@ -0,0 +1,96 @@
1
+ # Copyright (C) 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 Monitoring
17
+ module Event
18
+
19
+ # Event that is fired when a command operation fails.
20
+ #
21
+ # @since 2.1.0
22
+ class CommandFailed
23
+
24
+ # @return [ Server::Address ] address The server address.
25
+ attr_reader :address
26
+
27
+ # @return [ String ] command_name The name of the command.
28
+ attr_reader :command_name
29
+
30
+ # @return [ String ] database_name The name of the database_name.
31
+ attr_reader :database_name
32
+
33
+ # @return [ Float ] duration The duration of the command in seconds.
34
+ attr_reader :duration
35
+
36
+ # @return [ String ] message The error message.
37
+ attr_reader :message
38
+
39
+ # @return [ Integer ] operation_id The operation id.
40
+ attr_reader :operation_id
41
+
42
+ # @return [ Integer ] request_id The request id.
43
+ attr_reader :request_id
44
+
45
+ # Create the new event.
46
+ #
47
+ # @example Create the event.
48
+ #
49
+ # @param [ String ] command_name The name of the command.
50
+ # @param [ String ] database_name The database_name name.
51
+ # @param [ Server::Address ] address The server address.
52
+ # @param [ Integer ] request_id The request id.
53
+ # @param [ Integer ] operation_id The operation id.
54
+ # @param [ String ] message The error message.
55
+ # @param [ Float ] duration The duration the command took in seconds.
56
+ #
57
+ # @since 2.1.0
58
+ def initialize(command_name, database_name, address, request_id, operation_id, message, duration)
59
+ @command_name = command_name
60
+ @database_name = database_name
61
+ @address = address
62
+ @request_id = request_id
63
+ @operation_id = operation_id
64
+ @message = message
65
+ @duration = duration
66
+ end
67
+
68
+ # Create the event from a wire protocol message payload.
69
+ #
70
+ # @example Create the event.
71
+ # CommandFailed.generate(address, 1, payload, duration)
72
+ #
73
+ # @param [ Server::Address ] address The server address.
74
+ # @param [ Integer ] operation_id The operation id.
75
+ # @param [ Hash ] payload The message payload.
76
+ # @param [ String ] message The error message.
77
+ # @param [ Float ] duration The duration of the command in seconds.
78
+ #
79
+ # @return [ CommandFailed ] The event.
80
+ #
81
+ # @since 2.1.0
82
+ def self.generate(address, operation_id, payload, message, duration)
83
+ new(
84
+ payload[:command_name],
85
+ payload[:database_name],
86
+ address,
87
+ payload[:request_id],
88
+ operation_id,
89
+ message,
90
+ duration
91
+ )
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,89 @@
1
+ # Copyright (C) 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 Monitoring
17
+ module Event
18
+
19
+ # Event that is fired when a command operation starts.
20
+ #
21
+ # @since 2.1.0
22
+ class CommandStarted
23
+ include Secure
24
+
25
+ # @return [ Server::Address ] address The server address.
26
+ attr_reader :address
27
+
28
+ # @return [ BSON::Document ] command The command arguments.
29
+ attr_reader :command
30
+
31
+ # @return [ String ] command_name The name of the command.
32
+ attr_reader :command_name
33
+
34
+ # @return [ String ] database_name The name of the database_name.
35
+ attr_reader :database_name
36
+
37
+ # @return [ Integer ] operation_id The operation id.
38
+ attr_reader :operation_id
39
+
40
+ # @return [ Integer ] request_id The request id.
41
+ attr_reader :request_id
42
+
43
+ # Create the new event.
44
+ #
45
+ # @example Create the event.
46
+ #
47
+ # @param [ String ] command_name The name of the command.
48
+ # @param [ String ] database_name The database_name name.
49
+ # @param [ Server::Address ] address The server address.
50
+ # @param [ Integer ] request_id The request id.
51
+ # @param [ Integer ] operation_id The operation id.
52
+ # @param [ BSON::Document ] command The command arguments.
53
+ #
54
+ # @since 2.1.0
55
+ def initialize(command_name, database_name, address, request_id, operation_id, command)
56
+ @command_name = command_name
57
+ @database_name = database_name
58
+ @address = address
59
+ @request_id = request_id
60
+ @operation_id = operation_id
61
+ @command = redacted(command_name, command)
62
+ end
63
+
64
+ # Create the event from a wire protocol message payload.
65
+ #
66
+ # @example Create the event.
67
+ # CommandStarted.generate(address, 1, payload)
68
+ #
69
+ # @param [ Server::Address ] address The server address.
70
+ # @param [ Integer ] operation_id The operation id.
71
+ # @param [ Hash ] payload The message payload.
72
+ #
73
+ # @return [ CommandStarted ] The event.
74
+ #
75
+ # @since 2.1.0
76
+ def self.generate(address, operation_id, payload)
77
+ new(
78
+ payload[:command_name],
79
+ payload[:database_name],
80
+ address,
81
+ payload[:request_id],
82
+ operation_id,
83
+ payload[:command]
84
+ )
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,118 @@
1
+ # Copyright (C) 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 Monitoring
17
+ module Event
18
+
19
+ # Event that is fired when a command operation succeeds.
20
+ #
21
+ # @since 2.1.0
22
+ class CommandSucceeded
23
+ include Secure
24
+
25
+ # @return [ Server::Address ] address The server address.
26
+ attr_reader :address
27
+
28
+ # @return [ String ] command_name The name of the command.
29
+ attr_reader :command_name
30
+
31
+ # @return [ BSON::Document ] reply The command reply.
32
+ attr_reader :reply
33
+
34
+ # @return [ String ] database_name The name of the database.
35
+ attr_reader :database_name
36
+
37
+ # @return [ Float ] duration The duration of the event.
38
+ attr_reader :duration
39
+
40
+ # @return [ Integer ] operation_id The operation id.
41
+ attr_reader :operation_id
42
+
43
+ # @return [ Integer ] request_id The request id.
44
+ attr_reader :request_id
45
+
46
+ # Create the new event.
47
+ #
48
+ # @example Create the event.
49
+ #
50
+ # @param [ String ] command_name The name of the command.
51
+ # @param [ String ] database_name The database name.
52
+ # @param [ Server::Address ] address The server address.
53
+ # @param [ Integer ] request_id The request id.
54
+ # @param [ Integer ] operation_id The operation id.
55
+ # @param [ BSON::Document ] reply The command reply.
56
+ # @param [ Float ] duration The duration the command took in seconds.
57
+ #
58
+ # @since 2.1.0
59
+ def initialize(command_name, database_name, address, request_id, operation_id, reply, duration)
60
+ @command_name = command_name
61
+ @database_name = database_name
62
+ @address = address
63
+ @request_id = request_id
64
+ @operation_id = operation_id
65
+ @reply = redacted(command_name, reply)
66
+ @duration = duration
67
+ end
68
+
69
+ # Create the event from a wire protocol message payload.
70
+ #
71
+ # @example Create the event.
72
+ # CommandSucceeded.generate(address, 1, command_payload, reply_payload, 0.5)
73
+ #
74
+ # @param [ Server::Address ] address The server address.
75
+ # @param [ Integer ] operation_id The operation id.
76
+ # @param [ Hash ] command_payload The command message payload.
77
+ # @param [ Hash ] reply_payload The reply message payload.
78
+ # @param [ Float ] duration The duration of the command in seconds.
79
+ #
80
+ # @return [ CommandCompleted ] The event.
81
+ #
82
+ # @since 2.1.0
83
+ def self.generate(address, operation_id, command_payload, reply_payload, duration)
84
+ new(
85
+ command_payload[:command_name],
86
+ command_payload[:database_name],
87
+ address,
88
+ command_payload[:request_id],
89
+ operation_id,
90
+ generate_reply(command_payload, reply_payload),
91
+ duration
92
+ )
93
+ end
94
+
95
+ private
96
+
97
+ def self.generate_reply(command_payload, reply_payload)
98
+ if reply_payload
99
+ reply = reply_payload[:reply]
100
+ if cursor = reply[:cursor]
101
+ if !cursor.key?(Collection::NS)
102
+ cursor.merge!(Collection::NS => namespace(command_payload))
103
+ end
104
+ end
105
+ reply
106
+ else
107
+ BSON::Document.new(Operation::Result::OK => 1)
108
+ end
109
+ end
110
+
111
+ def self.namespace(payload)
112
+ command = payload[:command]
113
+ "#{payload[:database_name]}.#{command[:collection] || command.values.first}"
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright (C) 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 Monitoring
17
+ module Event
18
+
19
+ # Provides behaviour to redact sensitive information from commands and
20
+ # replies.
21
+ #
22
+ # @since 2.1.0
23
+ module Secure
24
+
25
+ # The list of commands that has the data redacted for security.
26
+ #
27
+ # @since 2.1.0
28
+ REDACTED_COMMANDS = [
29
+ 'authenticate',
30
+ 'saslStart',
31
+ 'saslContinue',
32
+ 'getnonce',
33
+ 'createUser',
34
+ 'updateUser',
35
+ 'copydbgetnonce',
36
+ 'copydbsaslstart',
37
+ 'copydb'
38
+ ].freeze
39
+
40
+ # Redact secure information from the document if it's command is in the
41
+ # list.
42
+ #
43
+ # @example Get the redacted document.
44
+ # secure.redacted(command_name, document)
45
+ #
46
+ # @param [ String, Symbol ] command_name The command name.
47
+ # @param [ BSON::Document ] document The document.
48
+ #
49
+ # @return [ BSON::Document ] The redacted document.
50
+ #
51
+ # @since 2.1.0
52
+ def redacted(command_name, document)
53
+ REDACTED_COMMANDS.include?(command_name.to_s) ? BSON::Document.new : document
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,18 @@
1
+ # Copyright (C) 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/monitoring/event/secure'
16
+ require 'mongo/monitoring/event/command_started'
17
+ require 'mongo/monitoring/event/command_succeeded'
18
+ require 'mongo/monitoring/event/command_failed'
@@ -0,0 +1,106 @@
1
+ # Copyright (C) 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 Monitoring
17
+
18
+ # Defines behaviour for an object that can publish monitoring events.
19
+ #
20
+ # @since 2.1.0
21
+ module Publishable
22
+
23
+ # @return [ Monitoring ] monitoring The monitoring.
24
+ attr_reader :monitoring
25
+
26
+ # Publish a command event to the global monitoring.
27
+ #
28
+ # @example Publish a command event.
29
+ # publish_command do |messages|
30
+ # # ...
31
+ # end
32
+ #
33
+ # @param [ Array<Message> ] messages The messages.
34
+ #
35
+ # @return [ Object ] The result of the yield.
36
+ #
37
+ # @since 2.1.0
38
+ def publish_command(messages, operation_id = Monitoring.next_operation_id)
39
+ start = Time.now
40
+ message = messages.first
41
+ message.set_request_id
42
+ payload = message.payload
43
+ send_duration = duration(start)
44
+ command_started(address, operation_id, payload)
45
+ receive_start = Time.now
46
+ begin
47
+ result = yield(messages)
48
+ total_duration = duration(receive_start) + send_duration
49
+ command_completed(result, address, operation_id, payload, total_duration)
50
+ result
51
+ rescue Exception => e
52
+ total_duration = duration(receive_start) + send_duration
53
+ command_failed(address, operation_id, payload, e.message, total_duration)
54
+ raise e
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def command_started(address, operation_id, payload)
61
+ monitoring.started(
62
+ Monitoring::COMMAND,
63
+ Event::CommandStarted.generate(address, operation_id, payload)
64
+ )
65
+ end
66
+
67
+ def command_completed(result, address, operation_id, payload, duration)
68
+ document = result ? (result.documents || []).first : nil
69
+ if error?(document)
70
+ parser = Error::Parser.new(document)
71
+ command_failed(address, operation_id, payload, parser.message, duration)
72
+ else
73
+ command_succeeded(result, address, operation_id, payload, duration)
74
+ end
75
+ end
76
+
77
+ def command_succeeded(result, address, operation_id, payload, duration)
78
+ monitoring.succeeded(
79
+ Monitoring::COMMAND,
80
+ Event::CommandSucceeded.generate(
81
+ address,
82
+ operation_id,
83
+ payload,
84
+ result ? result.payload : nil,
85
+ duration
86
+ )
87
+ )
88
+ end
89
+
90
+ def command_failed(address, operation_id, payload, message, duration)
91
+ monitoring.failed(
92
+ Monitoring::COMMAND,
93
+ Event::CommandFailed.generate(address, operation_id, payload, message, duration)
94
+ )
95
+ end
96
+
97
+ def duration(start)
98
+ Time.now - start
99
+ end
100
+
101
+ def error?(document)
102
+ document && (document['ok'] == 0 || document.key?('$err'))
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,195 @@
1
+ # Copyright (C) 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/monitoring/event'
16
+ require 'mongo/monitoring/publishable'
17
+ require 'mongo/monitoring/command_log_subscriber'
18
+
19
+ module Mongo
20
+
21
+ # The class defines behaviour for the performance monitoring API.
22
+ #
23
+ # @since 2.1.0
24
+ class Monitoring
25
+
26
+ # The command topic.
27
+ #
28
+ # @since 2.1.0
29
+ COMMAND = 'Command'.freeze
30
+
31
+ @@operation_id = 0
32
+ @@operation_id_lock = Mutex.new
33
+
34
+ # Used for generating unique operation ids to link events together.
35
+ #
36
+ # @example Get the next operation id.
37
+ # Monitoring.next_operation_id
38
+ #
39
+ # @return [ Integer ] The next operation id.
40
+ #
41
+ # @since 2.1.0
42
+ def self.next_operation_id
43
+ @@operation_id_lock.synchronize do
44
+ @@operation_id += 1
45
+ end
46
+ end
47
+
48
+ # Provides behaviour around global subscribers.
49
+ #
50
+ # @since 2.1.0
51
+ module Global
52
+ extend self
53
+
54
+ # Subscribe a listener to an event topic.
55
+ #
56
+ # @example Subscribe to the topic.
57
+ # Monitoring::Global.subscribe(QUERY, subscriber)
58
+ #
59
+ # @param [ String ] topic The event topic.
60
+ # @param [ Object ] subscriber The subscriber to handle the event.
61
+ #
62
+ # @since 2.1.0
63
+ def subscribe(topic, subscriber)
64
+ subscribers_for(topic).push(subscriber)
65
+ end
66
+
67
+ # Get all the global subscribers.
68
+ #
69
+ # @example Get all the global subscribers.
70
+ # Monitoring::Global.subscribers
71
+ #
72
+ # @return [ Hash<String, Object> ] The subscribers.
73
+ #
74
+ # @since 2.1.0
75
+ def subscribers
76
+ @subscribers ||= {}
77
+ end
78
+
79
+ private
80
+
81
+ def subscribers_for(topic)
82
+ subscribers[topic] ||= []
83
+ end
84
+ end
85
+
86
+ # Initialize the monitoring.
87
+ #
88
+ # @api private
89
+ #
90
+ # @example Create the new monitoring.
91
+ # Monitoring.new(:monitoring => true)
92
+ #
93
+ # @param [ Hash ] options The options.
94
+ #
95
+ # @since 2.1.0
96
+ def initialize(options = {})
97
+ if options[:monitoring] != false
98
+ Global.subscribers.each do |topic, subscribers|
99
+ subscribers.each do |subscriber|
100
+ subscribe(topic, subscriber)
101
+ end
102
+ end
103
+ subscribe(COMMAND, CommandLogSubscriber.new(options))
104
+ end
105
+ end
106
+
107
+ # Publish a started event.
108
+ #
109
+ # @example Publish a started event.
110
+ # monitoring.started(COMMAND, event)
111
+ #
112
+ # @param [ String ] topic The event topic.
113
+ # @param [ Event ] event The event to publish.
114
+ #
115
+ # @since 2.1.0
116
+ def started(topic, event)
117
+ subscribers_for(topic).each{ |subscriber| subscriber.started(event) }
118
+ end
119
+
120
+ # Publish a succeeded event.
121
+ #
122
+ # @example Publish a succeeded event.
123
+ # monitoring.succeeded(COMMAND, event)
124
+ #
125
+ # @param [ String ] topic The event topic.
126
+ # @param [ Event ] event The event to publish.
127
+ #
128
+ # @since 2.1.0
129
+ def succeeded(topic, event)
130
+ subscribers_for(topic).each{ |subscriber| subscriber.succeeded(event) }
131
+ end
132
+
133
+ # Publish a failed event.
134
+ #
135
+ # @example Publish a failed event.
136
+ # monitoring.failed(COMMAND, event)
137
+ #
138
+ # @param [ String ] topic The event topic.
139
+ # @param [ Event ] event The event to publish.
140
+ #
141
+ # @since 2.1.0
142
+ def failed(topic, event)
143
+ subscribers_for(topic).each{ |subscriber| subscriber.failed(event) }
144
+ end
145
+
146
+ # Subscribe a listener to an event topic.
147
+ #
148
+ # @example Subscribe to the topic.
149
+ # monitoring.subscribe(QUERY, subscriber)
150
+ #
151
+ # @param [ String ] topic The event topic.
152
+ # @param [ Object ] subscriber The subscriber to handle the event.
153
+ #
154
+ # @since 2.1.0
155
+ def subscribe(topic, subscriber)
156
+ subscribers_for(topic).push(subscriber)
157
+ end
158
+
159
+ # Get all the subscribers.
160
+ #
161
+ # @example Get all the subscribers.
162
+ # monitoring.subscribers
163
+ #
164
+ # @return [ Hash<String, Object> ] The subscribers.
165
+ #
166
+ # @since 2.1.0
167
+ def subscribers
168
+ @subscribers ||= {}
169
+ end
170
+
171
+ # Determine if there are any subscribers for a particular event.
172
+ #
173
+ # @example Are there subscribers?
174
+ # monitoring.subscribers?(COMMAND)
175
+ #
176
+ # @param [ String ] topic The event topic.
177
+ #
178
+ # @return [ true, false ] If there are subscribers for the topic.
179
+ #
180
+ # @since 2.1.0
181
+ def subscribers?(topic)
182
+ !subscribers_for(topic).empty?
183
+ end
184
+
185
+ private
186
+
187
+ def initialize_copy(original)
188
+ @subscribers = original.subscribers.dup
189
+ end
190
+
191
+ def subscribers_for(topic)
192
+ subscribers[topic] ||= []
193
+ end
194
+ end
195
+ end