mongo 2.11.1 → 2.11.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -1
  3. data.tar.gz.sig +2 -1
  4. data/Rakefile +24 -0
  5. data/lib/mongo/address.rb +53 -37
  6. data/lib/mongo/auth.rb +30 -10
  7. data/lib/mongo/auth/cr.rb +1 -0
  8. data/lib/mongo/auth/cr/conversation.rb +13 -13
  9. data/lib/mongo/auth/ldap.rb +2 -1
  10. data/lib/mongo/auth/ldap/conversation.rb +9 -12
  11. data/lib/mongo/auth/scram.rb +1 -0
  12. data/lib/mongo/auth/scram/conversation.rb +36 -27
  13. data/lib/mongo/auth/user.rb +7 -1
  14. data/lib/mongo/auth/x509.rb +2 -1
  15. data/lib/mongo/auth/x509/conversation.rb +9 -9
  16. data/lib/mongo/bulk_write/transformable.rb +3 -3
  17. data/lib/mongo/client.rb +17 -6
  18. data/lib/mongo/cluster.rb +67 -49
  19. data/lib/mongo/cluster/sdam_flow.rb +87 -3
  20. data/lib/mongo/collection/view/readable.rb +3 -1
  21. data/lib/mongo/collection/view/writable.rb +3 -3
  22. data/lib/mongo/cursor/builder/kill_cursors_command.rb +8 -1
  23. data/lib/mongo/cursor/builder/op_kill_cursors.rb +8 -1
  24. data/lib/mongo/database.rb +1 -1
  25. data/lib/mongo/grid/file.rb +5 -0
  26. data/lib/mongo/grid/file/chunk.rb +2 -0
  27. data/lib/mongo/grid/fs_bucket.rb +15 -13
  28. data/lib/mongo/grid/stream/write.rb +9 -3
  29. data/lib/mongo/protocol/serializers.rb +12 -2
  30. data/lib/mongo/server.rb +13 -6
  31. data/lib/mongo/server/connection.rb +15 -8
  32. data/lib/mongo/server/connection_base.rb +7 -4
  33. data/lib/mongo/server/description.rb +34 -21
  34. data/lib/mongo/server/monitor.rb +1 -1
  35. data/lib/mongo/server/monitor/connection.rb +2 -3
  36. data/lib/mongo/session.rb +10 -10
  37. data/lib/mongo/socket.rb +10 -1
  38. data/lib/mongo/uri.rb +1 -1
  39. data/lib/mongo/version.rb +1 -1
  40. data/mongo.gemspec +1 -1
  41. data/spec/README.md +13 -0
  42. data/spec/integration/auth_spec.rb +27 -8
  43. data/spec/integration/bson_symbol_spec.rb +34 -0
  44. data/spec/integration/client_construction_spec.rb +14 -0
  45. data/spec/integration/client_options_spec.rb +5 -5
  46. data/spec/integration/connection_spec.rb +57 -9
  47. data/spec/integration/crud_spec.rb +45 -0
  48. data/spec/integration/cursor_reaping_spec.rb +2 -1
  49. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  50. data/spec/integration/retryable_errors_spec.rb +2 -2
  51. data/spec/integration/zlib_compression_spec.rb +25 -0
  52. data/spec/lite_spec_helper.rb +1 -0
  53. data/spec/mongo/address_spec.rb +19 -13
  54. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  55. data/spec/mongo/auth/scram/conversation_spec.rb +25 -14
  56. data/spec/mongo/auth/user/view_spec.rb +39 -7
  57. data/spec/mongo/auth/user_spec.rb +12 -0
  58. data/spec/mongo/auth/x509/conversation_spec.rb +1 -1
  59. data/spec/mongo/bulk_write_spec.rb +2 -2
  60. data/spec/mongo/client_construction_spec.rb +3 -22
  61. data/spec/mongo/cluster_spec.rb +57 -0
  62. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  63. data/spec/mongo/collection_spec.rb +26 -2
  64. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +56 -0
  65. data/spec/mongo/server/connection_spec.rb +76 -8
  66. data/spec/mongo/server/monitor/connection_spec.rb +14 -7
  67. data/spec/mongo/socket/ssl_spec.rb +132 -98
  68. data/spec/mongo/socket/tcp_spec.rb +1 -9
  69. data/spec/mongo/uri_spec.rb +1 -1
  70. data/spec/runners/sdam/verifier.rb +6 -3
  71. data/spec/spec_tests/data/sdam/rs/primary_address_change.yml +29 -0
  72. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +27 -23
  73. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +56 -79
  74. data/spec/spec_tests/data/sdam/sharded/primary_address_change.yml +21 -0
  75. data/spec/spec_tests/data/sdam/sharded/primary_mismatched_me.yml +22 -0
  76. data/spec/spec_tests/data/sdam/single/primary_address_change.yml +24 -0
  77. data/spec/spec_tests/data/sdam/single/primary_mismatched_me.yml +25 -0
  78. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +159 -0
  79. data/spec/spec_tests/data/sdam_monitoring/{replica_set_other_seed.yml → replica_set_with_primary_change.yml} +97 -101
  80. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_removal.yml +22 -18
  81. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +90 -0
  82. data/spec/support/cluster_config.rb +36 -0
  83. data/spec/support/cluster_tools.rb +5 -3
  84. data/spec/support/command_monitoring.rb +1 -1
  85. data/spec/support/constraints.rb +18 -18
  86. data/spec/support/lite_constraints.rb +8 -0
  87. data/spec/support/server_discovery_and_monitoring.rb +2 -0
  88. data/spec/support/spec_config.rb +3 -3
  89. data/spec/support/utils.rb +11 -1
  90. metadata +661 -637
  91. metadata.gz.sig +0 -0
