diff options
author | Daniel Alabi <alabidan@gmail.com> | 2015-06-14 22:44:49 -0400 |
---|---|---|
committer | Daniel Alabi <alabidan@gmail.com> | 2015-06-16 15:00:06 -0400 |
commit | 6bf2bfe665e40213d5887160b787babd440e506f (patch) | |
tree | 0e424013f811f47189d3383747f4f9a7678d262d | |
parent | 34a05c0a54382012b1d41ce64f6256a6933c9004 (diff) | |
download | mongo-6bf2bfe665e40213d5887160b787babd440e506f.tar.gz |
SERVER-18949 Implement getDatabase for the RS catalog manager
-rw-r--r-- | src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp | 35 | ||||
-rw-r--r-- | src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp | 48 |
2 files changed, 82 insertions, 1 deletions
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp index e05eb3fccd1..4d438701e24 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp @@ -167,7 +167,40 @@ namespace { StatusWith<DatabaseType> CatalogManagerReplicaSet::getDatabase(const std::string& dbName) { invariant(nsIsDbOnly(dbName)); - return notYetImplemented; + + // The two databases that are hosted on the config server are config and admin + if (dbName == "config" || dbName == "admin") { + DatabaseType dbt; + dbt.setName(dbName); + dbt.setSharded(false); + dbt.setPrimary("config"); + + return dbt; + } + + const auto& configShard = grid.shardRegistry()->findIfExists("config"); + const auto readHost = configShard->getTargeter()->findHost(kConfigReadSelector); + if (!readHost.isOK()) { + return readHost.getStatus(); + } + + auto findStatus = _find(readHost.getValue(), + NamespaceString(DatabaseType::ConfigNS), + BSON(DatabaseType::name(dbName)), + 1); + if (!findStatus.isOK()) { + return findStatus.getStatus(); + } + + const auto& docs = findStatus.getValue(); + if (docs.empty()) { + return {ErrorCodes::NamespaceNotFound, + stream() << "database " << dbName << " not found"}; + } + + invariant(docs.size() == 1); + + return DatabaseType::fromBSON(docs.front()); } Status CatalogManagerReplicaSet::updateCollection(const std::string& collNs, diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp index e5229aba2e1..4d35495ce51 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp @@ -39,6 +39,7 @@ #include "mongo/s/catalog/replset/catalog_manager_replica_set.h" #include "mongo/s/catalog/replset/catalog_manager_replica_set_test_fixture.h" #include "mongo/s/catalog/type_collection.h" +#include "mongo/s/catalog/type_database.h" #include "mongo/s/client/shard_registry.h" #include "mongo/util/log.h" @@ -103,5 +104,52 @@ namespace { future.get(); } + TEST_F(CatalogManagerReplSetTestFixture, GetDatabaseExisting) { + RemoteCommandTargeterMock* targeter = + RemoteCommandTargeterMock::get(shardRegistry()->findIfExists("config")->getTargeter()); + targeter->setFindHostReturnValue(HostAndPort("TestHost1")); + + DatabaseType expectedDb; + expectedDb.setName("bigdata"); + expectedDb.setPrimary("shard0000"); + expectedDb.setSharded(true); + + auto future = async(std::launch::async, [this, &expectedDb] { + return assertGet(catalogManager()->getDatabase(expectedDb.getName())); + }); + + onFindCommand([&expectedDb](const std::string& dbName, const BSONObj& cmdObj) { + const NamespaceString nss(dbName + '.' + cmdObj.firstElement().String()); + ASSERT_EQ(nss.toString(), DatabaseType::ConfigNS); + + auto query = assertGet(LiteParsedQuery::fromFindCommand(nss, cmdObj, false)); + + ASSERT_EQ(query->ns(), DatabaseType::ConfigNS); + ASSERT_EQ(query->getFilter(), BSON(DatabaseType::name(expectedDb.getName()))); + + return vector<BSONObj>{ expectedDb.toBSON() }; + }); + + const auto& actualDb = future.get(); + ASSERT_EQ(expectedDb.toBSON(), actualDb.toBSON()); + } + + TEST_F(CatalogManagerReplSetTestFixture, GetDatabaseNotExisting) { + RemoteCommandTargeterMock* targeter = + RemoteCommandTargeterMock::get(shardRegistry()->findIfExists("config")->getTargeter()); + targeter->setFindHostReturnValue(HostAndPort("TestHost1")); + + auto future = async(std::launch::async, [this] { + auto dbResult = catalogManager()->getDatabase("NonExistent"); + ASSERT_EQ(dbResult.getStatus(), ErrorCodes::NamespaceNotFound); + }); + + onFindCommand([](const std::string& dbName, const BSONObj& cmdObj) { + return vector<BSONObj>{ }; + }); + + future.get(); + } + } // namespace } // namespace mongo |