diff options
13 files changed, 244 insertions, 157 deletions
diff --git a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml index a6da2878e4d..038456931a7 100644 --- a/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml +++ b/buildscripts/resmokeconfig/suites/sharding_last_stable_mongos_and_mixed_shards.yml @@ -6,16 +6,17 @@ selector: # Error format changes. See SERVER-22184. - jstests/sharding/error_propagation.js # New features for v3.4 + - jstests/sharding/add_shard_to_zone.js + - jstests/sharding/max_time_ms_sharded_new_commands.js + - jstests/sharding/movechunk_interrupt_at_primary_stepdown.js + - jstests/sharding/remove_shard_from_zone.js - jstests/sharding/shard_aware_init.js - jstests/sharding/shard_aware_on_add_shard.js - jstests/sharding/shard_aware_on_config_election.js - jstests/sharding/shard_aware_on_set_shard_version.js - jstests/sharding/shard_aware_primary_failover.js - jstests/sharding/shard_identity_config_update.js - - jstests/sharding/add_shard_to_zone.js - - jstests/sharding/remove_shard_from_zone.js - jstests/sharding/update_zone_key_range.js - - jstests/sharding/movechunk_interrupt_at_primary_stepdown.js # Doesn't use ShardingTest so won't actually be run in a mixed version configuration - jstests/sharding/config_version_rollback.js # TODO Assumes mongod and mongos handle read on view. Enable when 3.4 becomes 'last-stable'. diff --git a/jstests/sharding/max_time_ms_sharded.js b/jstests/sharding/max_time_ms_sharded.js index b551826ddfe..33121e61712 100644 --- a/jstests/sharding/max_time_ms_sharded.js +++ b/jstests/sharding/max_time_ms_sharded.js @@ -17,8 +17,7 @@ var res; // Helper function to configure "maxTimeAlwaysTimeOut" fail point on shards, which forces mongod - // to - // throw if it receives an operation with a max time. See fail point declaration for complete + // to throw if it receives an operation with a max time. See fail point declaration for complete // description. var configureMaxTimeAlwaysTimeOut = function(mode) { assert.commandWorked(shards[0].getDB("admin").runCommand( @@ -28,8 +27,7 @@ }; // Helper function to configure "maxTimeAlwaysTimeOut" fail point on shards, which prohibits - // mongod - // from enforcing time limits. See fail point declaration for complete description. + // mongod from enforcing time limits. See fail point declaration for complete description. var configureMaxTimeNeverTimeOut = function(mode) { assert.commandWorked(shards[0].getDB("admin").runCommand( {configureFailPoint: "maxTimeNeverTimeOut", mode: mode})); @@ -221,8 +219,6 @@ }), "expected moveChunk to not hit time limit in mongod"); - // TODO Test additional commmands. - st.stop(); })(); diff --git a/jstests/sharding/max_time_ms_sharded_new_commands.js b/jstests/sharding/max_time_ms_sharded_new_commands.js new file mode 100644 index 00000000000..373b4c5591d --- /dev/null +++ b/jstests/sharding/max_time_ms_sharded_new_commands.js @@ -0,0 +1,40 @@ +// Continuation of max_time_ms.js, but only contains commands which are not present in a previous +// version +(function() { + 'use strict'; + + var st = new ShardingTest({shards: 2}); + + var mongos = st.s0; + var shards = [st.shard0, st.shard1]; + var coll = mongos.getCollection("foo.bar"); + var admin = mongos.getDB("admin"); + var cursor; + var res; + + // Helper function to configure "maxTimeAlwaysTimeOut" fail point on shards, which forces mongod + // to throw if it receives an operation with a max time. See fail point declaration for + // complete description. + var configureMaxTimeAlwaysTimeOut = function(mode) { + assert.commandWorked(shards[0].getDB("admin").runCommand( + {configureFailPoint: "maxTimeAlwaysTimeOut", mode: mode})); + assert.commandWorked(shards[1].getDB("admin").runCommand( + {configureFailPoint: "maxTimeAlwaysTimeOut", mode: mode})); + }; + + // Positive test for "setFeatureCompatibilityVersion" + configureMaxTimeAlwaysTimeOut("alwaysOn"); + assert.commandFailedWithCode( + admin.runCommand({setFeatureCompatibilityVersion: '3.2', maxTimeMS: 1000 * 60 * 60 * 24}), + ErrorCodes.ExceededTimeLimit, + "expected setFeatureCompatibilityVersion to fail due to maxTimeAlwaysTimeOut fail point"); + + // Negative test for "setFeatureCompatibilityVersion" + configureMaxTimeAlwaysTimeOut("off"); + assert.commandWorked( + admin.runCommand({setFeatureCompatibilityVersion: '3.2', maxTimeMS: 1000 * 60 * 60 * 24}), + "expected setFeatureCompatibilityVersion to not hit time limit in mongod"); + + st.stop(); + +})(); diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index 868484de229..cc535fc4fe5 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -31,6 +31,7 @@ env.Library( "connection_status.cpp", "copydb_common.cpp", "fail_point_cmd.cpp", + "feature_compatibility_version_command_parser.cpp", "find_and_modify_common.cpp", "hashcmd.cpp", "isself.cpp", diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp index dcf4ae4c652..2e38906b685 100644 --- a/src/mongo/db/commands/feature_compatibility_version.cpp +++ b/src/mongo/db/commands/feature_compatibility_version.cpp @@ -34,6 +34,7 @@ #include "mongo/base/status.h" #include "mongo/db/catalog/collection_options.h" +#include "mongo/db/commands/feature_compatibility_version_command_parser.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop.h" #include "mongo/db/db_raii.h" @@ -58,8 +59,6 @@ constexpr StringData FeatureCompatibilityVersion::kCollection; constexpr StringData FeatureCompatibilityVersion::kCommandName; constexpr StringData FeatureCompatibilityVersion::kParameterName; constexpr StringData FeatureCompatibilityVersion::kVersionField; -constexpr StringData FeatureCompatibilityVersion::kVersion34; -constexpr StringData FeatureCompatibilityVersion::kVersion32; namespace { const BSONObj k32IncompatibleIndexSpec = @@ -104,9 +103,9 @@ StringData getFeatureCompatibilityVersionString( ServerGlobalParams::FeatureCompatibility::Version version) { switch (version) { case ServerGlobalParams::FeatureCompatibility::Version::k34: - return FeatureCompatibilityVersion::kVersion34; + return FeatureCompatibilityVersionCommandParser::kVersion34; case ServerGlobalParams::FeatureCompatibility::Version::k32: - return FeatureCompatibilityVersion::kVersion32; + return FeatureCompatibilityVersionCommandParser::kVersion32; default: MONGO_UNREACHABLE; } @@ -139,9 +138,9 @@ StatusWith<ServerGlobalParams::FeatureCompatibility::Version> FeatureCompatibili << featureCompatibilityVersionDoc << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility."); } - if (elem.String() == FeatureCompatibilityVersion::kVersion34) { + if (elem.String() == FeatureCompatibilityVersionCommandParser::kVersion34) { version = ServerGlobalParams::FeatureCompatibility::Version::k34; - } else if (elem.String() == FeatureCompatibilityVersion::kVersion32) { + } else if (elem.String() == FeatureCompatibilityVersionCommandParser::kVersion32) { version = ServerGlobalParams::FeatureCompatibility::Version::k32; } else { return Status( @@ -152,9 +151,9 @@ StatusWith<ServerGlobalParams::FeatureCompatibility::Version> FeatureCompatibili << ", found " << elem.String() << ", expected '" - << FeatureCompatibilityVersion::kVersion34 + << FeatureCompatibilityVersionCommandParser::kVersion34 << "' or '" - << FeatureCompatibilityVersion::kVersion32 + << FeatureCompatibilityVersionCommandParser::kVersion32 << "'. Contents of " << FeatureCompatibilityVersion::kParameterName << " document in " @@ -197,13 +196,13 @@ void FeatureCompatibilityVersion::set(OperationContext* txn, StringData version) uassert(40284, "featureCompatibilityVersion must be '3.4' or '3.2'. See " "http://dochub.mongodb.org/core/3.4-feature-compatibility.", - version == FeatureCompatibilityVersion::kVersion34 || - version == FeatureCompatibilityVersion::kVersion32); + version == FeatureCompatibilityVersionCommandParser::kVersion34 || + version == FeatureCompatibilityVersionCommandParser::kVersion32); DBDirectClient client(txn); NamespaceString nss(FeatureCompatibilityVersion::kCollection); - if (version == FeatureCompatibilityVersion::kVersion34) { + if (version == FeatureCompatibilityVersionCommandParser::kVersion34) { // We build a v=2 index on the "admin.system.version" collection as part of setting the // featureCompatibilityVersion to 3.4. This is a new index version that isn't supported by // versions of MongoDB earlier than 3.4 that will cause 3.2 secondaries to crash when it is @@ -248,7 +247,7 @@ void FeatureCompatibilityVersion::set(OperationContext* txn, StringData version) // We then update the value of the featureCompatibilityVersion server parameter. serverGlobalParams.featureCompatibility.version.store( ServerGlobalParams::FeatureCompatibility::Version::k34); - } else if (version == FeatureCompatibilityVersion::kVersion32) { + } else if (version == FeatureCompatibilityVersionCommandParser::kVersion32) { // We update the featureCompatibilityVersion document stored in the "admin.system.version" // collection. We do this before dropping the v=2 index in order to maintain the invariant // that if the featureCompatibilityVersion is 3.4, then 'k32IncompatibleIndexSpec' index @@ -321,7 +320,7 @@ void FeatureCompatibilityVersion::setIfCleanStartup(OperationContext* txn, nss, BSON("_id" << FeatureCompatibilityVersion::kParameterName << FeatureCompatibilityVersion::kVersionField - << FeatureCompatibilityVersion::kVersion34))); + << FeatureCompatibilityVersionCommandParser::kVersion34))); // We then update the value of the featureCompatibilityVersion server parameter. serverGlobalParams.featureCompatibility.version.store( @@ -347,7 +346,8 @@ void FeatureCompatibilityVersion::onDelete(const BSONObj& doc) { idElement.String() != FeatureCompatibilityVersion::kParameterName) { return; } - log() << "setting featureCompatibilityVersion to " << FeatureCompatibilityVersion::kVersion32; + log() << "setting featureCompatibilityVersion to " + << FeatureCompatibilityVersionCommandParser::kVersion32; serverGlobalParams.featureCompatibility.version.store( ServerGlobalParams::FeatureCompatibility::Version::k32); } diff --git a/src/mongo/db/commands/feature_compatibility_version.h b/src/mongo/db/commands/feature_compatibility_version.h index 2560d08953e..46fa8390bb3 100644 --- a/src/mongo/db/commands/feature_compatibility_version.h +++ b/src/mongo/db/commands/feature_compatibility_version.h @@ -52,8 +52,6 @@ public: static constexpr StringData kCommandName = "setFeatureCompatibilityVersion"_sd; static constexpr StringData kParameterName = "featureCompatibilityVersion"_sd; static constexpr StringData kVersionField = "version"_sd; - static constexpr StringData kVersion34 = "3.4"_sd; - static constexpr StringData kVersion32 = "3.2"_sd; /** * Parses the featureCompatibilityVersion document from admin.system.version, and returns the diff --git a/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp b/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp new file mode 100644 index 00000000000..e8536e88db2 --- /dev/null +++ b/src/mongo/db/commands/feature_compatibility_version_command_parser.cpp @@ -0,0 +1,96 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/db/commands/feature_compatibility_version_command_parser.h" + +#include "mongo/base/status_with.h" +#include "mongo/bson/bsonobj.h" +#include "mongo/db/query/query_request.h" +#include "mongo/util/version.h" + +namespace mongo { + +constexpr StringData FeatureCompatibilityVersionCommandParser::kVersion34; +constexpr StringData FeatureCompatibilityVersionCommandParser::kVersion32; + +StatusWith<std::string> FeatureCompatibilityVersionCommandParser::extractVersionFromCommand( + StringData commandName, const BSONObj& cmdObj) { + if (cmdObj.firstElementFieldName() != commandName) { + return {ErrorCodes::InternalError, + str::stream() << "Expected to find a " << commandName << " command, but found " + << cmdObj}; + } + + const auto versionElem = cmdObj.firstElement(); + + if (versionElem.type() != BSONType::String) { + return {ErrorCodes::TypeMismatch, + str::stream() << "Command argument must be of type " + "String, but was of type " + << typeName(versionElem.type()) + << " in: " + << cmdObj + << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility."}; + } + + // Ensure that the command does not contain any unrecognized parameters + for (const auto& cmdElem : cmdObj) { + if (cmdElem.fieldNameStringData() == commandName || + cmdElem.fieldNameStringData() == QueryRequest::cmdOptionMaxTimeMS) { + continue; + } + + uasserted( + ErrorCodes::InvalidOptions, + str::stream() << "Unrecognized field found " << cmdElem.fieldNameStringData() << " in " + << cmdObj + << ". See http ://dochub.mongodb.org/core/3.4-feature-compatibility."); + } + + const std::string version = versionElem.String(); + + if (version != FeatureCompatibilityVersionCommandParser::kVersion34 && + version != FeatureCompatibilityVersionCommandParser::kVersion32) { + return {ErrorCodes::BadValue, + str::stream() << "Invalid command argument. Expected '" + << FeatureCompatibilityVersionCommandParser::kVersion34 + << "' or '" + << FeatureCompatibilityVersionCommandParser::kVersion32 + << "', found " + << version + << " in: " + << cmdObj + << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility."}; + } + + return version; +} + +} // namespace mongo diff --git a/src/mongo/db/commands/feature_compatibility_version_command_parser.h b/src/mongo/db/commands/feature_compatibility_version_command_parser.h new file mode 100644 index 00000000000..4e17aa94cdc --- /dev/null +++ b/src/mongo/db/commands/feature_compatibility_version_command_parser.h @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2016 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ + +#pragma once + +#include <string> + +#include "mongo/base/string_data.h" + +namespace mongo { + +class BSONObj; +template <typename T> +class StatusWith; + +class FeatureCompatibilityVersionCommandParser { +public: + /** + * Known server release versions. + */ + static constexpr StringData kVersion34 = "3.4"_sd; + static constexpr StringData kVersion32 = "3.2"_sd; + + /** + * Interprets the specified BSON as a command and extracts the desired compatibility version + * from it. + */ + static StatusWith<std::string> extractVersionFromCommand(StringData commandName, + const BSONObj& cmdObj); +}; + +} // namespace mongo diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp index adc00bd7ae5..4d6c7f9867d 100644 --- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp @@ -31,6 +31,7 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" #include "mongo/db/commands/feature_compatibility_version.h" +#include "mongo/db/commands/feature_compatibility_version_command_parser.h" namespace mongo { @@ -86,51 +87,14 @@ public: int options, std::string& errmsg, BSONObjBuilder& result) { + const auto version = uassertStatusOK( + FeatureCompatibilityVersionCommandParser::extractVersionFromCommand(getName(), cmdObj)); - // Validate command. - std::string version; - for (auto&& elem : cmdObj) { - if (elem.fieldNameStringData() == FeatureCompatibilityVersion::kCommandName) { - uassert(ErrorCodes::TypeMismatch, - str::stream() - << FeatureCompatibilityVersion::kCommandName - << " must be of type String, but was of type " - << typeName(elem.type()) - << " in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.", - elem.type() == BSONType::String); - version = elem.String(); - } else { - uasserted(ErrorCodes::FailedToParse, - str::stream() - << "unrecognized field '" - << elem.fieldName() - << "' in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility."); - } - } - - uassert(ErrorCodes::BadValue, - str::stream() << "invalid value for " << FeatureCompatibilityVersion::kCommandName - << ", expected '" - << FeatureCompatibilityVersion::kVersion34 - << "' or '" - << FeatureCompatibilityVersion::kVersion32 - << "', found " - << version - << " in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.", - version == FeatureCompatibilityVersion::kVersion34 || - version == FeatureCompatibilityVersion::kVersion32); - - // Set featureCompatibilityVersion. FeatureCompatibilityVersion::set(txn, version); return true; } + } setFeatureCompatibilityVersionCommand; } // namespace diff --git a/src/mongo/db/s/config/configsvr_control_balancer_command.cpp b/src/mongo/db/s/config/configsvr_control_balancer_command.cpp index 7c269919384..88deff30a9e 100644 --- a/src/mongo/db/s/config/configsvr_control_balancer_command.cpp +++ b/src/mongo/db/s/config/configsvr_control_balancer_command.cpp @@ -78,16 +78,14 @@ public: int options, std::string& errmsg, BSONObjBuilder& result) final { - if (cmdObj.firstElementFieldName() != getName()) { - uasserted(ErrorCodes::InternalError, - str::stream() << "Expected to find a " << getName() << " command, but found " - << cmdObj); - } - - if (serverGlobalParams.clusterRole != ClusterRole::ConfigServer) { - uasserted(ErrorCodes::IllegalOperation, - str::stream() << getName() << " can only be run on config servers"); - } + uassert(ErrorCodes::InternalError, + str::stream() << "Expected to find a " << getName() << " command, but found " + << cmdObj, + cmdObj.firstElementFieldName() == getName()); + + uassert(ErrorCodes::IllegalOperation, + str::stream() << getName() << " can only be run on config servers", + serverGlobalParams.clusterRole == ClusterRole::ConfigServer); _run(txn, &result); diff --git a/src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp b/src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp index d42e9313c54..694cec5f96c 100644 --- a/src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/s/config/configsvr_set_feature_compatibility_version_command.cpp @@ -32,6 +32,7 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" #include "mongo/db/commands/feature_compatibility_version.h" +#include "mongo/db/commands/feature_compatibility_version_command_parser.h" #include "mongo/s/catalog/sharding_catalog_manager.h" #include "mongo/s/grid.h" @@ -86,58 +87,25 @@ public: int options, std::string& errmsg, BSONObjBuilder& result) override { + const auto version = uassertStatusOK( + FeatureCompatibilityVersionCommandParser::extractVersionFromCommand(getName(), cmdObj)); + uassert(ErrorCodes::IllegalOperation, - "_configsvrSetFeatureCompatibilityVersion can only be run on config servers. See " - "http://dochub.mongodb.org/core/3.4-feature-compatibility.", + str::stream() << getName() + << " can only be run on config servers. See " + "http://dochub.mongodb.org/core/3.4-feature-compatibility.", serverGlobalParams.clusterRole == ClusterRole::ConfigServer); - // Validate command. - std::string version; - for (auto&& elem : cmdObj) { - if (elem.fieldNameStringData() == "_configsvrSetFeatureCompatibilityVersion") { - uassert(ErrorCodes::TypeMismatch, - str::stream() - << "_configsvrSetFeatureCompatibilityVersion must be of type " - "String, but was of type " - << typeName(elem.type()) - << " in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.", - elem.type() == BSONType::String); - version = elem.String(); - } else { - uasserted(ErrorCodes::FailedToParse, - str::stream() - << "unrecognized field '" - << elem.fieldName() - << "' in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility."); - } - } - - uassert(ErrorCodes::BadValue, - str::stream() - << "invalid value for _configsvrSetFeatureCompatibilityVersion, expected '" - << FeatureCompatibilityVersion::kVersion34 - << "' or '" - << FeatureCompatibilityVersion::kVersion32 - << "', found " - << version - << " in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.", - version == FeatureCompatibilityVersion::kVersion34 || - version == FeatureCompatibilityVersion::kVersion32); - // Forward to all shards. uassertStatusOK( Grid::get(txn)->catalogManager()->setFeatureCompatibilityVersionOnShards(txn, version)); // On success, set featureCompatibilityVersion on self. FeatureCompatibilityVersion::set(txn, version); + return true; } + } configsvrSetFeatureCompatibilityVersionCmd; } // namespace diff --git a/src/mongo/s/catalog/sharding_catalog_manager_impl.cpp b/src/mongo/s/catalog/sharding_catalog_manager_impl.cpp index be41e606f76..640c2d9bdcf 100644 --- a/src/mongo/s/catalog/sharding_catalog_manager_impl.cpp +++ b/src/mongo/s/catalog/sharding_catalog_manager_impl.cpp @@ -45,6 +45,7 @@ #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/commands/feature_compatibility_version.h" +#include "mongo/db/commands/feature_compatibility_version_command_parser.h" #include "mongo/db/db_raii.h" #include "mongo/db/dbdirectclient.h" #include "mongo/db/namespace_string.h" @@ -844,7 +845,7 @@ StatusWith<string> ShardingCatalogManagerImpl::addShard( targeter.get(), "admin", BSON(FeatureCompatibilityVersion::kCommandName - << FeatureCompatibilityVersion::kVersion34)); + << FeatureCompatibilityVersionCommandParser::kVersion34)); if (!versionResponse.isOK()) { return versionResponse.getStatus(); } diff --git a/src/mongo/s/commands/cluster_set_feature_compatibility_version_cmd.cpp b/src/mongo/s/commands/cluster_set_feature_compatibility_version_cmd.cpp index 641e16dd31e..54a6d9d9bb7 100644 --- a/src/mongo/s/commands/cluster_set_feature_compatibility_version_cmd.cpp +++ b/src/mongo/s/commands/cluster_set_feature_compatibility_version_cmd.cpp @@ -30,6 +30,7 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" +#include "mongo/db/commands/feature_compatibility_version_command_parser.h" #include "mongo/s/client/shard.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/grid.h" @@ -88,56 +89,22 @@ public: int options, std::string& errmsg, BSONObjBuilder& result) { - - // Validate command. - std::string version; - for (auto&& elem : cmdObj) { - if (elem.fieldNameStringData() == "setFeatureCompatibilityVersion") { - uassert( - ErrorCodes::TypeMismatch, - str::stream() - << "setFeatureCompatibilityVersion must be of type String, but was of type " - << typeName(elem.type()) - << " in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.", - elem.type() == BSONType::String); - version = elem.String(); - } else if (elem.fieldNameStringData() == "maxTimeMS") { - continue; - } else { - uasserted(ErrorCodes::FailedToParse, - str::stream() - << "unrecognized field '" - << elem.fieldName() - << "' in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility."); - } - } - - uassert(ErrorCodes::BadValue, - str::stream() << "invalid value for setFeatureCompatibilityVersion, expected '3.4' " - "or '3.2', found " - << version - << " in: " - << cmdObj - << ". See http://dochub.mongodb.org/core/3.4-feature-compatibility.", - version == "3.4" || version == "3.2"); + const auto version = uassertStatusOK( + FeatureCompatibilityVersionCommandParser::extractVersionFromCommand(getName(), cmdObj)); // Forward to config shard, which will forward to all shards. auto configShard = Grid::get(txn)->shardRegistry()->getConfigShard(); - auto response = configShard->runCommandWithFixedRetryAttempts( + auto response = uassertStatusOK(configShard->runCommandWithFixedRetryAttempts( txn, ReadPreferenceSetting{ReadPreference::PrimaryOnly}, dbname, BSON("_configsvrSetFeatureCompatibilityVersion" << version), - Shard::RetryPolicy::kIdempotent); - uassertStatusOK(response); - uassertStatusOK(response.getValue().commandStatus); + Shard::RetryPolicy::kIdempotent)); + uassertStatusOK(response.commandStatus); return true; } + } clusterSetFeatureCompatibilityVersionCmd; } // namespace |