@@ -185,7 +185,9 @@ module Mongo
185
185
  pipeline << { :'$limit' => opts[:limit] } if opts[:limit]
186
186
  pipeline << { :'$group' => { _id: 1, n: { :'$sum' => 1 } } }
187
187
 
188
- opts.select! { |k, _| [:hint, :max_time_ms, :read, :collation, :session].include?(k) }
188
+ opts = opts.select { |k, _| [:hint, :max_time_ms, :read, :collation, :session].include?(k) }
189
+ opts[:collation] ||= collation
190
+
189
191
  first = aggregate(pipeline, opts).first
190
192
  return 0 unless first
191
193
  first['n'].to_i
@@ -234,7 +234,7 @@ module Mongo
234
234
  Operation::U => replacement,
235
235
  }
236
236
  if opts[:upsert]
237
- update_doc[:upsert] = true
237
+ update_doc['upsert'] = true
238
238
  end
239
239
  with_session(opts) do |session|
240
240
  write_concern = write_concern_with_session(session)
@@ -281,7 +281,7 @@ module Mongo
281
281
  Operation::MULTI => true,
282
282
  }
283
283
  if opts[:upsert]
284
- update_doc[:upsert] = true
284
+ update_doc['upsert'] = true
285
285
  end
286
286
  with_session(opts) do |session|
287
287
  write_concern = write_concern_with_session(session)
@@ -325,7 +325,7 @@ module Mongo
325
325
  Operation::U => spec,
326
326
  }
327
327
  if opts[:upsert]
328
- update_doc[:upsert] = true
328
+ update_doc['upsert'] = true
329
329
  end
330
330
  with_session(opts) do |session|
331
331
  write_concern = write_concern_with_session(session)
@@ -92,7 +92,14 @@ module Mongo
92
92
  #
93
93
  # @since 2.3.0
94
94
  def get_cursors_list(spec)
95
- spec[:selector][:cursors].map(&:value)
95
+ spec[:selector][:cursors].map do |value|
96
+ if value.respond_to?(:value)
97
+ # bson-ruby >= 4.6.0
98
+ value = value.value
99
+ else
100
+ value = value.instance_variable_get('@integer')
101
+ end
102
+ end
96
103
  end
