diff options
-rw-r--r-- | src/mongo/db/s/config/configsvr_create_collection_command.cpp | 108 | ||||
-rw-r--r-- | src/mongo/db/s/config/configsvr_create_database_command.cpp | 106 | ||||
-rw-r--r-- | src/mongo/db/s/implicit_create_collection.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/s/implicit_create_collection_test.cpp | 3 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_commands_helpers.cpp | 6 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_create_cmd.cpp | 6 | ||||
-rw-r--r-- | src/mongo/s/request_types/create_collection.idl | 11 | ||||
-rw-r--r-- | src/mongo/s/request_types/create_database.idl | 11 |
8 files changed, 116 insertions, 143 deletions
diff --git a/src/mongo/db/s/config/configsvr_create_collection_command.cpp b/src/mongo/db/s/config/configsvr_create_collection_command.cpp index 19c462adc02..f4f99fa1ab8 100644 --- a/src/mongo/db/s/config/configsvr_create_collection_command.cpp +++ b/src/mongo/db/s/config/configsvr_create_collection_command.cpp @@ -45,91 +45,75 @@ #include "mongo/util/log.h" namespace mongo { - -using std::shared_ptr; -using std::set; -using std::string; - namespace { /** * Internal sharding command run on config servers to create a new collection with unassigned shard * key. Call with { _configsvrCreateCollection: <string collName>, <other create options ...> } */ -class ConfigSvrCreateCollectionCommand : public BasicCommand { +class ConfigSvrCreateCollectionCommand final + : public TypedCommand<ConfigSvrCreateCollectionCommand> { public: - ConfigSvrCreateCollectionCommand() : BasicCommand("_configsvrCreateCollection") {} - - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return AllowedOnSecondary::kNever; - } - - bool adminOnly() const override { - return true; - } - - bool supportsWriteConcern(const BSONObj& cmd) const override { - return true; - } + using Request = ConfigsvrCreateCollection; - std::string help() const override { - return "Internal command, which is exported by the sharding config server. Do not call " - "directly. Create a collection."; - } + class Invocation final : public InvocationBase { + public: + using InvocationBase::InvocationBase; - Status checkAuthForCommand(Client* client, - const std::string& dbname, - const BSONObj& cmdObj) const override { - if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource( - ResourcePattern::forClusterResource(), ActionType::internal)) { - return Status(ErrorCodes::Unauthorized, "Unauthorized"); - } + void typedRun(OperationContext* opCtx) { + uassert(ErrorCodes::IllegalOperation, + "_configsvrCreateCollection can only be run on config servers", + serverGlobalParams.clusterRole == ClusterRole::ConfigServer); + uassert(ErrorCodes::InvalidOptions, + str::stream() << "createCollection must be called with majority writeConcern", + opCtx->getWriteConcern().wMode == WriteConcernOptions::kMajority); - return Status::OK(); - } + CollectionOptions options; + if (auto requestOptions = request().getOptions()) { + uassertStatusOK(options.parse(*requestOptions)); + } - std::string parseNs(const std::string& dbname, const BSONObj& cmdObj) const override { - return CommandHelpers::parseNsFullyQualified(cmdObj); - } + auto const catalogClient = Grid::get(opCtx)->catalogClient(); - bool run(OperationContext* opCtx, - const std::string& dbname_unused, - const BSONObj& cmdObj, - BSONObjBuilder& result) override { + auto dbDistLock = uassertStatusOK(catalogClient->getDistLockManager()->lock( + opCtx, ns().db(), "createCollection", DistLockManager::kDefaultLockTimeout)); + auto collDistLock = uassertStatusOK(catalogClient->getDistLockManager()->lock( + opCtx, ns().ns(), "createCollection", DistLockManager::kDefaultLockTimeout)); - if (serverGlobalParams.clusterRole != ClusterRole::ConfigServer) { - return CommandHelpers::appendCommandStatus( - result, - Status(ErrorCodes::IllegalOperation, - "_configsvrCreateCollection can only be run on config servers")); + ShardingCatalogManager::get(opCtx)->createCollection(opCtx, ns(), options); } - uassert(ErrorCodes::InvalidOptions, - str::stream() << "createCollection must be called with majority writeConcern, got " - << cmdObj, - opCtx->getWriteConcern().wMode == WriteConcernOptions::kMajority); - - auto createCmd = ConfigsvrCreateCollection::parse( - IDLParserErrorContext("ConfigsvrCreateCollection"), cmdObj); - - CollectionOptions options; - if (auto requestOptions = createCmd.getOptions()) { - uassertStatusOK(options.parse(*requestOptions)); + private: + NamespaceString ns() const override { + return request().getCommandParameter(); } - auto const catalogClient = Grid::get(opCtx)->catalogClient(); - const NamespaceString nss(parseNs(dbname_unused, cmdObj)); + bool supportsWriteConcern() const override { + return true; + } - auto dbDistLock = uassertStatusOK(catalogClient->getDistLockManager()->lock( - opCtx, nss.db(), "createCollection", DistLockManager::kDefaultLockTimeout)); - auto collDistLock = uassertStatusOK(catalogClient->getDistLockManager()->lock( - opCtx, nss.ns(), "createCollection", DistLockManager::kDefaultLockTimeout)); + void doCheckAuthorization(OperationContext* opCtx) const override { + uassert(ErrorCodes::Unauthorized, + "Unauthorized", + AuthorizationSession::get(opCtx->getClient()) + ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), + ActionType::internal)); + } + }; - ShardingCatalogManager::get(opCtx)->createCollection(opCtx, createCmd.getNs(), options); +private: + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kNever; + } + bool adminOnly() const override { return true; } + std::string help() const override { + return "Internal command, which is exported by the sharding config server. Do not call " + "directly. Create a collection."; + } } configsvrCreateCollectionCmd; } // namespace diff --git a/src/mongo/db/s/config/configsvr_create_database_command.cpp b/src/mongo/db/s/config/configsvr_create_database_command.cpp index 15115c96ee5..dfe3ee5b57e 100644 --- a/src/mongo/db/s/config/configsvr_create_database_command.cpp +++ b/src/mongo/db/s/config/configsvr_create_database_command.cpp @@ -48,86 +48,78 @@ #include "mongo/util/scopeguard.h" namespace mongo { - -using std::shared_ptr; -using std::set; -using std::string; - namespace { /** * Internal sharding command run on config servers to create a database. * Call with { _configsvrCreateDatabase: <string dbName> } */ -class ConfigSvrCreateDatabaseCommand : public BasicCommand { +class ConfigSvrCreateDatabaseCommand final : public TypedCommand<ConfigSvrCreateDatabaseCommand> { public: - ConfigSvrCreateDatabaseCommand() : BasicCommand("_configsvrCreateDatabase") {} + using Request = ConfigsvrCreateDatabase; - std::string help() const override { - return "Internal command, which is exported by the sharding config server. Do not call " - "directly. Create a database."; - } + class Invocation final : public InvocationBase { + public: + using InvocationBase::InvocationBase; - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return AllowedOnSecondary::kNever; - } + void typedRun(OperationContext* opCtx) { + uassert(ErrorCodes::IllegalOperation, + "_configsvrCreateDatabase can only be run on config servers", + serverGlobalParams.clusterRole == ClusterRole::ConfigServer); - bool adminOnly() const override { - return true; - } + auto dbname = request().getCommandParameter(); - bool supportsWriteConcern(const BSONObj& cmd) const override { - return true; - } + uassert(ErrorCodes::InvalidNamespace, + str::stream() << "invalid db name specified: " << dbname, + NamespaceString::validDBName(dbname, + NamespaceString::DollarInDbNameBehavior::Allow)); - Status checkAuthForCommand(Client* client, - const std::string& dbname, - const BSONObj& cmdObj) const override { - if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource( - ResourcePattern::forClusterResource(), ActionType::internal)) { - return Status(ErrorCodes::Unauthorized, "Unauthorized"); - } + uassert(ErrorCodes::InvalidOptions, + str::stream() << "createDatabase must be called with majority writeConcern", + opCtx->getWriteConcern().wMode == WriteConcernOptions::kMajority); - return Status::OK(); - } + // Make sure to force update of any stale metadata + ON_BLOCK_EXIT( + [opCtx, dbname] { Grid::get(opCtx)->catalogCache()->purgeDatabase(dbname); }); - bool run(OperationContext* opCtx, - const std::string& dbname_unused, - const BSONObj& cmdObj, - BSONObjBuilder& result) override { - if (serverGlobalParams.clusterRole != ClusterRole::ConfigServer) { - return CommandHelpers::appendCommandStatus( - result, - Status(ErrorCodes::IllegalOperation, - "_configsvrCreateDatabase can only be run on config servers")); - } + auto dbDistLock = + uassertStatusOK(Grid::get(opCtx)->catalogClient()->getDistLockManager()->lock( + opCtx, dbname, "createDatabase", DistLockManager::kDefaultLockTimeout)); - auto createDatabaseRequest = ConfigsvrCreateDatabase::parse( - IDLParserErrorContext("ConfigsvrCreateDatabase"), cmdObj); - const string dbname = createDatabaseRequest.get_configsvrCreateDatabase().toString(); + ShardingCatalogManager::get(opCtx)->createDatabase(opCtx, dbname.toString()); + } - uassert( - ErrorCodes::InvalidNamespace, - str::stream() << "invalid db name specified: " << dbname, - NamespaceString::validDBName(dbname, NamespaceString::DollarInDbNameBehavior::Allow)); + private: + NamespaceString ns() const override { + return NamespaceString(request().getDbName()); + } - uassert(ErrorCodes::InvalidOptions, - str::stream() << "createDatabase must be called with majority writeConcern, got " - << cmdObj, - opCtx->getWriteConcern().wMode == WriteConcernOptions::kMajority); + bool supportsWriteConcern() const override { + return true; + } - // Make sure to force update of any stale metadata - ON_BLOCK_EXIT([opCtx, dbname] { Grid::get(opCtx)->catalogCache()->purgeDatabase(dbname); }); + void doCheckAuthorization(OperationContext* opCtx) const override { + uassert(ErrorCodes::Unauthorized, + "Unauthorized", + AuthorizationSession::get(opCtx->getClient()) + ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), + ActionType::internal)); + } + }; - auto dbDistLock = - uassertStatusOK(Grid::get(opCtx)->catalogClient()->getDistLockManager()->lock( - opCtx, dbname, "createDatabase", DistLockManager::kDefaultLockTimeout)); +private: + std::string help() const override { + return "Internal command, which is exported by the sharding config server. Do not call " + "directly. Create a database."; + } - ShardingCatalogManager::get(opCtx)->createDatabase(opCtx, dbname); + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kNever; + } + bool adminOnly() const override { return true; } - } configsvrCreateDatabaseCmd; } // namespace diff --git a/src/mongo/db/s/implicit_create_collection.cpp b/src/mongo/db/s/implicit_create_collection.cpp index 0ad6e536658..67d069f9253 100644 --- a/src/mongo/db/s/implicit_create_collection.cpp +++ b/src/mongo/db/s/implicit_create_collection.cpp @@ -105,15 +105,15 @@ public: return ex.toStatus(); } - ConfigsvrCreateCollection configCreateCmd; - configCreateCmd.setNs(_ns); + ConfigsvrCreateCollection configCreateCmd(_ns); + configCreateCmd.setDbName(NamespaceString::kAdminDb); auto statusWith = Grid::get(opCtx)->shardRegistry()->getConfigShard()->runCommandWithFixedRetryAttempts( opCtx, ReadPreferenceSetting{ReadPreference::PrimaryOnly}, - "admin", - CommandHelpers::appendMajorityWriteConcern(configCreateCmd.toBSON()), + NamespaceString::kAdminDb.toString(), + CommandHelpers::appendMajorityWriteConcern(configCreateCmd.toBSON({})), Shard::RetryPolicy::kIdempotent); if (!statusWith.isOK()) { diff --git a/src/mongo/db/s/implicit_create_collection_test.cpp b/src/mongo/db/s/implicit_create_collection_test.cpp index 6b30e338c5a..4199d6d324c 100644 --- a/src/mongo/db/s/implicit_create_collection_test.cpp +++ b/src/mongo/db/s/implicit_create_collection_test.cpp @@ -53,8 +53,7 @@ public: ASSERT_EQ(configHost, request.target); auto cmdName = request.cmdObj.firstElement().fieldName(); - - ASSERT_EQ(ConfigsvrCreateCollection::kNsFieldName, cmdName); + ASSERT_EQ(ConfigsvrCreateCollection::kCommandName, cmdName); ASSERT_EQ("admin", request.dbname); ASSERT_EQ(expectedNss.ns(), request.cmdObj.firstElement().String()); diff --git a/src/mongo/s/commands/cluster_commands_helpers.cpp b/src/mongo/s/commands/cluster_commands_helpers.cpp index 7960dc22c11..9bdab8d5df0 100644 --- a/src/mongo/s/commands/cluster_commands_helpers.cpp +++ b/src/mongo/s/commands/cluster_commands_helpers.cpp @@ -501,8 +501,8 @@ bool appendEmptyResultSet(OperationContext* opCtx, StatusWith<CachedDatabaseInfo> createShardDatabase(OperationContext* opCtx, StringData dbName) { auto dbStatus = Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, dbName); if (dbStatus == ErrorCodes::NamespaceNotFound) { - ConfigsvrCreateDatabase configCreateDatabaseRequest; - configCreateDatabaseRequest.set_configsvrCreateDatabase(dbName); + ConfigsvrCreateDatabase configCreateDatabaseRequest(dbName.toString()); + configCreateDatabaseRequest.setDbName(NamespaceString::kAdminDb); auto configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard(); @@ -512,7 +512,7 @@ StatusWith<CachedDatabaseInfo> createShardDatabase(OperationContext* opCtx, Stri ReadPreferenceSetting(ReadPreference::PrimaryOnly), "admin", CommandHelpers::appendMajorityWriteConcern( - configCreateDatabaseRequest.toBSON()), + configCreateDatabaseRequest.toBSON({})), Shard::RetryPolicy::kIdempotent)) .commandStatus; diff --git a/src/mongo/s/commands/cluster_create_cmd.cpp b/src/mongo/s/commands/cluster_create_cmd.cpp index bf8df8a8e54..be8c8f9dd4a 100644 --- a/src/mongo/s/commands/cluster_create_cmd.cpp +++ b/src/mongo/s/commands/cluster_create_cmd.cpp @@ -79,8 +79,8 @@ public: !cmdObj["capped"].trueValue() || cmdObj["size"].isNumber() || cmdObj.hasField("$nExtents")); - ConfigsvrCreateCollection configCreateCmd; - configCreateCmd.setNs(nss); + ConfigsvrCreateCollection configCreateCmd(nss); + configCreateCmd.setDbName(NamespaceString::kAdminDb); { BSONObjIterator cmdIter(cmdObj); @@ -97,7 +97,7 @@ public: ReadPreferenceSetting{ReadPreference::PrimaryOnly}, "admin", CommandHelpers::appendMajorityWriteConcern( - CommandHelpers::appendPassthroughFields(cmdObj, configCreateCmd.toBSON())), + CommandHelpers::appendPassthroughFields(cmdObj, configCreateCmd.toBSON({}))), Shard::RetryPolicy::kIdempotent); uassertStatusOK(Shard::CommandResponse::getEffectiveStatus(response)); diff --git a/src/mongo/s/request_types/create_collection.idl b/src/mongo/s/request_types/create_collection.idl index d7257f1d599..94604b6f512 100644 --- a/src/mongo/s/request_types/create_collection.idl +++ b/src/mongo/s/request_types/create_collection.idl @@ -32,15 +32,14 @@ global: imports: - "mongo/idl/basic_types.idl" -structs: - ConfigsvrCreateCollection: +commands: + _configsvrCreateCollection: + cpp_name: ConfigsvrCreateCollection description: "The internal createCollection command on the config server" strict: false + namespace: type + type: namespacestring fields: - _configsvrCreateCollection: - cpp_name: ns - type: namespacestring - description: "The namespace of the collection to be created." options: type: object optional: true diff --git a/src/mongo/s/request_types/create_database.idl b/src/mongo/s/request_types/create_database.idl index f357a005778..83c42830075 100644 --- a/src/mongo/s/request_types/create_database.idl +++ b/src/mongo/s/request_types/create_database.idl @@ -32,11 +32,10 @@ global: imports: - "mongo/idl/basic_types.idl" -structs: - ConfigsvrCreateDatabase: +commands: + _configsvrCreateDatabase: + cpp_name : ConfigsvrCreateDatabase description: "The internal createDatabase command on the config server" strict: false - fields: - _configsvrCreateDatabase: - type: string - description: "The namespace of the database to be created."
\ No newline at end of file + namespace: type + type: string |