diff options
author | Tommaso Tocci <tommaso.tocci@mongodb.com> | 2022-02-23 16:12:51 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-02-23 18:00:30 +0000 |
commit | 5d99bcaa999e8ca595e36642bdd174abe6986929 (patch) | |
tree | 3a82b72b8a1517851d59207d01cfbef673b6e101 /src/mongo/s | |
parent | 359ecf5230af8f0b9db7fb92fecdf68769d95d0e (diff) | |
download | mongo-5d99bcaa999e8ca595e36642bdd174abe6986929.tar.gz |
SERVER-63897 IDL-ify database type
Diffstat (limited to 'src/mongo/s')
-rw-r--r-- | src/mongo/s/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client_impl.cpp | 43 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client_mock.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_client_test.cpp | 45 | ||||
-rw-r--r-- | src/mongo/s/catalog/sharding_catalog_write_retry_test.cpp | 1 | ||||
-rw-r--r-- | src/mongo/s/catalog/type_database.cpp | 140 | ||||
-rw-r--r-- | src/mongo/s/catalog/type_database.h | 118 | ||||
-rw-r--r-- | src/mongo/s/catalog/type_database.idl | 66 | ||||
-rw-r--r-- | src/mongo/s/catalog/type_database_test.cpp | 32 | ||||
-rw-r--r-- | src/mongo/s/catalog/types_validators.h | 50 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache.h | 2 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache_loader.h | 2 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache_loader_mock.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache_refresh_test.cpp | 5 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache_test_fixture.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/sharding_types.idl | 9 |
18 files changed, 197 insertions, 328 deletions
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript index 570f4ed2301..b4490ae4821 100644 --- a/src/mongo/s/SConscript +++ b/src/mongo/s/SConscript @@ -169,7 +169,7 @@ env.Library( 'catalog/type_collection.cpp', 'catalog/type_collection.idl', 'catalog/type_config_version.cpp', - 'catalog/type_database.cpp', + 'catalog/type_database.idl', 'catalog/type_mongos.cpp', 'catalog/type_shard.cpp', 'catalog/type_tags.cpp', diff --git a/src/mongo/s/catalog/sharding_catalog_client_impl.cpp b/src/mongo/s/catalog/sharding_catalog_client_impl.cpp index 8bab203a42f..e05b3b4a9d0 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_impl.cpp +++ b/src/mongo/s/catalog/sharding_catalog_client_impl.cpp @@ -59,7 +59,7 @@ #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" #include "mongo/s/catalog/type_config_version.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/catalog/type_tags.h" #include "mongo/s/client/shard.h" @@ -361,7 +361,7 @@ std::vector<DatabaseType> ShardingCatalogClientImpl::getAllDBs(OperationContext* auto dbs = uassertStatusOK(_exhaustiveFindOnConfig(opCtx, kConfigReadSelector, readConcern, - DatabaseType::ConfigNS, + NamespaceString::kConfigDatabasesNamespace, BSONObj(), BSONObj(), boost::none)) @@ -370,12 +370,7 @@ std::vector<DatabaseType> ShardingCatalogClientImpl::getAllDBs(OperationContext* std::vector<DatabaseType> databases; databases.reserve(dbs.size()); for (const BSONObj& doc : dbs) { - auto db = uassertStatusOKWithContext( - DatabaseType::fromBSON(doc), stream() << "Failed to parse database document " << doc); - uassertStatusOKWithContext(db.validate(), - stream() << "Failed to validate database document " << doc); - - databases.emplace_back(std::move(db)); + databases.emplace_back(DatabaseType::parse(IDLParserErrorContext("DatabaseType"), doc)); } return databases; @@ -391,8 +386,8 @@ StatusWith<repl::OpTimeWith<DatabaseType>> ShardingCatalogClientImpl::_fetchData auto findStatus = _exhaustiveFindOnConfig(opCtx, readPref, readConcernLevel, - DatabaseType::ConfigNS, - BSON(DatabaseType::name(dbName)), + NamespaceString::kConfigDatabasesNamespace, + BSON(DatabaseType::kNameFieldName << dbName), BSONObj(), boost::none); if (!findStatus.isOK()) { @@ -406,12 +401,13 @@ StatusWith<repl::OpTimeWith<DatabaseType>> ShardingCatalogClientImpl::_fetchData invariant(docsWithOpTime.value.size() == 1); - auto parseStatus = DatabaseType::fromBSON(docsWithOpTime.value.front()); - if (!parseStatus.isOK()) { - return parseStatus.getStatus(); + try { + auto db = DatabaseType::parse(IDLParserErrorContext("DatabaseType"), + docsWithOpTime.value.front()); + return repl::OpTimeWith<DatabaseType>(db, docsWithOpTime.opTime); + } catch (const DBException& e) { + return e.toStatus("Failed to parse DatabaseType"); } - - return repl::OpTimeWith<DatabaseType>(parseStatus.getValue(), docsWithOpTime.opTime); } CollectionType ShardingCatalogClientImpl::getCollection(OperationContext* opCtx, @@ -559,13 +555,14 @@ StatusWith<VersionType> ShardingCatalogClientImpl::getConfigVersion( StatusWith<std::vector<std::string>> ShardingCatalogClientImpl::getDatabasesForShard( OperationContext* opCtx, const ShardId& shardId) { - auto findStatus = _exhaustiveFindOnConfig(opCtx, - kConfigReadSelector, - repl::ReadConcernLevel::kMajorityReadConcern, - DatabaseType::ConfigNS, - BSON(DatabaseType::primary(shardId.toString())), - BSONObj(), - boost::none); // no limit + auto findStatus = + _exhaustiveFindOnConfig(opCtx, + kConfigReadSelector, + repl::ReadConcernLevel::kMajorityReadConcern, + NamespaceString::kConfigDatabasesNamespace, + BSON(DatabaseType::kPrimaryFieldName << shardId.toString()), + BSONObj(), + boost::none); // no limit if (!findStatus.isOK()) { return findStatus.getStatus(); } @@ -575,7 +572,7 @@ StatusWith<std::vector<std::string>> ShardingCatalogClientImpl::getDatabasesForS dbs.reserve(values.size()); for (const BSONObj& obj : values) { string dbName; - Status status = bsonExtractStringField(obj, DatabaseType::name(), &dbName); + Status status = bsonExtractStringField(obj, DatabaseType::kNameFieldName, &dbName); if (!status.isOK()) { return status; } diff --git a/src/mongo/s/catalog/sharding_catalog_client_mock.cpp b/src/mongo/s/catalog/sharding_catalog_client_mock.cpp index a4153e80d50..3ad6ab3f54a 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_mock.cpp +++ b/src/mongo/s/catalog/sharding_catalog_client_mock.cpp @@ -34,7 +34,7 @@ #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" #include "mongo/s/catalog/type_config_version.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/catalog/type_tags.h" #include "mongo/s/client/shard.h" diff --git a/src/mongo/s/catalog/sharding_catalog_client_test.cpp b/src/mongo/s/catalog/sharding_catalog_client_test.cpp index 63dd880b63f..69a56198fd6 100644 --- a/src/mongo/s/catalog/sharding_catalog_client_test.cpp +++ b/src/mongo/s/catalog/sharding_catalog_client_test.cpp @@ -47,7 +47,7 @@ #include "mongo/s/catalog/sharding_catalog_client.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/catalog/type_tags.h" #include "mongo/s/chunk_version.h" @@ -176,8 +176,9 @@ TEST_F(ShardingCatalogClientTest, GetDatabaseExisting) { auto query = query_request_helper::makeFromFindCommandForTests(opMsg.body); ASSERT_EQ(query->getNamespaceOrUUID().nss().value_or(NamespaceString()), - DatabaseType::ConfigNS); - ASSERT_BSONOBJ_EQ(query->getFilter(), BSON(DatabaseType::name(expectedDb.getName()))); + NamespaceString::kConfigDatabasesNamespace); + ASSERT_BSONOBJ_EQ(query->getFilter(), + BSON(DatabaseType::kNameFieldName << expectedDb.getName())); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); ASSERT(!query->getLimit()); @@ -920,9 +921,9 @@ TEST_F(ShardingCatalogClientTest, GetDatabasesForShardValid) { auto query = query_request_helper::makeFromFindCommandForTests(opMsg.body); ASSERT_EQ(query->getNamespaceOrUUID().nss().value_or(NamespaceString()), - DatabaseType::ConfigNS); + NamespaceString::kConfigDatabasesNamespace); ASSERT_BSONOBJ_EQ(query->getFilter(), - BSON(DatabaseType::primary(dbt1.getPrimary().toString()))); + BSON(DatabaseType::kPrimaryFieldName << dbt1.getPrimary())); ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm); @@ -951,7 +952,7 @@ TEST_F(ShardingCatalogClientTest, GetDatabasesForShardInvalidDoc) { "db1", {"shard0000"}, false, DatabaseVersion(UUID::gen(), Timestamp(1, 1))); return vector<BSONObj>{ dbt1.toBSON(), - BSON(DatabaseType::name() << 0) // DatabaseType::name() should be a string + BSON(DatabaseType::kNameFieldName << 0) // Database name should be a string }; }); @@ -1057,13 +1058,13 @@ TEST_F(ShardingCatalogClientTest, UpdateDatabase) { "test", ShardId("shard0000"), true, DatabaseVersion(UUID::gen(), Timestamp(1, 1))); auto future = launchAsync([this, dbt] { - auto status = - catalogClient()->updateConfigDocument(operationContext(), - DatabaseType::ConfigNS, - BSON(DatabaseType::name(dbt.getName())), - dbt.toBSON(), - true, - ShardingCatalogClient::kMajorityWriteConcern); + auto status = catalogClient()->updateConfigDocument( + operationContext(), + NamespaceString::kConfigDatabasesNamespace, + BSON(DatabaseType::kNameFieldName << dbt.getName()), + dbt.toBSON(), + true, + ShardingCatalogClient::kMajorityWriteConcern); ASSERT_OK(status); }); @@ -1075,7 +1076,7 @@ TEST_F(ShardingCatalogClientTest, UpdateDatabase) { const auto opMsgRequest = OpMsgRequest::fromDBAndBody(request.dbname, request.cmdObj); const auto updateOp = UpdateOp::parse(opMsgRequest); - ASSERT_EQUALS(DatabaseType::ConfigNS, updateOp.getNamespace()); + ASSERT_EQUALS(NamespaceString::kConfigDatabasesNamespace, updateOp.getNamespace()); const auto& updates = updateOp.getUpdates(); ASSERT_EQUALS(1U, updates.size()); @@ -1083,7 +1084,7 @@ TEST_F(ShardingCatalogClientTest, UpdateDatabase) { const auto& update = updates.front(); ASSERT(update.getUpsert()); ASSERT(!update.getMulti()); - ASSERT_BSONOBJ_EQ(update.getQ(), BSON(DatabaseType::name(dbt.getName()))); + ASSERT_BSONOBJ_EQ(update.getQ(), BSON(DatabaseType::kNameFieldName << dbt.getName())); ASSERT_BSONOBJ_EQ(update.getU().getUpdateReplacement(), dbt.toBSON()); BatchedCommandResponse response; @@ -1105,13 +1106,13 @@ TEST_F(ShardingCatalogClientTest, UpdateConfigDocumentNonRetryableError) { "test", ShardId("shard0001"), false, DatabaseVersion(UUID::gen(), Timestamp(1, 1))); auto future = launchAsync([this, dbt] { - auto status = - catalogClient()->updateConfigDocument(operationContext(), - DatabaseType::ConfigNS, - BSON(DatabaseType::name(dbt.getName())), - dbt.toBSON(), - true, - ShardingCatalogClient::kMajorityWriteConcern); + auto status = catalogClient()->updateConfigDocument( + operationContext(), + NamespaceString::kConfigDatabasesNamespace, + BSON(DatabaseType::kNameFieldName << dbt.getName()), + dbt.toBSON(), + true, + ShardingCatalogClient::kMajorityWriteConcern); ASSERT_EQ(ErrorCodes::Interrupted, status); }); diff --git a/src/mongo/s/catalog/sharding_catalog_write_retry_test.cpp b/src/mongo/s/catalog/sharding_catalog_write_retry_test.cpp index 47f8c601b38..efac61fbbda 100644 --- a/src/mongo/s/catalog/sharding_catalog_write_retry_test.cpp +++ b/src/mongo/s/catalog/sharding_catalog_write_retry_test.cpp @@ -48,7 +48,6 @@ #include "mongo/s/catalog/sharding_catalog_client_impl.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" -#include "mongo/s/catalog/type_database.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/grid.h" diff --git a/src/mongo/s/catalog/type_database.cpp b/src/mongo/s/catalog/type_database.cpp deleted file mode 100644 index 736fa3fe0ef..00000000000 --- a/src/mongo/s/catalog/type_database.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * 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 Server Side 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/s/catalog/type_database.h" - -#include "mongo/base/status_with.h" -#include "mongo/bson/bsonobj.h" -#include "mongo/bson/bsonobjbuilder.h" -#include "mongo/bson/util/bson_extract.h" -#include "mongo/s/database_version.h" -#include "mongo/util/assert_util.h" - -namespace mongo { - -using std::string; - -const NamespaceString DatabaseType::ConfigNS("config.databases"); - -const BSONField<std::string> DatabaseType::name("_id"); -const BSONField<std::string> DatabaseType::primary("primary"); -const BSONField<bool> DatabaseType::sharded("partitioned"); -const BSONField<BSONObj> DatabaseType::version("version"); - -DatabaseType::DatabaseType(const std::string& dbName, - const ShardId& primaryShard, - bool sharded, - DatabaseVersion version) - : _name(dbName), _primary(primaryShard), _sharded(sharded), _version(version) {} - -StatusWith<DatabaseType> DatabaseType::fromBSON(const BSONObj& source) { - std::string dbtName; - { - Status status = bsonExtractStringField(source, name.name(), &dbtName); - if (!status.isOK()) - return status; - } - - std::string dbtPrimary; - { - Status status = bsonExtractStringField(source, primary.name(), &dbtPrimary); - if (!status.isOK()) - return status; - } - - bool dbtSharded; - { - Status status = - bsonExtractBooleanFieldWithDefault(source, sharded.name(), false, &dbtSharded); - if (!status.isOK()) - return status; - } - - BSONObj versionField = source.getObjectField("version"); - if (versionField.isEmpty()) { - return Status{ErrorCodes::InternalError, - str::stream() << "DatabaseVersion doesn't exist in database entry " << source - << " despite the config server being in binary version 4.2 " - "or later."}; - } - DatabaseVersion dbtVersion(versionField); - - return DatabaseType{ - std::move(dbtName), std::move(dbtPrimary), dbtSharded, std::move(dbtVersion)}; -} - -Status DatabaseType::validate() const { - if (_name.empty()) { - return Status(ErrorCodes::NoSuchKey, "missing name"); - } - - if (!_primary.isValid()) { - return Status(ErrorCodes::NoSuchKey, "missing primary"); - } - - return Status::OK(); -} - -BSONObj DatabaseType::toBSON() const { - BSONObjBuilder builder; - - // Required fields. - builder.append(name.name(), _name); - builder.append(primary.name(), _primary.toString()); - builder.append(sharded.name(), _sharded); - builder.append(version.name(), _version.toBSON()); - - return builder.obj(); -} - -std::string DatabaseType::toString() const { - return toBSON().toString(); -} - -void DatabaseType::setName(const std::string& name) { - invariant(!name.empty()); - _name = name; -} - -void DatabaseType::setPrimary(const ShardId& primary) { - invariant(primary.isValid()); - _primary = primary; -} - -void DatabaseType::setSharded(bool sharded) { - _sharded = sharded; -} - -void DatabaseType::setVersion(const DatabaseVersion& version) { - _version = version; -} - -} // namespace mongo diff --git a/src/mongo/s/catalog/type_database.h b/src/mongo/s/catalog/type_database.h deleted file mode 100644 index 654e35fae15..00000000000 --- a/src/mongo/s/catalog/type_database.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * 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 - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * 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 Server Side 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 <boost/optional.hpp> -#include <string> - -#include "mongo/db/jsobj.h" -#include "mongo/db/namespace_string.h" -#include "mongo/s/database_version.h" -#include "mongo/s/shard_id.h" - -namespace mongo { - -class BSONObj; -class Status; -template <typename T> -class StatusWith; - - -/** - * This class represents the layout and contents of documents contained in the config.databases - * collection. All manipulation of documents coming from that collection should be done with - * this class. - */ -class DatabaseType { -public: - DatabaseType(const std::string& dbName, - const ShardId& primaryShard, - bool sharded, - DatabaseVersion dbVersion); - - DatabaseType() = default; - - // Name of the databases collection in the config server. - static const NamespaceString ConfigNS; - - static const BSONField<std::string> name; - static const BSONField<std::string> primary; - static const BSONField<bool> sharded; - static const BSONField<BSONObj> version; - - /** - * Constructs a new DatabaseType object from BSON. Also does validation of the contents. - */ - static StatusWith<DatabaseType> fromBSON(const BSONObj& source); - - /** - * Returns OK if all fields have been set. Otherwise returns NoSuchKey and information - * about what is the first field which is missing. - */ - Status validate() const; - - /** - * Returns the BSON representation of the entry. - */ - BSONObj toBSON() const; - - /** - * Returns a std::string representation of the current internal state. - */ - std::string toString() const; - - const std::string& getName() const { - return _name; - } - void setName(const std::string& name); - - const ShardId& getPrimary() const { - return _primary; - } - void setPrimary(const ShardId& primary); - - bool getSharded() const { - return _sharded; - } - void setSharded(bool sharded); - - const DatabaseVersion& getVersion() const { - return _version; - } - void setVersion(const DatabaseVersion& version); - -private: - std::string _name; - ShardId _primary; - bool _sharded{false}; - DatabaseVersion _version; -}; - -} // namespace mongo diff --git a/src/mongo/s/catalog/type_database.idl b/src/mongo/s/catalog/type_database.idl new file mode 100644 index 00000000000..0da8feb6b62 --- /dev/null +++ b/src/mongo/s/catalog/type_database.idl @@ -0,0 +1,66 @@ +# Copyright (C) 2022-present MongoDB, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the Server Side Public License, version 1, +# as published by MongoDB, Inc. +# +# 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 +# Server Side Public License for more details. +# +# You should have received a copy of the Server Side Public License +# along with this program. If not, see +# <http://www.mongodb.com/licensing/server-side-public-license>. +# +# 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 Server Side 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. +# + +global: + cpp_namespace: "mongo" + cpp_includes: + - "mongo/s/catalog/types_validators.h" + +imports: + - "mongo/idl/basic_types.idl" + - "mongo/s/sharding_types.idl" + +structs: + DatabaseType: + description: "Represents the layout and contents of documents contained in the config + server's config.databases collection." + strict: false + fields: + _id: + description: "Database name." + cpp_name: name + type: string + validator: + callback: "validateDatabaseName" + optional: false + primary: + description: "Primary shard for this database." + type: shard_id + validator: + callback: "validateShardId" + optional: false + partitioned: + description: "Specify if it is allowed to create sharded collection on this database." + cpp_name: sharded + type: bool + optional: false + version: + description: "Version of the database." + type: database_version + optional: false + diff --git a/src/mongo/s/catalog/type_database_test.cpp b/src/mongo/s/catalog/type_database_test.cpp index 3f954a70f0d..73197980f55 100644 --- a/src/mongo/s/catalog/type_database_test.cpp +++ b/src/mongo/s/catalog/type_database_test.cpp @@ -31,7 +31,7 @@ #include "mongo/base/status_with.h" #include "mongo/db/jsobj.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/unittest/unittest.h" #include "mongo/util/uuid.h" @@ -41,21 +41,21 @@ using namespace mongo; using std::string; TEST(DatabaseType, Empty) { - StatusWith<DatabaseType> status = DatabaseType::fromBSON(BSONObj()); - ASSERT_FALSE(status.isOK()); + // Constructing from empty BSON must fails + ASSERT_THROWS(DatabaseType::parse(IDLParserErrorContext("DatabaseType"), BSONObj()), + AssertionException); } TEST(DatabaseType, Basic) { UUID uuid = UUID::gen(); Timestamp timestamp = Timestamp(1, 1); - StatusWith<DatabaseType> status = DatabaseType::fromBSON( - BSON(DatabaseType::name("mydb") - << DatabaseType::primary("shard") << DatabaseType::sharded(true) - << DatabaseType::version( - BSON("uuid" << uuid << "lastMod" << 0 << "timestamp" << timestamp)))); - ASSERT_TRUE(status.isOK()); + const auto dbObj = + BSON(DatabaseType::kNameFieldName + << "mydb" << DatabaseType::kPrimaryFieldName << "shard" + << DatabaseType::kShardedFieldName << true << DatabaseType::kVersionFieldName + << BSON("uuid" << uuid << "lastMod" << 0 << "timestamp" << timestamp)); - DatabaseType db = status.getValue(); + const auto db = DatabaseType::parse(IDLParserErrorContext("DatabaseType"), dbObj); ASSERT_EQUALS(db.getName(), "mydb"); ASSERT_EQUALS(db.getPrimary(), "shard"); ASSERT_TRUE(db.getSharded()); @@ -64,13 +64,17 @@ TEST(DatabaseType, Basic) { } TEST(DatabaseType, BadType) { - StatusWith<DatabaseType> status = DatabaseType::fromBSON(BSON(DatabaseType::name() << 0)); - ASSERT_FALSE(status.isOK()); + // Cosntructing from an BSON object with a malformed database must fails + const auto dbObj = BSON(DatabaseType::kNameFieldName << 0); + ASSERT_THROWS(DatabaseType::parse(IDLParserErrorContext("DatabaseType"), dbObj), + AssertionException); } TEST(DatabaseType, MissingRequired) { - StatusWith<DatabaseType> status = DatabaseType::fromBSON(BSON(DatabaseType::name("mydb"))); - ASSERT_FALSE(status.isOK()); + // Cosntructing from an BSON object without all the required fields must fails + const auto dbObj = BSON(DatabaseType::kNameFieldName << "mydb"); + ASSERT_THROWS(DatabaseType::parse(IDLParserErrorContext("DatabaseType"), dbObj), + AssertionException); } } // unnamed namespace diff --git a/src/mongo/s/catalog/types_validators.h b/src/mongo/s/catalog/types_validators.h new file mode 100644 index 00000000000..cded608aaaf --- /dev/null +++ b/src/mongo/s/catalog/types_validators.h @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * 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 Server Side 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 "mongo/s/shard_id.h" + +namespace mongo { + +inline Status validateDatabaseName(const std::string& value) { + if (value.empty()) { + return {ErrorCodes::NoSuchKey, "Database name cannot be empty"}; + } + return Status::OK(); +} + +inline Status validateShardId(const ShardId& value) { + if (!value.isValid()) { + return {ErrorCodes::NoSuchKey, "Shard ID cannot be empty"}; + } + return Status::OK(); +} + +} // namespace mongo diff --git a/src/mongo/s/catalog_cache.cpp b/src/mongo/s/catalog_cache.cpp index 317e93348f8..abb5afe2321 100644 --- a/src/mongo/s/catalog_cache.cpp +++ b/src/mongo/s/catalog_cache.cpp @@ -42,7 +42,7 @@ #include "mongo/db/repl/optime_with.h" #include "mongo/logv2/log.h" #include "mongo/s/catalog/type_collection.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/grid.h" #include "mongo/s/is_mongos.h" diff --git a/src/mongo/s/catalog_cache.h b/src/mongo/s/catalog_cache.h index b5b155f7af5..e51f0cd14b4 100644 --- a/src/mongo/s/catalog_cache.h +++ b/src/mongo/s/catalog_cache.h @@ -32,7 +32,7 @@ #include "mongo/base/string_data.h" #include "mongo/db/jsobj.h" #include "mongo/platform/atomic_word.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/catalog_cache_loader.h" #include "mongo/s/chunk_manager.h" #include "mongo/s/type_collection_common_types_gen.h" diff --git a/src/mongo/s/catalog_cache_loader.h b/src/mongo/s/catalog_cache_loader.h index efdfcaa3dd2..18a26324fbc 100644 --- a/src/mongo/s/catalog_cache_loader.h +++ b/src/mongo/s/catalog_cache_loader.h @@ -36,7 +36,7 @@ #include "mongo/base/string_data.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/chunk_version.h" #include "mongo/s/type_collection_common_types_gen.h" #include "mongo/util/concurrency/notification.h" diff --git a/src/mongo/s/catalog_cache_loader_mock.cpp b/src/mongo/s/catalog_cache_loader_mock.cpp index f8dadc1e667..059a7e8d132 100644 --- a/src/mongo/s/catalog_cache_loader_mock.cpp +++ b/src/mongo/s/catalog_cache_loader_mock.cpp @@ -123,7 +123,7 @@ SemiFuture<CollectionAndChangedChunks> CatalogCacheLoaderMock::getChunksSince( SemiFuture<DatabaseType> CatalogCacheLoaderMock::getDatabase(StringData dbName) { return makeReadyFutureWith([this] { uassertStatusOK(_swDatabaseReturnValue); - return DatabaseType(_swDatabaseReturnValue.getValue().getName(), + return DatabaseType(_swDatabaseReturnValue.getValue().getName().toString(), _swDatabaseReturnValue.getValue().getPrimary(), _swDatabaseReturnValue.getValue().getSharded(), _swDatabaseReturnValue.getValue().getVersion()); diff --git a/src/mongo/s/catalog_cache_refresh_test.cpp b/src/mongo/s/catalog_cache_refresh_test.cpp index 37d28ef5f99..0167943d7c8 100644 --- a/src/mongo/s/catalog_cache_refresh_test.cpp +++ b/src/mongo/s/catalog_cache_refresh_test.cpp @@ -35,7 +35,7 @@ #include "mongo/db/pipeline/aggregation_request_helper.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/catalog_cache.h" #include "mongo/s/catalog_cache_test_fixture.h" #include "mongo/s/database_version.h" @@ -205,7 +205,8 @@ TEST_F(CatalogCacheRefreshTest, DatabaseBSONCorrupted) { FAIL(str::stream() << "Returning corrupted database entry did not fail and returned " << cm.toString()); } catch (const DBException& ex) { - ASSERT_EQ(ErrorCodes::NoSuchKey, ex.code()); + constexpr int kParseError = 40414; + ASSERT_EQ(ErrorCodes::Error(kParseError), ex.code()); } } diff --git a/src/mongo/s/catalog_cache_test.cpp b/src/mongo/s/catalog_cache_test.cpp index 813012a3270..959cd7bf1fb 100644 --- a/src/mongo/s/catalog_cache_test.cpp +++ b/src/mongo/s/catalog_cache_test.cpp @@ -33,7 +33,7 @@ #include <boost/optional/optional_io.hpp> -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/catalog_cache.h" #include "mongo/s/catalog_cache_loader_mock.h" #include "mongo/s/sharding_router_test_fixture.h" diff --git a/src/mongo/s/catalog_cache_test_fixture.cpp b/src/mongo/s/catalog_cache_test_fixture.cpp index 06283c2679f..f3e3431e832 100644 --- a/src/mongo/s/catalog_cache_test_fixture.cpp +++ b/src/mongo/s/catalog_cache_test_fixture.cpp @@ -41,7 +41,7 @@ #include "mongo/db/query/collation/collator_factory_mock.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/catalog/type_collection.h" -#include "mongo/s/catalog/type_database.h" +#include "mongo/s/catalog/type_database_gen.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/catalog_cache.h" #include "mongo/s/database_version.h" diff --git a/src/mongo/s/sharding_types.idl b/src/mongo/s/sharding_types.idl index 6d27a591067..acf3509d0ff 100644 --- a/src/mongo/s/sharding_types.idl +++ b/src/mongo/s/sharding_types.idl @@ -32,6 +32,7 @@ global: cpp_namespace: "mongo" cpp_includes: - "mongo/s/shard_id.h" + - "mongo/s/database_version.h" imports: - "mongo/idl/basic_types.idl" @@ -43,3 +44,11 @@ types: cpp_type: "ShardId" deserializer: "mongo::BSONElement::str" serializer: "mongo::ShardId::toString" + + database_version: + bson_serialization_type: object + description: An object representing a version for a database. + cpp_type: DatabaseVersion + serializer: "mongo::DatabaseVersion::toBSON" + deserializer: "mongo::DatabaseVersion" + |