97
104
  end
98
105
  end
@@ -87,7 +87,14 @@ module Mongo
87
87
  #
88
88
  # @since 2.3.0
89
89
  def get_cursors_list(spec)
90
- spec[:cursor_ids].map(&:value)
90
+ spec[:cursor_ids].map do |value|
91
+ if value.respond_to?(:value)
92
+ # bson-ruby >= 4.6.0
93
+ value.value
94
+ else
95
+ value.instance_variable_get('@integer')
96
+ end
97
+ end
91
98
  end
92
99
  end
93
100
  end
@@ -157,7 +157,7 @@ module Mongo
157
157
  # @option opts :read [ Hash ] The read preference for this command.
158
158
  # @option opts :session [ Session ] The session to use for this command.
159
159
  #
160
- # @return [ Hash ] The result of the command execution.
160
+ # @return [ Mongo::Operation::Result ] The result of the command execution.
161
161
  def command(operation, opts = {})
162
162
  txn_read_pref = if opts[:session] && opts[:session].in_transaction?
163
163
  opts[:session].txn_read_preference
@@ -104,6 +104,11 @@ module Mongo
104
104
  # chunk objects and assemble the data. If we have an IO object, then
105
105
  # it's the original file data and we must split it into chunks and set
106
106
  # the original data itself.
107
+ #
108
+ # @param [ IO, String, Array<BSON::Document> ] value The file object,
109
+ # file contents or chunk documents.
110
+ #
111
+ # @return [ Array<Grid::File::Chunk> ] Array of chunks.
107
112
  def initialize_chunks!(value)
108
113
  if value.is_a?(Array)
109
114
  @chunks = value.map{ |doc| Chunk.new(doc) }
@@ -151,6 +151,7 @@ module Mongo
151
151
  # @return [ String ] The assembled data.
152
152
  #
153
153
  # @since 2.0.0
154
+ # @api private
154
155
  def assemble(chunks)
155
156
  chunks.reduce(''){ |data, chunk| data << chunk.data.data }
156
157
  end
@@ -167,6 +168,7 @@ module Mongo
167
168
  # @return [ Array<Chunk> ] The chunks of the data.
168
169
  #
169
170
  # @since 2.0.0
171
+ # @api private
170
172
  def split(io, file_info, offset = 0)
171
173
  io = StringIO.new(io) if io.is_a?(String)
172
174
  parts = Enumerator.new { |y| y << io.read(file_info.chunk_size) until io.eof? }
@@ -177,7 +177,7 @@ module Mongo
177
177
  #
178
178
  # @since 2.0.0
179
179
  def prefix
180
- @options[:fs_name] || @options[:bucket_name]|| DEFAULT_ROOT
180
+ @options[:fs_name] || @options[:bucket_name] || DEFAULT_ROOT
181
181
  end
182
182
 
183
183
  # Remove a single file from the GridFS.
@@ -230,7 +230,8 @@ module Mongo
230
230
  #
231
231
  # @since 2.1.0
232
232
  def open_download_stream(id, options = nil)
233
- read_stream(id, options).tap do |stream|
233
+ options = Hash[(options || {}).map { |k, v| [k.to_sym, v] }]
234
+ read_stream(id, **options).tap do |stream|
234
235
  if block_given?
235
236
  begin
236
237
  yield stream
@@ -348,15 +349,15 @@ module Mongo
348
349
  download_to_stream(open_download_stream_by_name(filename, opts).file_id, io)
349
350
  end
350
351
 
351
- # Opens an upload stream to GridFS to which the contents of a user file came be written.
352
+ # Opens an upload stream to GridFS to which the contents of a file or
353
+ # blob can be written.
352
354
  #
353
- # @example Open a stream to which the contents of a file came be written.
354
- # fs.open_upload_stream('a-file.txt')
355
- #
356
- # @param [ String ] filename The filename of the file to upload.
355
+ # @param [ String ] filename The name of the file in GridFS.
357
356
  # @param [ Hash ] opts The options for the write stream.
