mongo 1.12.5 → 2.0.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CONTRIBUTING.md +64 -0
- data/LICENSE +1 -1
- data/README.md +21 -126
- data/Rakefile +39 -21
- data/bin/mongo_console +6 -38
- data/lib/mongo/address/ipv4.rb +85 -0
- data/lib/mongo/address/ipv6.rb +85 -0
- data/lib/mongo/address/unix.rb +76 -0
- data/lib/mongo/address.rb +111 -0
- data/lib/mongo/auth/cr/conversation.rb +119 -0
- data/lib/mongo/auth/cr.rb +44 -0
- data/lib/mongo/auth/executable.rb +52 -0
- data/lib/mongo/auth/ldap/conversation.rb +92 -0
- data/lib/mongo/auth/ldap.rb +48 -0
- data/lib/mongo/auth/roles.rb +104 -0
- data/lib/mongo/auth/scram/conversation.rb +450 -0
- data/lib/mongo/auth/scram.rb +53 -0
- data/lib/mongo/auth/user/view.rb +102 -0
- data/lib/mongo/auth/user.rb +159 -0
- data/lib/mongo/auth/x509/conversation.rb +92 -0
- data/lib/mongo/auth/x509.rb +48 -0
- data/lib/mongo/auth.rb +108 -0
- data/lib/mongo/bulk_write/bulk_writable.rb +191 -0
- data/lib/mongo/bulk_write/deletable.rb +60 -0
- data/lib/mongo/bulk_write/insertable.rb +52 -0
- data/lib/mongo/bulk_write/ordered_bulk_write.rb +48 -0
- data/lib/mongo/bulk_write/replacable.rb +57 -0
- data/lib/mongo/bulk_write/unordered_bulk_write.rb +46 -0
- data/lib/mongo/bulk_write/updatable.rb +68 -0
- data/lib/mongo/bulk_write.rb +52 -0
- data/lib/mongo/client.rb +246 -0
- data/lib/mongo/cluster/topology/replica_set.rb +160 -0
- data/lib/mongo/cluster/topology/sharded.rb +132 -0
- data/lib/mongo/cluster/topology/standalone.rb +132 -0
- data/lib/mongo/cluster/topology/unknown.rb +155 -0
- data/lib/mongo/cluster/topology.rb +60 -0
- data/lib/mongo/cluster.rb +203 -0
- data/lib/mongo/collection/view/aggregation.rb +108 -0
- data/lib/mongo/collection/view/explainable.rb +49 -0
- data/lib/mongo/collection/view/immutable.rb +43 -0
- data/lib/mongo/collection/view/iterable.rb +48 -0
- data/lib/mongo/collection/view/map_reduce.rb +191 -0
- data/lib/mongo/collection/view/readable.rb +363 -0
- data/lib/mongo/collection/view/writable.rb +185 -0
- data/lib/mongo/collection/view.rb +169 -0
- data/lib/mongo/collection.rb +130 -1101
- data/lib/mongo/cursor.rb +78 -681
- data/lib/mongo/database/view.rb +101 -0
- data/lib/mongo/database.rb +224 -0
- data/lib/mongo/error/bulk_write_error.rb +41 -0
- data/lib/mongo/error/invalid_bulk_operation.rb +36 -0
- data/lib/mongo/error/invalid_bulk_operation_type.rb +36 -0
- data/lib/mongo/error/invalid_collection_name.rb +39 -0
- data/lib/mongo/error/invalid_database_name.rb +39 -0
- data/{test/replica_set/ssl_test.rb → lib/mongo/error/invalid_document.rb} +21 -14
- data/lib/mongo/error/invalid_file.rb +38 -0
- data/lib/mongo/error/invalid_nonce.rb +46 -0
- data/lib/mongo/error/invalid_replacement_document.rb +39 -0
- data/lib/mongo/error/invalid_signature.rb +47 -0
- data/{test/functional/ssl_test.rb → lib/mongo/error/invalid_update_document.rb} +22 -12
- data/lib/mongo/error/max_bson_size.rb +40 -0
- data/lib/mongo/error/max_message_size.rb +42 -0
- data/{test/functional/db_connection_test.rb → lib/mongo/error/multi_index_drop.rb} +17 -8
- data/lib/mongo/{utils.rb → error/need_primary_server.rb} +10 -6
- data/lib/mongo/{connection.rb → error/operation_failure.rb} +10 -6
- data/lib/mongo/error/parser.rb +77 -0
- data/lib/mongo/{connection/socket.rb → error/socket_error.rb} +10 -5
- data/lib/mongo/error/socket_timeout_error.rb +23 -0
- data/lib/mongo/error/unsupported_features.rb +43 -0
- data/lib/mongo/error.rb +82 -0
- data/lib/mongo/event/listeners.rb +63 -0
- data/lib/mongo/event/primary_elected.rb +53 -0
- data/lib/mongo/event/publisher.rb +42 -0
- data/lib/mongo/event/server_added.rb +53 -0
- data/lib/mongo/event/server_removed.rb +53 -0
- data/lib/mongo/event/subscriber.rb +41 -0
- data/lib/mongo/event.rb +40 -0
- data/lib/mongo/grid/file/chunk.rb +184 -0
- data/lib/mongo/grid/file/metadata.rb +229 -0
- data/lib/mongo/grid/file.rb +106 -0
- data/lib/mongo/grid/fs.rb +149 -0
- data/lib/mongo/{gridfs.rb → grid.rb} +3 -5
- data/lib/mongo/index/view.rb +261 -0
- data/lib/mongo/index.rb +64 -0
- data/lib/mongo/loggable.rb +126 -0
- data/lib/mongo/logger.rb +132 -0
- data/lib/mongo/operation/aggregate/result.rb +88 -0
- data/lib/mongo/operation/aggregate.rb +100 -0
- data/lib/mongo/operation/command.rb +62 -0
- data/lib/mongo/operation/executable.rb +105 -0
- data/lib/mongo/operation/kill_cursors.rb +39 -0
- data/lib/mongo/operation/limited.rb +37 -0
- data/lib/mongo/operation/list_collections/result.rb +114 -0
- data/lib/mongo/operation/list_indexes/result.rb +118 -0
- data/lib/mongo/operation/map_reduce/result.rb +122 -0
- data/lib/mongo/operation/map_reduce.rb +96 -0
- data/lib/mongo/operation/read/collections_info.rb +67 -0
- data/lib/mongo/operation/read/get_more.rb +71 -0
- data/lib/mongo/operation/read/indexes.rb +68 -0
- data/lib/mongo/operation/read/list_collections.rb +75 -0
- data/lib/mongo/operation/read/list_indexes.rb +77 -0
- data/lib/mongo/operation/read/query.rb +71 -0
- data/lib/mongo/{functional.rb → operation/read.rb} +7 -7
- data/lib/mongo/operation/read_preferrable.rb +34 -0
- data/lib/mongo/operation/result.rb +259 -0
- data/lib/mongo/operation/specifiable.rb +397 -0
- data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +75 -0
- data/lib/mongo/operation/write/bulk/bulk_delete.rb +144 -0
- data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +68 -0
- data/lib/mongo/operation/write/bulk/bulk_insert.rb +129 -0
- data/lib/mongo/operation/write/bulk/bulk_mergable.rb +67 -0
- data/lib/mongo/operation/write/bulk/bulk_update/result.rb +162 -0
- data/lib/mongo/operation/write/bulk/bulk_update.rb +153 -0
- data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +83 -0
- data/lib/mongo/operation/write/bulk.rb +17 -0
- data/lib/mongo/operation/write/command/create_index.rb +50 -0
- data/lib/mongo/operation/write/command/create_user.rb +43 -0
- data/lib/mongo/operation/write/command/delete.rb +56 -0
- data/lib/mongo/operation/write/command/drop_index.rb +51 -0
- data/lib/mongo/operation/write/command/insert.rb +55 -0
- data/lib/mongo/operation/write/command/remove_user.rb +42 -0
- data/lib/mongo/operation/write/command/update.rb +60 -0
- data/lib/mongo/operation/write/command/writable.rb +61 -0
- data/lib/mongo/operation/write/command.rb +22 -0
- data/lib/mongo/operation/write/create_index.rb +89 -0
- data/lib/mongo/operation/write/create_user.rb +75 -0
- data/lib/mongo/operation/write/delete/result.rb +40 -0
- data/lib/mongo/operation/write/delete.rb +93 -0
- data/lib/mongo/operation/write/drop_index.rb +62 -0
- data/lib/mongo/{utils/thread_local_variable_manager.rb → operation/write/insert/result.rb} +15 -8
- data/lib/mongo/operation/write/insert.rb +90 -0
- data/lib/mongo/operation/write/remove_user.rb +70 -0
- data/lib/mongo/operation/write/update/result.rb +160 -0
- data/lib/mongo/operation/write/update.rb +103 -0
- data/lib/mongo/{connection/socket/socket_util.rb → operation/write.rb} +10 -24
- data/lib/mongo/operation.rb +25 -0
- data/lib/mongo/options/mapper.rb +78 -0
- data/lib/mongo/options.rb +15 -0
- data/lib/mongo/protocol/bit_vector.rb +61 -0
- data/lib/mongo/protocol/delete.rb +94 -0
- data/lib/mongo/protocol/get_more.rb +99 -0
- data/lib/mongo/protocol/insert.rb +99 -0
- data/lib/mongo/protocol/kill_cursors.rb +74 -0
- data/lib/mongo/protocol/message.rb +252 -0
- data/lib/mongo/protocol/query.rb +147 -0
- data/lib/mongo/protocol/reply.rb +72 -0
- data/lib/mongo/protocol/serializers.rb +180 -0
- data/lib/mongo/protocol/update.rb +111 -0
- data/lib/mongo/protocol.rb +15 -0
- data/lib/mongo/server/connectable.rb +110 -0
- data/lib/mongo/server/connection.rb +134 -0
- data/lib/mongo/server/connection_pool/queue.rb +182 -0
- data/lib/mongo/server/connection_pool.rb +141 -0
- data/lib/mongo/server/context.rb +66 -0
- data/lib/mongo/server/description/features.rb +85 -0
- data/lib/mongo/server/description/inspector/primary_elected.rb +58 -0
- data/lib/mongo/server/description/inspector/server_added.rb +59 -0
- data/lib/mongo/server/description/inspector/server_removed.rb +59 -0
- data/lib/mongo/server/description/inspector.rb +79 -0
- data/lib/mongo/server/description.rb +450 -0
- data/lib/mongo/server/monitor/connection.rb +89 -0
- data/lib/mongo/server/monitor.rb +176 -0
- data/lib/mongo/server.rb +163 -0
- data/lib/mongo/server_selector/nearest.rb +94 -0
- data/lib/mongo/server_selector/primary.rb +88 -0
- data/lib/mongo/server_selector/primary_preferred.rb +94 -0
- data/lib/mongo/server_selector/secondary.rb +91 -0
- data/lib/mongo/server_selector/secondary_preferred.rb +96 -0
- data/lib/mongo/server_selector/selectable.rb +209 -0
- data/lib/mongo/server_selector.rb +81 -0
- data/lib/mongo/socket/ssl.rb +130 -0
- data/lib/mongo/socket/tcp.rb +69 -0
- data/lib/mongo/socket/unix.rb +64 -0
- data/lib/mongo/socket.rb +179 -0
- data/lib/mongo/uri.rb +504 -0
- data/lib/mongo/version.rb +21 -0
- data/lib/mongo/write_concern/acknowledged.rb +52 -0
- data/lib/mongo/write_concern/normalizable.rb +51 -0
- data/lib/mongo/write_concern/unacknowledged.rb +55 -0
- data/lib/mongo/write_concern.rb +99 -0
- data/lib/mongo.rb +24 -82
- data/mongo.gemspec +17 -14
- data/spec/certificates/ca.pem +17 -0
- data/spec/certificates/client.pem +101 -0
- data/spec/certificates/crl.pem +10 -0
- data/spec/certificates/crl_client_revoked.pem +12 -0
- data/spec/certificates/password_protected.pem +51 -0
- data/spec/certificates/server.pem +34 -0
- data/spec/mongo/address/ipv4_spec.rb +74 -0
- data/spec/mongo/address/ipv6_spec.rb +74 -0
- data/spec/mongo/address/unix_spec.rb +30 -0
- data/spec/mongo/address_spec.rb +206 -0
- data/spec/mongo/auth/cr_spec.rb +59 -0
- data/spec/mongo/auth/ldap_spec.rb +40 -0
- data/spec/mongo/auth/scram/conversation_spec.rb +197 -0
- data/spec/mongo/auth/scram_spec.rb +55 -0
- data/spec/mongo/auth/user/view_spec.rb +76 -0
- data/spec/mongo/auth/user_spec.rb +190 -0
- data/spec/mongo/auth/x509_spec.rb +40 -0
- data/spec/mongo/auth_spec.rb +65 -0
- data/spec/mongo/bulk/bulk_write_spec.rb +262 -0
- data/spec/mongo/client_spec.rb +564 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +101 -0
- data/spec/mongo/cluster/topology/sharded_spec.rb +74 -0
- data/spec/mongo/cluster/topology/standalone_spec.rb +79 -0
- data/spec/mongo/cluster/topology_spec.rb +65 -0
- data/spec/mongo/cluster_spec.rb +129 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +148 -0
- data/spec/mongo/collection/view/explainable_spec.rb +32 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +242 -0
- data/spec/mongo/collection/view/readable_spec.rb +603 -0
- data/spec/mongo/collection/view/writable_spec.rb +679 -0
- data/spec/mongo/collection/view_spec.rb +530 -0
- data/spec/mongo/collection_spec.rb +362 -0
- data/spec/mongo/crud_spec.rb +42 -0
- data/spec/mongo/cursor_spec.rb +295 -0
- data/spec/mongo/database_spec.rb +302 -0
- data/spec/mongo/error/parser_spec.rb +119 -0
- data/spec/mongo/event/publisher_spec.rb +50 -0
- data/spec/mongo/event/subscriber_spec.rb +34 -0
- data/spec/mongo/grid/file/chunk_spec.rb +226 -0
- data/spec/mongo/grid/file/metadata_spec.rb +92 -0
- data/spec/mongo/grid/file_spec.rb +172 -0
- data/spec/mongo/grid/fs_spec.rb +129 -0
- data/spec/mongo/index/view_spec.rb +330 -0
- data/spec/mongo/loggable_spec.rb +62 -0
- data/spec/mongo/logger_spec.rb +97 -0
- data/spec/mongo/operation/aggregate/result_spec.rb +80 -0
- data/spec/mongo/operation/aggregate_spec.rb +127 -0
- data/spec/mongo/operation/command_spec.rb +98 -0
- data/spec/mongo/operation/kill_cursors_spec.rb +66 -0
- data/spec/mongo/operation/limited_spec.rb +50 -0
- data/spec/mongo/operation/map_reduce_spec.rb +143 -0
- data/spec/mongo/operation/read/collections_info_spec.rb +40 -0
- data/spec/mongo/operation/read/get_more_spec.rb +81 -0
- data/spec/mongo/operation/read/indexes_spec.rb +31 -0
- data/spec/mongo/operation/read/query_spec.rb +84 -0
- data/spec/mongo/operation/result_spec.rb +275 -0
- data/spec/mongo/operation/specifiable_spec.rb +53 -0
- data/spec/mongo/operation/write/bulk_delete_spec.rb +235 -0
- data/spec/mongo/operation/write/bulk_insert_spec.rb +235 -0
- data/spec/mongo/operation/write/bulk_update_spec.rb +236 -0
- data/spec/mongo/operation/write/command/delete_spec.rb +103 -0
- data/spec/mongo/operation/write/command/insert_spec.rb +103 -0
- data/spec/mongo/operation/write/command/update_spec.rb +109 -0
- data/spec/mongo/operation/write/create_index_spec.rb +63 -0
- data/spec/mongo/operation/write/create_user_spec.rb +44 -0
- data/spec/mongo/operation/write/delete_spec.rb +186 -0
- data/spec/mongo/operation/write/drop_index_spec.rb +51 -0
- data/spec/mongo/operation/write/insert_spec.rb +244 -0
- data/spec/mongo/operation/write/remove_user_spec.rb +46 -0
- data/spec/mongo/operation/write/response_spec.rb +85 -0
- data/spec/mongo/operation/write/update_spec.rb +228 -0
- data/spec/mongo/protocol/delete_spec.rb +167 -0
- data/spec/mongo/protocol/get_more_spec.rb +146 -0
- data/spec/mongo/protocol/insert_spec.rb +161 -0
- data/spec/mongo/protocol/kill_cursors_spec.rb +101 -0
- data/spec/mongo/protocol/query_spec.rb +285 -0
- data/spec/mongo/protocol/reply_spec.rb +157 -0
- data/spec/mongo/protocol/update_spec.rb +186 -0
- data/spec/mongo/server/connection_pool/queue_spec.rb +170 -0
- data/spec/mongo/server/connection_pool_spec.rb +120 -0
- data/spec/mongo/server/connection_spec.rb +312 -0
- data/spec/mongo/server/description/features_spec.rb +138 -0
- data/spec/mongo/server/description/inspector/primary_elected_spec.rb +94 -0
- data/spec/mongo/server/description/inspector/server_added_spec.rb +92 -0
- data/spec/mongo/server/description/inspector/server_removed_spec.rb +95 -0
- data/spec/mongo/server/description_spec.rb +510 -0
- data/spec/mongo/server/monitor_spec.rb +144 -0
- data/spec/mongo/server_discovery_and_monitoring_spec.rb +103 -0
- data/spec/mongo/server_selection_rtt_spec.rb +104 -0
- data/spec/mongo/server_selection_spec.rb +89 -0
- data/spec/mongo/server_selector/nearest_spec.rb +250 -0
- data/spec/mongo/server_selector/primary_preferred_spec.rb +290 -0
- data/spec/mongo/server_selector/primary_spec.rb +114 -0
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +252 -0
- data/spec/mongo/server_selector/secondary_spec.rb +196 -0
- data/spec/mongo/server_selector_spec.rb +101 -0
- data/spec/mongo/server_spec.rb +131 -0
- data/spec/mongo/uri_spec.rb +517 -0
- data/spec/mongo/write_concern/acknowledged_spec.rb +44 -0
- data/spec/mongo/write_concern/unacknowledged_spec.rb +15 -0
- data/spec/spec_helper.rb +133 -0
- data/spec/support/authorization.rb +247 -0
- data/spec/support/crud/read.rb +144 -0
- data/spec/support/crud/write.rb +214 -0
- data/spec/support/crud.rb +203 -0
- data/spec/support/crud_tests/read/aggregate.yml +43 -0
- data/spec/support/crud_tests/read/count.yml +37 -0
- data/spec/support/crud_tests/read/distinct.yml +33 -0
- data/spec/support/crud_tests/read/find.yml +50 -0
- data/spec/support/crud_tests/write/deleteMany.yml +36 -0
- data/spec/support/crud_tests/write/deleteOne.yml +49 -0
- data/spec/support/crud_tests/write/findOneAndDelete.yml +54 -0
- data/spec/support/crud_tests/write/findOneAndReplace.yml +153 -0
- data/spec/support/crud_tests/write/findOneAndUpdate.yml +161 -0
- data/spec/support/crud_tests/write/insertMany.yml +24 -0
- data/spec/support/crud_tests/write/insertOne.yml +19 -0
- data/spec/support/crud_tests/write/replaceOne.yml +96 -0
- data/spec/support/crud_tests/write/updateMany.yml +83 -0
- data/spec/support/crud_tests/write/updateOne.yml +80 -0
- data/spec/support/helpers.rb +140 -0
- data/spec/support/matchers.rb +37 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +41 -0
- data/spec/support/sdam/rs/discover_passives.yml +41 -0
- data/spec/support/sdam/rs/discover_primary.yml +40 -0
- data/spec/support/sdam/rs/discover_secondary.yml +41 -0
- data/spec/support/sdam/rs/discovery.yml +195 -0
- data/spec/support/sdam/rs/ghost_discovered.yml +39 -0
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +34 -0
- data/spec/support/sdam/rs/member_reconfig.yml +68 -0
- data/spec/support/sdam/rs/member_standalone.yml +60 -0
- data/spec/support/sdam/rs/new_primary.yml +74 -0
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +71 -0
- data/spec/support/sdam/rs/non_rs_member.yml +31 -0
- data/spec/support/sdam/rs/normalize_case.yml +49 -0
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +52 -0
- data/spec/support/sdam/rs/primary_changes_set_name.yml +57 -0
- data/spec/support/sdam/rs/primary_disconnect.yml +56 -0
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +27 -0
- data/spec/support/sdam/rs/response_from_removed.yml +63 -0
- data/spec/support/sdam/rs/rsother_discovered.yml +41 -0
- data/spec/support/sdam/rs/sec_not_auth.yml +49 -0
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +28 -0
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +69 -0
- data/spec/support/sdam/rs/unexpected_mongos.yml +26 -0
- data/spec/support/sdam/rs/wrong_set_name.yml +35 -0
- data/spec/support/sdam/sharded/multiple_mongoses.yml +46 -0
- data/spec/support/sdam/sharded/non_mongos_removed.yml +41 -0
- data/spec/support/sdam/sharded/normalize_uri_case.yml +32 -0
- data/spec/support/sdam/single/direct_connection_external_ip.yml +34 -0
- data/spec/support/sdam/single/direct_connection_mongos.yml +33 -0
- data/spec/support/sdam/single/direct_connection_rsarbiter.yml +35 -0
- data/spec/support/sdam/single/direct_connection_rsprimary.yml +34 -0
- data/spec/support/sdam/single/direct_connection_rssecondary.yml +35 -0
- data/spec/support/sdam/single/direct_connection_slave.yml +32 -0
- data/spec/support/sdam/single/direct_connection_standalone.yml +32 -0
- data/spec/support/sdam/single/not_ok_response.yml +39 -0
- data/spec/support/sdam/single/standalone_removed.yml +32 -0
- data/spec/support/sdam/single/unavailable_seed.yml +28 -0
- data/spec/support/server_discovery_and_monitoring.rb +167 -0
- data/spec/support/server_selection/rtt/first_value.yml +4 -0
- data/spec/support/server_selection/rtt/first_value_zero.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_1.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_2.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_3.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_4.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_5.yml +4 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Primary.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest.yml +33 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Primary.yml +29 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +29 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +29 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary.yml +31 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred.yml +31 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml +29 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary_non_matching.yml +26 -0
- data/spec/support/server_selection/selection/Sharded/read/SecondaryPreferred.yml +26 -0
- data/spec/support/server_selection/selection/Single/read/SecondaryPreferred.yml +19 -0
- data/spec/support/server_selection/selection/Unknown/read/SecondaryPreferred.yml +11 -0
- data/spec/support/server_selection.rb +157 -0
- data/spec/support/server_selection_rtt.rb +41 -0
- data/spec/support/shared/bulk_write.rb +535 -0
- data/spec/support/shared/cursor.rb +38 -0
- data/spec/support/shared/operation.rb +77 -0
- data/spec/support/shared/protocol.rb +31 -0
- data/spec/support/shared/server_selector.rb +111 -0
- data/spec/support/shared/socket.rb +82 -0
- data/spec/support/travis.rb +14 -0
- data.tar.gz.sig +2 -3
- metadata +583 -186
- metadata.gz.sig +0 -0
- data/VERSION +0 -1
- data/lib/mongo/bulk_write_collection_view.rb +0 -387
- data/lib/mongo/collection_writer.rb +0 -364
- data/lib/mongo/connection/node.rb +0 -249
- data/lib/mongo/connection/pool.rb +0 -340
- data/lib/mongo/connection/pool_manager.rb +0 -320
- data/lib/mongo/connection/sharding_pool_manager.rb +0 -67
- data/lib/mongo/connection/socket/ssl_socket.rb +0 -95
- data/lib/mongo/connection/socket/tcp_socket.rb +0 -87
- data/lib/mongo/connection/socket/unix_socket.rb +0 -39
- data/lib/mongo/db.rb +0 -808
- data/lib/mongo/exception.rb +0 -145
- data/lib/mongo/functional/authentication.rb +0 -455
- data/lib/mongo/functional/logging.rb +0 -85
- data/lib/mongo/functional/read_preference.rb +0 -183
- data/lib/mongo/functional/scram.rb +0 -556
- data/lib/mongo/functional/uri_parser.rb +0 -409
- data/lib/mongo/functional/write_concern.rb +0 -66
- data/lib/mongo/gridfs/grid.rb +0 -112
- data/lib/mongo/gridfs/grid_ext.rb +0 -53
- data/lib/mongo/gridfs/grid_file_system.rb +0 -163
- data/lib/mongo/gridfs/grid_io.rb +0 -484
- data/lib/mongo/legacy.rb +0 -140
- data/lib/mongo/mongo_client.rb +0 -697
- data/lib/mongo/mongo_replica_set_client.rb +0 -535
- data/lib/mongo/mongo_sharded_client.rb +0 -159
- data/lib/mongo/networking.rb +0 -372
- data/lib/mongo/utils/conversions.rb +0 -110
- data/lib/mongo/utils/core_ext.rb +0 -70
- data/lib/mongo/utils/server_version.rb +0 -69
- data/lib/mongo/utils/support.rb +0 -80
- data/test/functional/authentication_test.rb +0 -39
- data/test/functional/bulk_api_stress_test.rb +0 -133
- data/test/functional/bulk_write_collection_view_test.rb +0 -1198
- data/test/functional/client_test.rb +0 -627
- data/test/functional/collection_test.rb +0 -2175
- data/test/functional/collection_writer_test.rb +0 -83
- data/test/functional/conversions_test.rb +0 -163
- data/test/functional/cursor_fail_test.rb +0 -57
- data/test/functional/cursor_message_test.rb +0 -56
- data/test/functional/cursor_test.rb +0 -683
- data/test/functional/db_api_test.rb +0 -835
- data/test/functional/db_test.rb +0 -348
- data/test/functional/grid_file_system_test.rb +0 -285
- data/test/functional/grid_io_test.rb +0 -252
- data/test/functional/grid_test.rb +0 -273
- data/test/functional/pool_test.rb +0 -136
- data/test/functional/safe_test.rb +0 -98
- data/test/functional/support_test.rb +0 -62
- data/test/functional/timeout_test.rb +0 -60
- data/test/functional/uri_test.rb +0 -446
- data/test/functional/write_concern_test.rb +0 -118
- data/test/helpers/general.rb +0 -50
- data/test/helpers/test_unit.rb +0 -476
- data/test/replica_set/authentication_test.rb +0 -37
- data/test/replica_set/basic_test.rb +0 -189
- data/test/replica_set/client_test.rb +0 -393
- data/test/replica_set/connection_test.rb +0 -138
- data/test/replica_set/count_test.rb +0 -66
- data/test/replica_set/cursor_test.rb +0 -220
- data/test/replica_set/insert_test.rb +0 -157
- data/test/replica_set/max_values_test.rb +0 -151
- data/test/replica_set/pinning_test.rb +0 -105
- data/test/replica_set/query_test.rb +0 -73
- data/test/replica_set/read_preference_test.rb +0 -219
- data/test/replica_set/refresh_test.rb +0 -211
- data/test/replica_set/replication_ack_test.rb +0 -95
- data/test/sharded_cluster/basic_test.rb +0 -203
- data/test/shared/authentication/basic_auth_shared.rb +0 -260
- data/test/shared/authentication/bulk_api_auth_shared.rb +0 -249
- data/test/shared/authentication/gssapi_shared.rb +0 -176
- data/test/shared/authentication/sasl_plain_shared.rb +0 -96
- data/test/shared/authentication/scram_shared.rb +0 -92
- data/test/shared/ssl_shared.rb +0 -235
- data/test/test_helper.rb +0 -61
- data/test/threading/basic_test.rb +0 -120
- data/test/tools/mongo_config.rb +0 -708
- data/test/tools/mongo_config_test.rb +0 -160
- data/test/unit/client_test.rb +0 -381
- data/test/unit/collection_test.rb +0 -166
- data/test/unit/connection_test.rb +0 -335
- data/test/unit/cursor_test.rb +0 -307
- data/test/unit/db_test.rb +0 -136
- data/test/unit/grid_test.rb +0 -76
- data/test/unit/mongo_sharded_client_test.rb +0 -48
- data/test/unit/node_test.rb +0 -93
- data/test/unit/pool_manager_test.rb +0 -111
- data/test/unit/read_pref_test.rb +0 -406
- data/test/unit/read_test.rb +0 -159
- data/test/unit/safe_test.rb +0 -158
- data/test/unit/sharding_pool_manager_test.rb +0 -84
- data/test/unit/write_concern_test.rb +0 -175
@@ -0,0 +1,91 @@
|
|
1
|
+
# Copyright (C) 2014-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
|
+
|
17
|
+
module ServerSelector
|
18
|
+
|
19
|
+
# Encapsulates specifications for selecting secondary servers given a list
|
20
|
+
# of candidates.
|
21
|
+
#
|
22
|
+
# @since 2.0.0
|
23
|
+
class Secondary
|
24
|
+
include Selectable
|
25
|
+
|
26
|
+
# Get the name of the server mode type.
|
27
|
+
#
|
28
|
+
# @example Get the name of the server mode for this preference.
|
29
|
+
# preference.name
|
30
|
+
#
|
31
|
+
# @return [ Symbol ] :secondary
|
32
|
+
#
|
33
|
+
# @since 2.0.0
|
34
|
+
def name
|
35
|
+
:secondary
|
36
|
+
end
|
37
|
+
|
38
|
+
# Whether the slaveOk bit should be set on wire protocol messages.
|
39
|
+
# I.e. whether the operation can be performed on a secondary server.
|
40
|
+
#
|
41
|
+
# @return [ true ] true
|
42
|
+
#
|
43
|
+
# @since 2.0.0
|
44
|
+
def slave_ok?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
# Whether tag sets are allowed to be defined for this server preference.
|
49
|
+
#
|
50
|
+
# @return [ true ] true
|
51
|
+
#
|
52
|
+
# @since 2.0.0
|
53
|
+
def tags_allowed?
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convert this server preference definition into a format appropriate
|
58
|
+
# for a mongos server.
|
59
|
+
#
|
60
|
+
# @example Convert this server preference definition into a format
|
61
|
+
# for mongos.
|
62
|
+
# preference = Mongo::ServerSelector::Secondary.new
|
63
|
+
# preference.to_mongos
|
64
|
+
#
|
65
|
+
# @return [ Hash ] The server preference formatted for a mongos server.
|
66
|
+
#
|
67
|
+
# @since 2.0.0
|
68
|
+
def to_mongos
|
69
|
+
preference = { :mode => 'secondary' }
|
70
|
+
preference.merge!({ :tags => tag_sets }) unless tag_sets.empty?
|
71
|
+
preference
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# Select the secondary servers taking into account any defined tag sets and
|
77
|
+
# local threshold between the nearest secondary and other secondaries.
|
78
|
+
#
|
79
|
+
# @example Select secondary servers given a list of candidates.
|
80
|
+
# preference = Mongo::ServerSelector::Secondary.new
|
81
|
+
# preference.select([candidate_1, candidate_2])
|
82
|
+
#
|
83
|
+
# @return [ Array ] The secondary servers from the list of candidates.
|
84
|
+
#
|
85
|
+
# @since 2.0.0
|
86
|
+
def select(candidates)
|
87
|
+
near_servers(secondaries(candidates))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# Copyright (C) 2014-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
|
+
|
17
|
+
module ServerSelector
|
18
|
+
|
19
|
+
# Encapsulates specifications for selecting servers, with
|
20
|
+
# secondaries preferred, given a list of candidates.
|
21
|
+
#
|
22
|
+
# @since 2.0.0
|
23
|
+
class SecondaryPreferred
|
24
|
+
include Selectable
|
25
|
+
|
26
|
+
# Get the name of the server mode type.
|
27
|
+
#
|
28
|
+
# @example Get the name of the server mode for this preference.
|
29
|
+
# preference.name
|
30
|
+
#
|
31
|
+
# @return [ Symbol ] :secondary_preferred
|
32
|
+
#
|
33
|
+
# @since 2.0.0
|
34
|
+
def name
|
35
|
+
:secondary_preferred
|
36
|
+
end
|
37
|
+
|
38
|
+
# Whether the slaveOk bit should be set on wire protocol messages.
|
39
|
+
# I.e. whether the operation can be performed on a secondary server.
|
40
|
+
#
|
41
|
+
# @return [ true ] true
|
42
|
+
#
|
43
|
+
# @since 2.0.0
|
44
|
+
def slave_ok?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
# Whether tag sets are allowed to be defined for this server preference.
|
49
|
+
#
|
50
|
+
# @return [ true ] true
|
51
|
+
#
|
52
|
+
# @since 2.0.0
|
53
|
+
def tags_allowed?
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convert this server preference definition into a format appropriate
|
58
|
+
# for a mongos server.
|
59
|
+
# Note that the server preference is not sent to mongos as part of the query
|
60
|
+
# selector if there are no tag sets, for maximum backwards compatibility.
|
61
|
+
#
|
62
|
+
# @example Convert this server preference definition into a format
|
63
|
+
# for mongos.
|
64
|
+
# preference = Mongo::ServerSelector::SecondaryPreferred.new
|
65
|
+
# preference.to_mongos
|
66
|
+
#
|
67
|
+
# @return [ Hash ] The server preference formatted for a mongos server.
|
68
|
+
#
|
69
|
+
# @since 2.0.0
|
70
|
+
def to_mongos
|
71
|
+
return nil if tag_sets.empty?
|
72
|
+
preference = { mode: 'secondaryPreferred' }
|
73
|
+
preference.merge!({ tags: tag_sets })
|
74
|
+
preference
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# Select servers taking into account any defined tag sets and
|
80
|
+
# local threshold, with secondaries.
|
81
|
+
#
|
82
|
+
# @example Select servers given a list of candidates,
|
83
|
+
# with secondaries preferred.
|
84
|
+
# preference = Mongo::ServerSelector::SecondaryPreferred.new
|
85
|
+
# preference.select([candidate_1, candidate_2])
|
86
|
+
#
|
87
|
+
# @return [ Array ] A list of servers matching tag sets and acceptable
|
88
|
+
# latency with secondaries preferred.
|
89
|
+
#
|
90
|
+
# @since 2.0.0
|
91
|
+
def select(candidates)
|
92
|
+
near_servers(secondaries(candidates)) + primary(candidates)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# Copyright (C) 2014-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
|
+
module ServerSelector
|
17
|
+
|
18
|
+
# Provides common behavior for filtering a list of servers by server mode or tag set.
|
19
|
+
#
|
20
|
+
# @since 2.0.0
|
21
|
+
module Selectable
|
22
|
+
|
23
|
+
# The max latency in seconds between the closest server and other servers
|
24
|
+
# considered for selection.
|
25
|
+
#
|
26
|
+
# @since 2.0.0
|
27
|
+
LOCAL_THRESHOLD = 0.015.freeze
|
28
|
+
|
29
|
+
# How long to block for server selection before throwing an exception.
|
30
|
+
#
|
31
|
+
# @since 2.0.0
|
32
|
+
SERVER_SELECTION_TIMEOUT = 30.freeze
|
33
|
+
|
34
|
+
# @return [ Hash ] options The options.
|
35
|
+
attr_reader :options
|
36
|
+
|
37
|
+
# @return [ Array ] tag_sets The tag sets used to select servers.
|
38
|
+
attr_reader :tag_sets
|
39
|
+
|
40
|
+
# Check equality of two server selector.
|
41
|
+
#
|
42
|
+
# @example Check server selector equality.
|
43
|
+
# preference == other
|
44
|
+
#
|
45
|
+
# @param [ Object ] other The other preference.
|
46
|
+
#
|
47
|
+
# @return [ true, false ] Whether the objects are equal.
|
48
|
+
#
|
49
|
+
# @since 2.0.0
|
50
|
+
def ==(other)
|
51
|
+
name == other.name && tag_sets == other.tag_sets
|
52
|
+
end
|
53
|
+
|
54
|
+
# Initialize the server selector.
|
55
|
+
#
|
56
|
+
# @example Initialize the preference with tag sets.
|
57
|
+
# Mongo::ServerSelector::Secondary.new([{ 'tag' => 'set' }])
|
58
|
+
#
|
59
|
+
# @example Initialize the preference with no options.
|
60
|
+
# Mongo::ServerSelector::Secondary.new
|
61
|
+
#
|
62
|
+
# @param [ Array ] tag_sets The tag sets used to select servers.
|
63
|
+
#
|
64
|
+
# @todo: document specific error
|
65
|
+
# @raise [ Exception ] If tag sets are specified but not allowed.
|
66
|
+
#
|
67
|
+
# @since 2.0.0
|
68
|
+
def initialize(tag_sets = [], options = {})
|
69
|
+
if !tag_sets.all? { |set| set.empty? } && !tags_allowed?
|
70
|
+
raise ServerSelector::InvalidServerPreference.new(name)
|
71
|
+
end
|
72
|
+
@tag_sets = tag_sets
|
73
|
+
@options = options
|
74
|
+
end
|
75
|
+
|
76
|
+
# Select a server from eligible candidates.
|
77
|
+
#
|
78
|
+
# @example Select a server from the cluster.
|
79
|
+
# selector.select_server(cluster)
|
80
|
+
#
|
81
|
+
# @param [ Mongo::Cluster ] cluster The cluster from which to select an eligible server.
|
82
|
+
#
|
83
|
+
# @return [ Mongo::Server ] A server matching the server preference.
|
84
|
+
#
|
85
|
+
# @since 2.0.0
|
86
|
+
def select_server(cluster)
|
87
|
+
deadline = Time.now + server_selection_timeout
|
88
|
+
while (deadline - Time.now) > 0
|
89
|
+
if cluster.standalone?
|
90
|
+
servers = cluster.servers
|
91
|
+
elsif cluster.sharded?
|
92
|
+
servers = near_servers(cluster.servers)
|
93
|
+
else
|
94
|
+
servers = select(cluster.servers)
|
95
|
+
end
|
96
|
+
return servers.first if servers && !servers.compact.empty?
|
97
|
+
cluster.scan!
|
98
|
+
end
|
99
|
+
raise NoServerAvailable.new(self)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Get the timeout for server selection.
|
103
|
+
#
|
104
|
+
# @example Get the server selection timeout, in seconds.
|
105
|
+
# selector.server_selection_timeout
|
106
|
+
#
|
107
|
+
# @return [ Float ] The timeout.
|
108
|
+
#
|
109
|
+
# @since 2.0.0
|
110
|
+
def server_selection_timeout
|
111
|
+
@server_selection_timeout ||=
|
112
|
+
(options[:server_selection_timeout] || SERVER_SELECTION_TIMEOUT)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Get the local threshold boundary for nearest selection in seconds.
|
116
|
+
#
|
117
|
+
# @example Get the local threshold.
|
118
|
+
# selector.local_threshold
|
119
|
+
#
|
120
|
+
# @return [ Float ] The local threshold.
|
121
|
+
#
|
122
|
+
# @since 2.0.0
|
123
|
+
def local_threshold
|
124
|
+
@local_threshold ||= (options[:local_threshold] || LOCAL_THRESHOLD)
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
# Select the primary from a list of provided candidates.
|
130
|
+
#
|
131
|
+
# @param [ Array ] candidates List of candidate servers to select the
|
132
|
+
# primary from.
|
133
|
+
#
|
134
|
+
# @return [ Array ] The primary.
|
135
|
+
#
|
136
|
+
# @since 2.0.0
|
137
|
+
def primary(candidates)
|
138
|
+
candidates.select do |server|
|
139
|
+
server.primary? || server.standalone?
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Select the secondaries from a list of provided candidates.
|
144
|
+
#
|
145
|
+
# @param [ Array ] candidates List of candidate servers to select the
|
146
|
+
# secondaries from.
|
147
|
+
#
|
148
|
+
# @return [ Array ] The secondary servers.
|
149
|
+
#
|
150
|
+
# @since 2.0.0
|
151
|
+
def secondaries(candidates)
|
152
|
+
matching_servers = candidates.select(&:secondary?)
|
153
|
+
matching_servers = match_tag_sets(matching_servers) unless tag_sets.empty?
|
154
|
+
matching_servers
|
155
|
+
end
|
156
|
+
|
157
|
+
# Select the near servers from a list of provided candidates, taking the
|
158
|
+
# local threshold into account.
|
159
|
+
#
|
160
|
+
# @param [ Array ] candidates List of candidate servers to select the
|
161
|
+
# near servers from.
|
162
|
+
#
|
163
|
+
# @return [ Array ] The near servers.
|
164
|
+
#
|
165
|
+
# @since 2.0.0
|
166
|
+
def near_servers(candidates = [])
|
167
|
+
return candidates if candidates.empty?
|
168
|
+
nearest_server = candidates.min_by(&:average_round_trip_time)
|
169
|
+
threshold = nearest_server.average_round_trip_time + (local_threshold * 1000)
|
170
|
+
candidates.select { |server| server.average_round_trip_time <= threshold }.shuffle!
|
171
|
+
end
|
172
|
+
|
173
|
+
# Select the servers matching the defined tag sets.
|
174
|
+
#
|
175
|
+
# @param [ Array ] candidates List of candidate servers from which those
|
176
|
+
# matching the defined tag sets should be selected.
|
177
|
+
#
|
178
|
+
# @return [ Array ] The servers matching the defined tag sets.
|
179
|
+
#
|
180
|
+
# @since 2.0.0
|
181
|
+
def match_tag_sets(candidates)
|
182
|
+
matches = []
|
183
|
+
tag_sets.find do |tag_set|
|
184
|
+
matches = candidates.select { |server| server.matches_tag_set?(tag_set) }
|
185
|
+
!matches.empty?
|
186
|
+
end
|
187
|
+
matches || []
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# Raised when an invalid server preference is provided.
|
192
|
+
#
|
193
|
+
# @since 2.0.0
|
194
|
+
class InvalidServerPreference < Error
|
195
|
+
|
196
|
+
# Instantiate the new exception.
|
197
|
+
#
|
198
|
+
# @example Instantiate the exception.
|
199
|
+
# Mongo::ServerSelector::InvalidServerPreference.new
|
200
|
+
#
|
201
|
+
# @param [ String ] name The preference name.
|
202
|
+
#
|
203
|
+
# @since 2.0.0
|
204
|
+
def initialize(name)
|
205
|
+
super("This server preference #{name} cannot be combined with tags.")
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Copyright (C) 2014-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/server_selector/selectable'
|
16
|
+
require 'mongo/server_selector/nearest'
|
17
|
+
require 'mongo/server_selector/primary'
|
18
|
+
require 'mongo/server_selector/primary_preferred'
|
19
|
+
require 'mongo/server_selector/secondary'
|
20
|
+
require 'mongo/server_selector/secondary_preferred'
|
21
|
+
|
22
|
+
module Mongo
|
23
|
+
|
24
|
+
# Functionality for getting an object able to select a server, given a preference.
|
25
|
+
#
|
26
|
+
# @since 2.0.0
|
27
|
+
module ServerSelector
|
28
|
+
extend self
|
29
|
+
|
30
|
+
# Hash lookup for the selector classes based off the symbols
|
31
|
+
# provided in configuration.
|
32
|
+
#
|
33
|
+
# @since 2.0.0
|
34
|
+
PREFERENCES = {
|
35
|
+
nearest: Nearest,
|
36
|
+
primary: Primary,
|
37
|
+
primary_preferred: PrimaryPreferred,
|
38
|
+
secondary: Secondary,
|
39
|
+
secondary_preferred: SecondaryPreferred
|
40
|
+
}.freeze
|
41
|
+
|
42
|
+
# Create a server selector object.
|
43
|
+
#
|
44
|
+
# @example Get a server selector object for selecting a secondary with
|
45
|
+
# specific tag sets.
|
46
|
+
# Mongo::ServerSelector.get({ :mode => :secondary, :tag_sets => [{'dc' => 'nyc'}] })
|
47
|
+
#
|
48
|
+
# @param [ Hash ] preference The server preference.
|
49
|
+
# @param [ Hash ] options The preference options.
|
50
|
+
#
|
51
|
+
# @option preference :mode [ Symbol ] The preference mode.
|
52
|
+
# @option preference :tag_sets [ Array<Hash> ] The tag sets.
|
53
|
+
#
|
54
|
+
# @since 2.0.0
|
55
|
+
def get(preference = {}, options = {})
|
56
|
+
PREFERENCES.fetch(preference[:mode] || :primary).new(
|
57
|
+
preference[:tag_sets] || [],
|
58
|
+
options
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Exception raised if there are no servers available matching the preference.
|
63
|
+
#
|
64
|
+
# @since 2.0.0
|
65
|
+
class NoServerAvailable < Error
|
66
|
+
|
67
|
+
# Instantiate the new exception.
|
68
|
+
#
|
69
|
+
# @example Instantiate the exception.
|
70
|
+
# Mongo::ServerSelector::NoServerAvailable.new(server_selector)
|
71
|
+
#
|
72
|
+
# @param [ Hash ] server_selector The server preference that could not be
|
73
|
+
# satisfied.
|
74
|
+
#
|
75
|
+
# @since 2.0.0
|
76
|
+
def initialize(server_selector)
|
77
|
+
super("No server is available matching preference: #{server_selector.inspect}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# Copyright (C) 2014-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 'openssl'
|
16
|
+
|
17
|
+
module Mongo
|
18
|
+
class Socket
|
19
|
+
|
20
|
+
# Wrapper for SSL sockets.
|
21
|
+
#
|
22
|
+
# @since 2.0.0
|
23
|
+
class SSL < Socket
|
24
|
+
include OpenSSL
|
25
|
+
|
26
|
+
# @return [ SSLContext ] context The ssl context.
|
27
|
+
attr_reader :context
|
28
|
+
|
29
|
+
# @return [ String ] host The host to connect to.
|
30
|
+
attr_reader :host
|
31
|
+
|
32
|
+
# @return [ Hash ] The ssl options.
|
33
|
+
attr_reader :options
|
34
|
+
|
35
|
+
# @return [ Integer ] port The port to connect to.
|
36
|
+
attr_reader :port
|
37
|
+
|
38
|
+
# @return [ Float ] timeout The connection timeout.
|
39
|
+
attr_reader :timeout
|
40
|
+
|
41
|
+
# Establishes a socket connection.
|
42
|
+
#
|
43
|
+
# @example Connect the socket.
|
44
|
+
# sock.connect!
|
45
|
+
#
|
46
|
+
# @note This method mutates the object by setting the socket
|
47
|
+
# internally.
|
48
|
+
#
|
49
|
+
# @return [ SSL ] The connected socket instance.
|
50
|
+
#
|
51
|
+
# @since 2.0.0
|
52
|
+
def connect!
|
53
|
+
Timeout.timeout(timeout, Error::SocketTimeoutError) do
|
54
|
+
@tcp_socket.connect(::Socket.pack_sockaddr_in(port, host))
|
55
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
|
56
|
+
@socket.sync_close = true
|
57
|
+
@socket.connect
|
58
|
+
verify_certificate!(@socket)
|
59
|
+
self
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Initializes a new SSL socket.
|
64
|
+
#
|
65
|
+
# @example Create the SSL socket.
|
66
|
+
# SSL.new('::1', 27017, 30)
|
67
|
+
#
|
68
|
+
# @param [ String ] host The hostname or IP address.
|
69
|
+
# @param [ Integer ] port The port number.
|
70
|
+
# @param [ Float ] timeout The socket timeout value.
|
71
|
+
# @param [ Integer ] family The socket family.
|
72
|
+
# @param [ Hash ] options The ssl options.
|
73
|
+
#
|
74
|
+
# @since 2.0.0
|
75
|
+
def initialize(host, port, timeout, family, options = {})
|
76
|
+
@host, @port, @timeout, @options = host, port, timeout, options
|
77
|
+
@context = create_context(options)
|
78
|
+
@family = family
|
79
|
+
@tcp_socket = ::Socket.new(family, SOCK_STREAM, 0)
|
80
|
+
@tcp_socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
|
81
|
+
encoded_timeout = [ timeout, 0 ].pack(TIMEOUT_PACK)
|
82
|
+
@tcp_socket.set_encoding(BSON::BINARY)
|
83
|
+
@tcp_socket.setsockopt(SOL_SOCKET, SO_RCVTIMEO, encoded_timeout)
|
84
|
+
@tcp_socket.setsockopt(SOL_SOCKET, SO_SNDTIMEO, encoded_timeout)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Read a single byte from the socket.
|
88
|
+
#
|
89
|
+
# @example Read a single byte.
|
90
|
+
# socket.readbyte
|
91
|
+
#
|
92
|
+
# @return [ Object ] The read byte.
|
93
|
+
#
|
94
|
+
# @since 2.0.0
|
95
|
+
def readbyte
|
96
|
+
handle_errors { socket.read(1) }
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def create_context(options)
|
102
|
+
context = OpenSSL::SSL::SSLContext.new
|
103
|
+
if options[:ssl_cert]
|
104
|
+
context.cert = OpenSSL::X509::Certificate.new(File.open(options[:ssl_cert]))
|
105
|
+
end
|
106
|
+
if options[:ssl_key]
|
107
|
+
if options[:ssl_key_pass_phrase]
|
108
|
+
context.key = OpenSSL::PKey::RSA.new(File.open(options[:ssl_key]),
|
109
|
+
options[:ssl_key_pass_phrase])
|
110
|
+
else
|
111
|
+
context.key = OpenSSL::PKey::RSA.new(File.open(options[:ssl_key]))
|
112
|
+
end
|
113
|
+
end
|
114
|
+
if options[:ssl_verify] || options[:ssl_ca_cert]
|
115
|
+
context.ca_file = options[:ssl_ca_cert]
|
116
|
+
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
117
|
+
end
|
118
|
+
context
|
119
|
+
end
|
120
|
+
|
121
|
+
def verify_certificate!(socket)
|
122
|
+
if context.verify_mode == OpenSSL::SSL::VERIFY_PEER
|
123
|
+
unless OpenSSL::SSL.verify_certificate_identity(socket.peer_cert, host)
|
124
|
+
raise Error::SocketError, 'SSL handshake failed due to a hostname mismatch.'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Copyright (C) 2014-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 Socket
|
17
|
+
|
18
|
+
# Wrapper for TCP sockets.
|
19
|
+
#
|
20
|
+
# @since 2.0.0
|
21
|
+
class TCP < Socket
|
22
|
+
|
23
|
+
# @return [ String ] host The host to connect to.
|
24
|
+
attr_reader :host
|
25
|
+
|
26
|
+
# @return [ Integer ] port The port to connect to.
|
27
|
+
attr_reader :port
|
28
|
+
|
29
|
+
# @return [ Float ] timeout The connection timeout.
|
30
|
+
attr_reader :timeout
|
31
|
+
|
32
|
+
# Establishes a socket connection.
|
33
|
+
#
|
34
|
+
# @example Connect the socket.
|
35
|
+
# sock.connect!
|
36
|
+
#
|
37
|
+
# @note This method mutates the object by setting the socket
|
38
|
+
# internally.
|
39
|
+
#
|
40
|
+
# @return [ TCP ] The connected socket instance.
|
41
|
+
#
|
42
|
+
# @since 2.0.0
|
43
|
+
def connect!
|
44
|
+
Timeout.timeout(timeout, Error::SocketTimeoutError) do
|
45
|
+
socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
|
46
|
+
socket.connect(::Socket.pack_sockaddr_in(port, host))
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Initializes a new TCP socket.
|
52
|
+
#
|
53
|
+
# @example Create the TCP socket.
|
54
|
+
# TCP.new('::1', 27017, 30)
|
55
|
+
# TCP.new('127.0.0.1', 27017, 30)
|
56
|
+
#
|
57
|
+
# @param [ String ] host The hostname or IP address.
|
58
|
+
# @param [ Integer ] port The port number.
|
59
|
+
# @param [ Float ] timeout The socket timeout value.
|
60
|
+
# @param [ Integer ] family The socket family.
|
61
|
+
#
|
62
|
+
# @since 2.0.0
|
63
|
+
def initialize(host, port, timeout, family)
|
64
|
+
@host, @port, @timeout = host, port, timeout
|
65
|
+
super(family)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|