mongo 2.7.2 → 2.8.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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