358
357
  #
359
- # @option opts [ Object ] :file_id An optional unique file id. An ObjectId is generated otherwise.
358
+ # @option opts [ Object ] :file_id An optional unique file id.
359
+ # A BSON::ObjectId is automatically generated if a file id is not
360
+ # provided.
360
361
  # @option opts [ Integer ] :chunk_size Override the default chunk size.
361
362
  # @option opts [ Hash ] :metadata User data for the 'metadata' field of the files
362
363
  # collection document.
@@ -375,7 +376,8 @@ module Mongo
375
376
  #
376
377
  # @since 2.1.0
377
378
  def open_upload_stream(filename, opts = {})
378
- write_stream(filename, opts).tap do |stream|
379
+ opts = Hash[opts.map { |k, v| [k.to_sym, v] }]
380
+ write_stream(filename, **opts).tap do |stream|
379
381
  if block_given?
380
382
  begin
381
383
  yield stream
@@ -462,12 +464,12 @@ module Mongo
462
464
  #
463
465
  # @option opts [ BSON::Document ] :file_info_doc For internal
464
466
  # driver use only. A BSON document to use as file information.
465
- def read_stream(id, opts = nil)
466
- Stream.get(self, Stream::READ_MODE, { file_id: id }.update(options).update(opts || {}))
467
+ def read_stream(id, **opts)
468
+ Stream.get(self, Stream::READ_MODE, { file_id: id }.update(options).update(opts))
467
469
  end
468
470
 
469
- def write_stream(filename, opts)
470
- Stream.get(self, Stream::WRITE_MODE, { filename: filename }.merge!(options).merge!(opts))
471
+ def write_stream(filename, **opts)
472
+ Stream.get(self, Stream::WRITE_MODE, { filename: filename }.update(options).update(opts))
471
473
  end
472
474
 
473
475
  def chunks_name
@@ -82,12 +82,12 @@ module Mongo
82
82
  @open = true
83
83
  end
84
84
 
85
- # Write to the GridFS bucket from the source stream.
85
+ # Write to the GridFS bucket from the source stream or a string.
86
86
  #
87
87
  # @example Write to GridFS.
88
88
  # stream.write(io)
89
89
  #
90
- # @param [ IO ] io The source io stream to upload from.
90
+ # @param [ String | IO ] io The string or IO object to upload from.
91
91
  #
92
92
  # @return [ Stream::Write ] self The write stream itself.
93
93
  #
@@ -95,7 +95,13 @@ module Mongo
95
95
  def write(io)
96
96
  ensure_open!
97
97
  @indexes ||= ensure_indexes!
98
- @length += io.size
98
+ @length += if io.respond_to?(:bytesize)
99
+ # String objects
100
+ io.bytesize
101
+ else
102
+ # IO objects
103
+ io.size
104
+ end
99
105
  chunks = File::Chunk.split(io, file_info, @n)
100
106
  @n += chunks.size
101
107
  chunks_collection.insert_many(chunks) unless chunks.empty?
@@ -110,7 +110,12 @@ module Mongo
110
110
  # @return [String] Buffer with serialized value.
111
111
  def self.serialize(buffer, value, validating_keys = BSON::Config.validating_keys?)
112
112
  if value.is_a?(BSON::Int32)
113
- value = value.value
113
+ if value.respond_to?(:value)
114
+ # bson-ruby >= 4.6.0
115
+ value = value.value
116
+ else
117
+ value = value.instance_variable_get('@integer')
118
+ end
114
119
  end
115
120
  buffer.put_int32(value)
116
121
  end
@@ -138,7 +143,12 @@ module Mongo
138
143
  # @return [ String ] Buffer with serialized value.
139
144
  def self.serialize(buffer, value, validating_keys = BSON::Config.validating_keys?)
140
145
  if value.is_a?(BSON::Int64)
141
- value = value.value
146
+ if value.respond_to?(:value)
147
+ # bson-ruby >= 4.6.0
148
+ value = value.value
149
+ else
150
+ value = value.instance_variable_get('@integer')
151
+ end
142
152
  end
