mongo 2.7.2 → 2.8.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 (94) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -3
  4. data/lib/mongo/address.rb +17 -20
  5. data/lib/mongo/address/ipv4.rb +6 -3
  6. data/lib/mongo/address/ipv6.rb +6 -3
  7. data/lib/mongo/address/unix.rb +5 -2
  8. data/lib/mongo/auth.rb +15 -2
  9. data/lib/mongo/auth/cr/conversation.rb +4 -2
  10. data/lib/mongo/auth/ldap/conversation.rb +4 -2
  11. data/lib/mongo/auth/scram.rb +3 -7
  12. data/lib/mongo/auth/scram/conversation.rb +28 -19
  13. data/lib/mongo/auth/user.rb +45 -10
  14. data/lib/mongo/auth/x509/conversation.rb +4 -2
  15. data/lib/mongo/cluster.rb +9 -17
  16. data/lib/mongo/error.rb +2 -0
  17. data/lib/mongo/error/missing_password.rb +29 -0
  18. data/lib/mongo/error/operation_failure.rb +7 -3
  19. data/lib/mongo/error/parser.rb +2 -1
  20. data/lib/mongo/error/sdam_error_detection.rb +54 -0
  21. data/lib/mongo/operation/aggregate/command.rb +1 -16
  22. data/lib/mongo/operation/aggregate/op_msg.rb +1 -1
  23. data/lib/mongo/operation/collections_info.rb +2 -3
  24. data/lib/mongo/operation/delete/command.rb +2 -15
  25. data/lib/mongo/operation/delete/legacy.rb +1 -16
  26. data/lib/mongo/operation/explain/command.rb +1 -16
  27. data/lib/mongo/operation/explain/legacy.rb +1 -16
  28. data/lib/mongo/operation/find/command.rb +1 -16
  29. data/lib/mongo/operation/find/legacy.rb +1 -16
  30. data/lib/mongo/operation/get_more/command.rb +1 -16
  31. data/lib/mongo/operation/indexes/command.rb +1 -16
  32. data/lib/mongo/operation/indexes/legacy.rb +4 -16
  33. data/lib/mongo/operation/list_collections/command.rb +1 -16
  34. data/lib/mongo/operation/map_reduce/command.rb +1 -16
  35. data/lib/mongo/operation/parallel_scan/command.rb +1 -16
  36. data/lib/mongo/operation/result.rb +3 -0
  37. data/lib/mongo/operation/shared/executable.rb +4 -0
  38. data/lib/mongo/operation/shared/polymorphic_lookup.rb +1 -1
  39. data/lib/mongo/operation/shared/polymorphic_result.rb +8 -1
  40. data/lib/mongo/operation/shared/result/aggregatable.rb +0 -5
  41. data/lib/mongo/operation/update/command.rb +2 -15
  42. data/lib/mongo/operation/update/legacy.rb +1 -16
  43. data/lib/mongo/operation/users_info/command.rb +1 -16
  44. data/lib/mongo/retryable.rb +22 -10
  45. data/lib/mongo/server.rb +10 -1
  46. data/lib/mongo/server/app_metadata.rb +7 -2
  47. data/lib/mongo/server/connectable.rb +0 -6
  48. data/lib/mongo/server/connection.rb +86 -135
  49. data/lib/mongo/server/connection_base.rb +133 -0
  50. data/lib/mongo/server/connection_pool.rb +11 -24
  51. data/lib/mongo/server/connection_pool/queue.rb +41 -41
  52. data/lib/mongo/server/description.rb +1 -1
  53. data/lib/mongo/server/monitor.rb +4 -4
  54. data/lib/mongo/server/monitor/connection.rb +26 -7
  55. data/lib/mongo/server/pending_connection.rb +36 -0
  56. data/lib/mongo/server_selector/selectable.rb +9 -1
  57. data/lib/mongo/session.rb +0 -1
  58. data/lib/mongo/socket.rb +23 -6
  59. data/lib/mongo/socket/ssl.rb +11 -18
  60. data/lib/mongo/socket/tcp.rb +13 -14
  61. data/lib/mongo/socket/unix.rb +9 -27
  62. data/lib/mongo/uri.rb +1 -1
  63. data/lib/mongo/version.rb +1 -1
  64. data/spec/integration/auth_spec.rb +160 -0
  65. data/spec/integration/retryable_writes_spec.rb +55 -58
  66. data/spec/integration/sdam_error_handling_spec.rb +115 -0
  67. data/spec/mongo/address/ipv4_spec.rb +4 -0
  68. data/spec/mongo/address/ipv6_spec.rb +4 -0
  69. data/spec/mongo/auth/scram/conversation_spec.rb +6 -5
  70. data/spec/mongo/auth/scram/negotiation_spec.rb +25 -36
  71. data/spec/mongo/auth/scram_spec.rb +2 -2
  72. data/spec/mongo/auth/user_spec.rb +97 -0
  73. data/spec/mongo/client_construction_spec.rb +1 -1
  74. data/spec/mongo/error/operation_failure_spec.rb +125 -1
  75. data/spec/mongo/retryable_spec.rb +17 -8
  76. data/spec/mongo/server/connection_pool/queue_spec.rb +24 -10
  77. data/spec/mongo/server/connection_pool_spec.rb +30 -117
  78. data/spec/mongo/server/connection_spec.rb +147 -25
  79. data/spec/mongo/server/description_spec.rb +0 -14
  80. data/spec/mongo/server/monitor/connection_spec.rb +22 -0
  81. data/spec/mongo/server_selector_spec.rb +1 -0
  82. data/spec/mongo/server_spec.rb +6 -6
  83. data/spec/mongo/socket/ssl_spec.rb +48 -116
  84. data/spec/mongo/socket/tcp_spec.rb +22 -0
  85. data/spec/mongo/socket/unix_spec.rb +9 -9
  86. data/spec/mongo/socket_spec.rb +15 -3
  87. data/spec/spec_tests/server_selection_spec.rb +2 -0
  88. data/spec/support/client_registry.rb +8 -2
  89. data/spec/support/common_shortcuts.rb +20 -1
  90. data/spec/support/constraints.rb +10 -2
  91. data/spec/support/lite_constraints.rb +8 -0
  92. data/spec/support/spec_config.rb +9 -1
  93. metadata +14 -4
  94. metadata.gz.sig +0 -0
