diff options
-rw-r--r-- | src/mongo/db/catalog/SConscript | 24 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_build_entry.idl | 85 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_build_entry_test.cpp | 149 | ||||
-rw-r--r-- | src/mongo/db/write_concern_options.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/write_concern_options.h | 7 | ||||
-rw-r--r-- | src/mongo/util/uuid.h | 1 |
6 files changed, 272 insertions, 0 deletions
diff --git a/src/mongo/db/catalog/SConscript b/src/mongo/db/catalog/SConscript index d678985f150..f55d3c617ff 100644 --- a/src/mongo/db/catalog/SConscript +++ b/src/mongo/db/catalog/SConscript @@ -55,6 +55,30 @@ env.Library( ) env.Library( + target='index_build_entry_idl', + source=[ + env.Idlc('index_build_entry.idl')[0], + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/base', + '$BUILD_DIR/mongo/db/write_concern_options', + '$BUILD_DIR/mongo/idl/idl_parser', + '$BUILD_DIR/mongo/util/net/network', + ], +) + +env.CppUnitTest( + target='index_build_entry_test', + source=[ + 'index_build_entry_test.cpp', + ], + LIBDEPS=[ + 'index_build_entry_idl', + '$BUILD_DIR/mongo/unittest/unittest', + ], +) + +env.Library( target='health_log', source=[ "health_log.cpp", diff --git a/src/mongo/db/catalog/index_build_entry.idl b/src/mongo/db/catalog/index_build_entry.idl new file mode 100644 index 00000000000..dde8d2a23fc --- /dev/null +++ b/src/mongo/db/catalog/index_build_entry.idl @@ -0,0 +1,85 @@ +# 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. +# + +global: + cpp_namespace: "mongo" + cpp_includes: + - "mongo/db/write_concern_options.h" + - "mongo/util/uuid.h" + +imports: + - "mongo/idl/basic_types.idl" + - "mongo/util/net/hostandport.idl" + +types: + commitQuorum: + bson_serialization_type: object + description: "commitQuorum type that shadows the behaviour of WriteConcernOptions." + cpp_type: "mongo::WriteConcernOptions" + serializer: "mongo::WriteConcernOptions::toBSON" + deserializer: "mongo::WriteConcernOptions::deserializerForIDL" + +structs: + IndexBuildEntry: + description: "A document that tracks the progress of an index build across replica set + members." + strict: true + fields: + _id: + cpp_name: buildUUID + optional: false + type: uuid + description: "Unique identifier of an index build across replica set members." + collectionUUID: + optional: false + type: uuid + description: "Identifies the collection upon which the index is being built." + commitQuorum: + optional: false + type: commitQuorum + description: "commitQuorum has the same behaviour as writeConcern, indicating how + many replica set members are needed to commit the index build." + indexNames: + optional: false + type: array<string> + description: "An array of index names associated with this particular cross replica + set index build." + prepareIndexBuild: + optional: false + type: bool + default: false + description: "Indicates that the primary has entered the commit phase, and + secondaries are allowed to proceed with the index constraint + violations resolution phase when ready and then send + voteCommitIndexBuild." + commitReadyMembers: + optional: true + type: array<HostAndPort> + description: "List of replica set members, by their host and port, that are in the + commit phase waiting for the primary to write the commitIndexBuild + oplog entry." diff --git a/src/mongo/db/catalog/index_build_entry_test.cpp b/src/mongo/db/catalog/index_build_entry_test.cpp new file mode 100644 index 00000000000..9f774514a9e --- /dev/null +++ b/src/mongo/db/catalog/index_build_entry_test.cpp @@ -0,0 +1,149 @@ +/** + * 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 <string> +#include <vector> + +#include "mongo/bson/bsonobj.h" +#include "mongo/bson/bsonobjbuilder.h" +#include "mongo/bson/bsontypes.h" +#include "mongo/db/catalog/index_build_entry_gen.h" +#include "mongo/db/write_concern_options.h" +#include "mongo/unittest/unittest.h" +#include "mongo/util/assert_util.h" +#include "mongo/util/net/hostandport.h" +#include "mongo/util/uuid.h" + +namespace mongo { +namespace { + +enum CommitQuorumOptions { Number, Majority, Tag }; + +const std::vector<std::string> generateIndexes(size_t numIndexes) { + std::vector<std::string> indexes; + for (size_t i = 0; i < numIndexes; i++) { + indexes.push_back("Index" + std::to_string(i)); + } + return indexes; +} + +const WriteConcernOptions generateCommitQuorum(CommitQuorumOptions option) { + switch (option) { + case Number: + return WriteConcernOptions(1, WriteConcernOptions::SyncMode::UNSET, 0); + break; + case Majority: + return WriteConcernOptions( + WriteConcernOptions::kMajority, WriteConcernOptions::SyncMode::UNSET, 0); + break; + case Tag: + return WriteConcernOptions("someTag", WriteConcernOptions::SyncMode::UNSET, 0); + break; + default: + return WriteConcernOptions(0, WriteConcernOptions::SyncMode::UNSET, 0); + } +} + +const std::vector<HostAndPort> generateCommitReadyMembers(size_t numMembers) { + std::vector<HostAndPort> members; + for (size_t i = 0; i < numMembers; i++) { + members.push_back(HostAndPort("localhost:27017")); + } + return members; +} + +TEST(IndexBuildEntryTest, IndexBuildEntryWithRequiredFields) { + const UUID id = UUID::gen(); + const UUID collectionUUID = UUID::gen(); + const WriteConcernOptions commitQuorum = generateCommitQuorum(CommitQuorumOptions::Number); + const std::vector<std::string> indexes = generateIndexes(1); + + IndexBuildEntry entry(id, collectionUUID, commitQuorum, indexes); + + ASSERT_EQUALS(entry.getBuildUUID(), id); + ASSERT_EQUALS(entry.getCollectionUUID(), collectionUUID); + ASSERT_EQUALS(entry.getCommitQuorum().wNumNodes, 1); + ASSERT_TRUE(entry.getCommitQuorum().syncMode == WriteConcernOptions::SyncMode::UNSET); + ASSERT_EQUALS(entry.getCommitQuorum().wTimeout, 0); + ASSERT_EQUALS(entry.getIndexNames().size(), indexes.size()); + ASSERT_FALSE(entry.getPrepareIndexBuild()); +} + +TEST(IndexBuildEntryTest, IndexBuildEntryWithOptionalFields) { + const UUID id = UUID::gen(); + const UUID collectionUUID = UUID::gen(); + const WriteConcernOptions commitQuorum = generateCommitQuorum(CommitQuorumOptions::Majority); + const std::vector<std::string> indexes = generateIndexes(3); + + IndexBuildEntry entry(id, collectionUUID, commitQuorum, indexes); + + ASSERT_FALSE(entry.getPrepareIndexBuild()); + entry.setPrepareIndexBuild(true); + entry.setCommitReadyMembers(generateCommitReadyMembers(2)); + + ASSERT_EQUALS(entry.getBuildUUID(), id); + ASSERT_EQUALS(entry.getCollectionUUID(), collectionUUID); + ASSERT_EQUALS(entry.getCommitQuorum().wMode, WriteConcernOptions::kMajority); + ASSERT_TRUE(entry.getCommitQuorum().syncMode == WriteConcernOptions::SyncMode::UNSET); + ASSERT_EQUALS(entry.getCommitQuorum().wTimeout, 0); + ASSERT_EQUALS(entry.getIndexNames().size(), indexes.size()); + ASSERT_TRUE(entry.getPrepareIndexBuild()); + ASSERT_TRUE(entry.getCommitReadyMembers()->size() == 2); +} + +TEST(IndexBuildEntryTest, SerializeAndDeserialize) { + const UUID id = UUID::gen(); + const UUID collectionUUID = UUID::gen(); + const WriteConcernOptions commitQuorum = generateCommitQuorum(CommitQuorumOptions::Tag); + const std::vector<std::string> indexes = generateIndexes(1); + + IndexBuildEntry entry(id, collectionUUID, commitQuorum, indexes); + entry.setPrepareIndexBuild(false); + entry.setCommitReadyMembers(generateCommitReadyMembers(3)); + + BSONObj obj = entry.toBSON(); + ASSERT_TRUE(obj.valid(BSONVersion::kLatest)); + + IDLParserErrorContext ctx("IndexBuildsEntry Parser"); + IndexBuildEntry rebuiltEntry = IndexBuildEntry::parse(ctx, obj); + + ASSERT_EQUALS(rebuiltEntry.getBuildUUID(), id); + ASSERT_EQUALS(rebuiltEntry.getCollectionUUID(), collectionUUID); + ASSERT_EQUALS(rebuiltEntry.getCommitQuorum().wMode, "someTag"); + ASSERT_TRUE(rebuiltEntry.getCommitQuorum().syncMode == WriteConcernOptions::SyncMode::UNSET); + ASSERT_EQUALS(rebuiltEntry.getCommitQuorum().wTimeout, 0); + ASSERT_EQUALS(rebuiltEntry.getIndexNames().size(), indexes.size()); + ASSERT_FALSE(rebuiltEntry.getPrepareIndexBuild()); + ASSERT_TRUE(rebuiltEntry.getCommitReadyMembers()->size() == 3); +} + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/write_concern_options.cpp b/src/mongo/db/write_concern_options.cpp index 59fb840ec9a..e9bf4f4ba68 100644 --- a/src/mongo/db/write_concern_options.cpp +++ b/src/mongo/db/write_concern_options.cpp @@ -161,6 +161,12 @@ Status WriteConcernOptions::parse(const BSONObj& obj) { return Status::OK(); } +WriteConcernOptions WriteConcernOptions::deserializerForIDL(const BSONObj& obj) { + WriteConcernOptions writeConcernOptions; + uassertStatusOK(writeConcernOptions.parse(obj)); + return writeConcernOptions; +} + StatusWith<WriteConcernOptions> WriteConcernOptions::extractWCFromCommand( const BSONObj& cmdObj, const WriteConcernOptions& defaultWC) { WriteConcernOptions writeConcern = defaultWC; diff --git a/src/mongo/db/write_concern_options.h b/src/mongo/db/write_concern_options.h index 8a68a39bf8e..8ff5bc050c1 100644 --- a/src/mongo/db/write_concern_options.h +++ b/src/mongo/db/write_concern_options.h @@ -75,6 +75,13 @@ public: Status parse(const BSONObj& obj); /** + * Returns an instance of WriteConcernOptions from a BSONObj. + * + * uasserts() if the obj cannot be deserialized. + */ + static WriteConcernOptions deserializerForIDL(const BSONObj& obj); + + /** * Attempts to extract a writeConcern from cmdObj. * Verifies that the writeConcern is of type Object (BSON type). */ diff --git a/src/mongo/util/uuid.h b/src/mongo/util/uuid.h index 06535daf979..48efcbaf06c 100644 --- a/src/mongo/util/uuid.h +++ b/src/mongo/util/uuid.h @@ -68,6 +68,7 @@ class UUID { friend class DatabaseVersion; friend class DbCheckOplogCollection; friend class idl::import::One_UUID; + friend class IndexBuildEntry; friend class LogicalSessionId; friend class LogicalSessionToClient; friend class LogicalSessionIdToClient; |