143
153
  buffer.put_int64(value)
144
154
  end
@@ -306,12 +306,11 @@ module Mongo
306
306
  "#<Mongo::Server:0x#{object_id} address=#{address.host}:#{address.port}>"
307
307
  end
308
308
 
309
- # @note This method is experimental and subject to change.
309
+ # @return [ String ] String representing server status (e.g. PRIMARY).
310
310
  #
311
- # @api experimental
312
- # @since 2.7.0
313
- def summary
314
- status = case
311
+ # @api private
312
+ def status
313
+ case
315
314
  when primary?
316
315
  'PRIMARY'
317
316
  when secondary?
@@ -331,8 +330,16 @@ module Mongo
331
330
  else
332
331
  # Since the summary method is often used for debugging, do not raise
333
332
  # an exception in case none of the expected types matched
334
- ''
333
+ nil
335
334
  end
335
+ end
336
+
337
+ # @note This method is experimental and subject to change.
338
+ #
339
+ # @api experimental
340
+ # @since 2.7.0
341
+ def summary
342
+ status = self.status || ''
336
343
  if replica_set_name
337
344
  status += " replica_set=#{replica_set_name}"
338
345
  end
@@ -103,6 +103,12 @@ module Mongo
103
103
  )
104
104
  end
105
105
 
106
+ # @return [ Server::Description ] The server description obtained from
107
+ # the handshake on this connection.
108
+ #
109
+ # @api private
110
+ attr_reader :description
111
+
106
112
  # @return [ Time ] The last time the connection was checked back into a pool.
107
113
  #
108
114
  # @since 2.5.0
@@ -181,13 +187,14 @@ module Mongo
181
187
 
182
188
  # Separate method to permit easier mocking in the test suite.
183
189
  def do_connect
184
- socket = address.socket(socket_timeout, ssl_options,
185
- connect_timeout: address.connect_timeout)
190
+ socket = address.socket(socket_timeout, ssl_options, address.options)
186
191
 
187
192
  begin
188
193
  handshake!(socket)
189
- pending_connection = PendingConnection.new(socket, @server, monitoring, options.merge(id: id))
190
- authenticate!(pending_connection)
194
+ unless description.arbiter?
195
+ pending_connection = PendingConnection.new(socket, @server, monitoring, options.merge(id: id))
196
+ authenticate!(pending_connection)
197
+ end
191
198
  rescue Exception
192
199
  socket.close
193
200
  raise
@@ -314,7 +321,7 @@ module Mongo
314
321
  raise exc
315
322
  end
316
323
  rescue => e
317
- log_warn("Failed to handshake with #{address}: #{e.class}: #{e}")
324
+ log_warn("Failed to handshake with #{address}: #{e.class}: #{e}:\n#{e.backtrace[0..5].join("\n")}")
318
325
  raise
319
326
  end
320
327
  end
@@ -356,8 +363,8 @@ module Mongo
356
363
  @auth_mechanism = nil
357
364
  end
358
365
 
359
- new_description = Description.new(address, response, average_rtt)
360
- @server.cluster.run_sdam_flow(@server.description, new_description)
366
+ @description = Description.new(address, response, average_rtt)
367
+ @server.cluster.run_sdam_flow(@server.description, @description)
361
368
  end
362
369
 
363
370
  def authenticate!(pending_connection)
@@ -371,7 +378,7 @@ module Mongo
371
378
  begin
372
379
  Auth.get(user).login(pending_connection)
373
380
  rescue => e
374
- log_warn("Failed to handshake with #{address}: #{e.class}: #{e}")
381
+ log_warn("Failed to handshake with #{address}: #{e.class}: #{e}:\n#{e.backtrace[0..5].join("\n")}")
375
382
  raise
376
383
  end
377
384
  end
@@ -29,12 +29,15 @@ module Mongo
29
29
  # @return [ Hash ] options The passed in options.