@@ -51,7 +51,7 @@ module Mongo
51
51
  end
52
52
 
53
53
  # Start the x.509 conversation. This returns the first message that
54
- # needs to be send to the server.
54
+ # needs to be sent to the server.
55
55
  #
56
56
  # @example Start the conversation.
57
57
  # conversation.start
@@ -95,7 +95,9 @@ module Mongo
95
95
  private
96
96
 
97
97
  def validate!(reply)
98
- raise Unauthorized.new(user) if reply.documents[0][Operation::Result::OK] != 1
98
+ if reply.documents[0][Operation::Result::OK] != 1
99
+ raise Unauthorized.new(user, MECHANISM)
100
+ end
99
101
  @reply = reply
100
102
  end
101
103
  end
@@ -99,7 +99,6 @@ module Mongo
99
99
  @app_metadata = Server::AppMetadata.new(@options)
100
100
  @update_lock = Mutex.new
101
101
  @sdam_flow_lock = Mutex.new
102
- @pool_lock = Mutex.new
103
102
  @cluster_time = nil
104
103
  @cluster_time_lock = Mutex.new
105
104
  @topology = Topology.initial(self, monitoring, options)
@@ -153,7 +152,7 @@ module Mongo
153
152
  @periodic_executor = PeriodicExecutor.new(@cursor_reaper, @socket_reaper)
154
153
  @periodic_executor.run!
155
154
 
156
- ObjectSpace.define_finalizer(self, self.class.finalize(pools, @periodic_executor, @session_pool))
155
+ ObjectSpace.define_finalizer(self, self.class.finalize({}, @periodic_executor, @session_pool))
157
156
 
158
157
  @connecting = false
159
158
  @connected = true
@@ -341,15 +340,16 @@ module Mongo
341
340
  end
342
341
 
343
342
  # @api private
344
- attr_reader :server_selection_semaphore
343
+ def server_selection_semaphore
344
+ options[:server_selection_semaphore]
345
+ end
345
346
 
346
- # Finalize the cluster for garbage collection. Disconnects all the scoped
347
- # connection pools.
347
+ # Finalize the cluster for garbage collection.
348
348
  #
349
349
  # @example Finalize the cluster.
350
350
  # Cluster.finalize(pools)
351
351
  #
352
- # @param [ Hash<Address, Server::ConnectionPool> ] pools The connection pools.
352
+ # @param [ Hash<Address, Server::ConnectionPool> ] pools Ignored.
353
353
  # @param [ PeriodicExecutor ] periodic_executor The periodic executor.
354
354
  # @param [ SessionPool ] session_pool The session pool.
355
355
  #
@@ -360,9 +360,6 @@ module Mongo
360
360
  proc do
361
361
  session_pool.end_sessions
362
362
  periodic_executor.stop!
363
- pools.values.each do |pool|
364
- pool.disconnect!
365
- end
366
363
  end
367
364
  end
368
365
 
@@ -523,7 +520,7 @@ module Mongo
523
520
  @primary_selector.select_server(self)
524
521
  end
525
522
 
526
- # Get the scoped connection pool for the server.
523
+ # Get the connection pool for the server.
527
524
  #
528
525
  # @example Get the connection pool.
529
526
  # cluster.pool(server)
@@ -533,10 +530,9 @@ module Mongo
533
530
  # @return [ Server::ConnectionPool ] The connection pool.
534
531
  #
535
532
  # @since 2.2.0
533
+ # @deprecated
536
534
  def pool(server)
537
- @pool_lock.synchronize do
538
- pools[server.address] ||= Server::ConnectionPool.get(server)
539
- end
535
+ server.pool
540
536
  end
541
537
 
542
538
  # Update the max cluster time seen in a response.
@@ -675,10 +671,6 @@ module Mongo
675
671
  false
676
672
  end
677
673
  end
678
-
679
- def pools
680
- @pools ||= {}
681
- end
682
674
  end
683
675
  end
684
676
 
@@ -134,6 +134,7 @@ module Mongo
134
134
  end
135
135
  end
136
136
 
137
+ require 'mongo/error/sdam_error_detection'
137
138
  require 'mongo/error/parser'
138
139
  require 'mongo/error/write_retryable'
139
140
  require 'mongo/error/change_stream_resumable'
@@ -179,6 +180,7 @@ require 'mongo/error/unchangeable_collection_option'
179
180
  require 'mongo/error/unexpected_chunk_length'
180
181
  require 'mongo/error/unexpected_response'
181
182
  require 'mongo/error/missing_file_chunk'
183
+ require 'mongo/error/missing_password'
182
184
  require 'mongo/error/missing_resume_token'
183
185
  require 'mongo/error/unsupported_array_filters'
184
186
  require 'mongo/error/unknown_payload_type'
@@ -0,0 +1,29 @@
1
+ # Copyright (C) 2019 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 Error
17
+
18
+ # Raised when the operations that require a password (e.g. retrieving
19
+ # a salted or hashed password) are attempted on a User object that was
20
+ # not created with a password.
21
+ #
22
+ # @since 2.8.0
23
+ class MissingPassword < Error
24
+ def initialize(msg = nil)
25
+ super(msg || 'User was created without a password')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -20,6 +20,7 @@ module Mongo
20
20
  # @since 2.0.0
21
21
  class OperationFailure < Error
22
22
  extend Forwardable
23
+ include SdamErrorDetection
23
24
 
24
25
  # Error codes and code names that should result in a failing write
25
26
  # being retried.
@@ -28,7 +29,7 @@ module Mongo
28
29
  # @api private