30
30
  attr_reader :options
31
31
 
32
+ # @return [ Server ] The server that this connection is for.
33
+ #
34
+ # @api private
35
+ attr_reader :server
36
+
32
37
  # @return [ Mongo::Address ] address The address to connect to.
33
- def address
34
- @server.address
35
- end
38
+ def_delegators :server, :address
36
39
 
37
- def_delegators :@server,
40
+ def_delegators :server,
38
41
  :features,
39
42
  :max_bson_object_size,
40
43
  :max_message_size,
@@ -33,6 +33,7 @@ module Mongo
33
33
  # Constant for reading arbiter info from config.
34
34
  #
35
35
  # @since 2.0.0
36
+ # @deprecated
36
37
  ARBITER = 'arbiterOnly'.freeze
37
38
 
38
39
  # Constant for reading arbiters info from config.
@@ -53,16 +54,19 @@ module Mongo
53
54
  # Constant for the key for the message value.
54
55
  #
55
56
  # @since 2.0.0
57
+ # @deprecated
56
58
  MESSAGE = 'msg'.freeze
57
59
 
58
60
  # Constant for the message that indicates a sharded cluster.
59
61
  #
60
62
  # @since 2.0.0
63
+ # @deprecated
61
64
  MONGOS_MESSAGE = 'isdbgrid'.freeze
62
65
 
63
66
  # Constant for determining ghost servers.
64
67
  #
65
68
  # @since 2.0.0
69
+ # @deprecated
66
70
  REPLICA_SET = 'isreplicaset'.freeze
67
71
 
68
72
  # Constant for reading max bson size info from config.
@@ -129,6 +133,7 @@ module Mongo
129
133
  # Constant for reading primary info from config.
130
134
  #
131
135
  # @since 2.0.0
136
+ # @deprecated
132
137
  PRIMARY = 'ismaster'.freeze
133
138
 
134
139
  # Constant for reading primary host field from config.
@@ -139,6 +144,7 @@ module Mongo
139
144
  # Constant for reading secondary info from config.
140
145
  #
141
146
  # @since 2.0.0
147
+ # @deprecated
142
148
  SECONDARY = 'secondary'.freeze
143
149
 
144
150
  # Constant for reading replica set name info from config.
@@ -227,7 +233,7 @@ module Mongo
227
233
  # @return [ Float ] The moving average time the ismaster call took to complete.
228
234
  attr_reader :average_round_trip_time
229
235
 
230
- # Will return true if the server is an arbiter.
236
+ # Returns whether this server is an arbiter, per the SDAM spec.
231
237
  #
232
238
  # @example Is the server an arbiter?
233
239
  # description.arbiter?
@@ -236,7 +242,9 @@ module Mongo
236
242
  #
237
243
  # @since 2.0.0
238
244
  def arbiter?
239
- ok? && !!config[ARBITER] && !replica_set_name.nil?
245
+ ok? &&
246
+ config['arbiterOnly'] == true &&
247
+ !!config['setName']
240
248
  end
241
249
 
242
250
  # Get a list of all arbiters in the replica set.
@@ -251,7 +259,7 @@ module Mongo
251
259
  @arbiters ||= (config[ARBITERS] || []).map { |s| s.downcase }
252
260
  end
253
261
 
254
- # Is the server a ghost in a replica set?
262
+ # Whether this server is a ghost, per the SDAM spec.
255
263
  #
256
264
  # @example Is the server a ghost?
257
265
  # description.ghost?
@@ -260,7 +268,8 @@ module Mongo
260
268
  #
261
269
  # @since 2.0.0
262
270
  def ghost?
263
- ok? && !!config[REPLICA_SET]
271
+ ok? &&
272
+ config['isreplicaset'] == true
264
273
  end
265
274
 
266
275
  # Will return true if the server is hidden.
@@ -431,7 +440,7 @@ module Mongo
431
440
  config[LOGICAL_SESSION_TIMEOUT_MINUTES] if config[LOGICAL_SESSION_TIMEOUT_MINUTES]
432
441
  end
433
442
 
434
- # Is the server a mongos?
443
+ # Returns whether this server is a mongos, per the SDAM spec.
435
444
  #
436
445
  # @example Is the server a mongos?
437
446
  # description.mongos?
@@ -440,10 +449,10 @@ module Mongo
440
449
  #
441
450
  # @since 2.0.0
442
451
  def mongos?
443
- ok? && config[MESSAGE] == MONGOS_MESSAGE
452
+ ok? && config['msg'] == 'isdbgrid'
444
453
  end
445
454
 
446
- # Is the description of type other.
455
+ # Returns whether the server is an other, per the SDAM spec.
447
456
  #
448
457
  # @example Is the description of type other.
449
458
  # description.other?
@@ -455,11 +464,11 @@ module Mongo
455
464
  # The SDAM spec is slightly confusing on what "other" means,
456
465
  # but it's referred to it as "RSOther" which means a non-RS member
457
466
  # cannot be "other".
458
- if unknown? || replica_set_name.nil?
459
- return false
460
- end
461
- (!primary? && !secondary? && !passive? && !arbiter?) ||
462
- (hidden? && !replica_set_name.nil?)
467
+ ok? &&
468
+ !!config['setName'] && (
469
+ config['hidden'] == true ||
470
+ !primary? && !secondary? && !arbiter?
471
+ )
463
472
  end
464
473
 
465
474
  # Will return true if the server is passive.
@@ -498,7 +507,7 @@ module Mongo
498
507
  config[PRIMARY_HOST] && config[PRIMARY_HOST].downcase
499
508
  end
500
509
 
501
- # Will return true if the server is a primary.
510
+ # Returns whether this server is a primary, per the SDAM spec.
502
511
  #
503
512
  # @example Is the server a primary?
504
513
  # description.primary?
@@ -508,9 +517,8 @@ module Mongo
508
517
  # @since 2.0.0
509
518
  def primary?
510
519
  ok? &&
511
- !!config[PRIMARY] &&
512
- (primary_host.nil? || primary_host == address.to_s) &&
513
- !replica_set_name.nil?
520
+ config['ismaster'] == true &&
521
+ !!config['setName']
514
522
  end
515
523
 
516
524
  # Get the name of the replica set the server belongs to, returns nil if
@@ -538,7 +546,7 @@ module Mongo
538
546
  hosts + arbiters + passives
539
547
  end
540
548
 
541
- # Will return true if the server is a secondary.
549
+ # Returns whether this server is a secondary, per the SDAM spec.
542
550
  #
543
551
  # @example Is the server a secondary?
544
552
  # description.secondary?
@@ -547,7 +555,9 @@ module Mongo
547
555
  #
548
556
  # @since 2.0.0
549
557
  def secondary?
550
- ok? && !!config[SECONDARY] && !replica_set_name.nil?
558
+ ok? &&
559
+ config['secondary'] == true &&
560
+ !!config['setName']
551
561
  end
552
562
 
553
563
  # Returns the server type as a symbol.
@@ -569,7 +579,7 @@ module Mongo
569
579
  :unknown
570
580
  end
571
581
 
572
- # Is this server a standalone server?
582
+ # Returns whether this server is a standalone, per the SDAM spec.
573
583
  #
574
584
  # @example Is the server standalone?
575
585
  # description.standalone?
@@ -578,10 +588,13 @@ module Mongo
578
588
  #
579
589
  # @since 2.0.0
580
590
  def standalone?
581
- replica_set_name.nil? && !mongos? && !ghost? && !unknown?
591
+ ok? &&
592
+ config['msg'] != 'isdbgrid' &&
593
+ config['setName'].nil? &&
594
+ config['isreplicaset'] != true
582
595
  end
583
596
 
584
- # Is the server description currently unknown?
597
+ # Returns whether this server is an unknown, per the SDAM spec.
585
598
  #
586
599
  # @example Is the server description unknown?
587
600
  # description.unknown?