29
30
  WRITE_RETRY_ERRORS = [
30
31
  {:code_name => 'InterruptedAtShutdown', :code => 11600},
31
- {:code_name => 'InterruptedDueToReplStateChange', :code => 11602},
32
+ {:code_name => 'InterruptedDueToStepDown', :code => 11602},
32
33
  {:code_name => 'NotMaster', :code => 10107},
33
34
  {:code_name => 'NotMasterNoSlaveOk', :code => 13435},
34
35
  {:code_name => 'NotMasterOrSecondary', :code => 13436},
@@ -175,6 +176,9 @@ module Mongo
175
176
  #
176
177
  # @option options [ Integer ] :code Error code
177
178
  # @option options [ String ] :code_name Error code name
179
+ # @option options [ Array<String> ] :labels The set of labels associated
180
+ # with the error
181
+ # @option options [ true | false ] :wtimeout Whether the error is a wtimeout
178
182
  #
179
183
  # @since 2.5.0, options added in 2.6.0
180
184
  def initialize(message = nil, result = nil, options = {})
@@ -186,9 +190,9 @@ module Mongo
186
190
  super(message)
187
191
  end
188
192
 
189
- # Whether the error was a write concern timeout.
193
+ # Whether the error is a write concern timeout.
190
194
  #
191
- # @return [ true | false ] Whether the error was a write concern timeout.
195
+ # @return [ true | false ] Whether the error is a write concern timeout.
192
196
  #
193
197
  # @since 2.7.1
194
198
  def wtimeout?
@@ -44,6 +44,7 @@ module Mongo
44
44
  #
45
45
  # @since 2.0.0
46
46
  class Parser
47
+ include SdamErrorDetection
47
48
 
48
49
  # @return [ BSON::Document ] document The returned document.
49
50
  attr_reader :document
@@ -62,7 +63,7 @@ module Mongo
62
63
  # @since 2.6.0
63
64
  attr_reader :code_name
64
65
 
65
- # @return [ Array ] labels The set of labels associated with the error.
66
+ # @return [ Array<String> ] labels The set of labels associated with the error.
66
67
  # @since 2.7.0
67
68
  attr_reader :labels
68
69
 
@@ -0,0 +1,54 @@
1
+ module Mongo
2
+ class Error
3
+ # @note Although not_master? and node_recovering? methods of this module
4
+ # are part of the public API, the fact that these methods are defined on
5
+ # this module and not on the classes which include this module is not
6
+ # part of the public API.
7
+ #
8
+ # @api semipublic
9
+ module SdamErrorDetection
10
+
11
+ # @api private
12
+ NOT_MASTER_CODES = [10107, 13435].freeze
13
+
14
+ # @api private
15
+ NODE_RECOVERING_CODES = [11600, 11602, 13436, 189, 91].freeze
16
+
17
+ # Whether the error is a "not master" error, or one of its variants.
18
+ #
19
+ # See https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-master-and-node-is-recovering.
20
+ #
21
+ # @return [ true | false ] Whether the error is a not master.
22
+ #
23
+ # @since 2.8.0
24
+ def not_master?
25
+ if node_recovering?
26
+ false
27
+ elsif code && NOT_MASTER_CODES.include?(code)
28
+ true
29
+ elsif message
30
+ message.include?('not master')
31
+ else
32
+ false
33
+ end
34
+ end
35
+
36
+ # Whether the error is a "node is recovering" error, or one of its variants.
37
+ #
38
+ # See https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#not-master-and-node-is-recovering.
39
+ #
40
+ # @return [ true | false ] Whether the error is a node is recovering.
41
+ #
42
+ # @since 2.8.0
43
+ def node_recovering?
44
+ if code && NODE_RECOVERING_CODES.include?(code)
45
+ true
46
+ elsif message
47
+ message.include?('node is recovering') || message.include?('not master or secondary')
48
+ else
49
+ false
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -24,26 +24,11 @@ module Mongo
24
24
  class Command
25
25
  include Specifiable
26
26
  include Executable
27
+ include PolymorphicResult
27
28
  include ReadPreferenceSupported
28
29
  include WriteConcernSupported
29
30
  include Limited
30
31
 
31
- # Execute the operation.
32
- #
33
- # @example
34
- # operation.execute(server)
35
- #
36
- # @param [ Mongo::Server ] server The server to send the operation to.
37
- #
38
- # @return [ Mongo::Operation::Aggregate::Result ] The operation result.
39
- #
40
- # @since 2.5.2
41
- def execute(server)
42
- result = Result.new(dispatch_message(server))
43
- process_result(result, server)
44
- result.validate!
45
- end
46
-
47
32
  private
48
33
 
49
34
  def write_concern_supported?(server)
@@ -23,8 +23,8 @@ module Mongo
23
23
  # @since 2.5.2
24
24
  class OpMsg < OpMsgBase
25
25
  include CausalConsistencySupported
26
- include PolymorphicResult
27
26
  include ExecutableTransactionLabel
27
+ include PolymorphicResult
28
28
  end
29
29
  end
30
30
  end
@@ -26,6 +26,7 @@ module Mongo
26
26
  include Specifiable
27
27
  include Executable
28
28
  include ReadPreferenceSupported
29
+ include PolymorphicResult
29
30
 
30
31
  # Execute the operation.
31
32
  #
@@ -43,9 +44,7 @@ module Mongo
43
44
  return Operation::ListCollections.new(spec).execute(server)
44
45
  end
45
46
 
46
- result = Result.new(dispatch_message(server))
47
- process_result(result, server)
48
- result.validate!
47
+ super
49
48
  end
50
49
 
51
50
  private
@@ -26,21 +26,8 @@ module Mongo
26
26
  include Executable
27
27
  include Limited
28
28
  include WriteConcernSupported
29
-
30
- # Execute the operation.
31
- #
32
- # @example
33
- # operation.execute(server)
34
- #
35
- # @param [ Mongo::Server ] server The server to send the operation to.
36
- #
37
- # @return [ Mongo::Operation::Delete::Result ] The operation result.
38
- #
39
- # @since 2.5.2
40
- def execute(server)
41
- result = Result.new(dispatch_message(server))
42
- process_result(result, server)
43
- end
29
+ include ExecutableNoValidate
30
+ include PolymorphicResult
44
31
 
45
32
  private
46
33
 
@@ -24,22 +24,7 @@ module Mongo
24
24
  class Legacy
25
25
  include Specifiable
26
26
  include Executable
27
-
28
- # Execute the operation.
29
- #
30
- # @example
31
- # operation.execute(server)
32
- #
33
- # @param [ Mongo::Server ] server The server to send the operation to.
34
- #
35
- # @return [ Mongo::Operation::Delete::Result ] The operation result.
36
- #
37
- # @since 2.5.2
38
- def execute(server)
39
- result = Result.new(dispatch_message(server))
40
- process_result(result, server)
41
- result.validate!
42
- end
27
+ include PolymorphicResult
43
28
 
44
29
  private
45
30
 
@@ -26,22 +26,7 @@ module Mongo
26
26
  include Executable
27
27
  include Limited
28
28
  include ReadPreferenceSupported
29
-
30
- # Execute the operation.
31
- #
32
- # @example
33
- # operation.execute(server)
34
- #
35
- # @param [ Mongo::Server ] server The server to send the operation to.
36
- #
37
- # @return [ Mongo::Operation::Explain::Result ] The operation result.
38
- #
39
- # @since 2.5.2
40
- def execute(server)
41
- result = Result.new(dispatch_message(server))
42
- process_result(result, server)
43
- result.validate!
44
- end
29
+ include PolymorphicResult
45
30
 
46
31
  private
47
32
 
@@ -25,22 +25,7 @@ module Mongo
25
25
  include Specifiable
26
26
  include Executable
27
27
  include ReadPreferenceSupported
28
-
29
- # Execute the operation.
30
- #
31
- # @example
32
- # operation.execute(server)
33
- #
34
- # @param [ Mongo::Server ] server The server to send the operation to.
35
- #
36
- # @return [ Mongo::Operation::Explain::Result ] The operation result.
37
- #
38
- # @since 2.5.2
39
- def execute(server)
40
- result = Result.new(dispatch_message(server))
41
- process_result(result, server)
42
- result.validate!
43
- end
28
+ include PolymorphicResult
44
29
 
45
30
  private
46
31
 
@@ -26,22 +26,7 @@ module Mongo
26
26
  include Executable
27
27
  include Limited
28
28
  include ReadPreferenceSupported
29
-
30
- # Execute the operation.
31
- #
32
- # @example
33
- # operation.execute(server)
34
- #
35
- # @param [ Mongo::Server ] server The server to send the operation to.
36
- #
37
- # @return [ Mongo::Operation::Find::Result ] The operation result.
38
- #
39
- # @since 2.5.2
40
- def execute(server)
41
- result = Result.new(dispatch_message(server))
42
- process_result(result, server)
43
- result.validate!
44
- end
29
+ include PolymorphicResult
45
30
 
46
31
  private
47
32
 
@@ -27,22 +27,7 @@ module Mongo
27
27
  include Specifiable
28
28
  include Executable
29
29
  include ReadPreferenceSupported
30
-
31
- # Execute the operation.
32
- #
33
- # @example
34
- # operation.execute(server)
35
- #
36
- # @param [ Mongo::Server ] server The server to send the operation to.
37
- #
38
- # @return [ Mongo::Operation::Find::Result ] The operation result.
39
- #
40
- # @since 2.5.2
41
- def execute(server)
42
- result = Result.new(dispatch_message(server))
43
- process_result(result, server)
44
- result.validate!
45
- end
30
+ include PolymorphicResult
46
31
 
47
32
  private
48
33