/** * Copyright 2014 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 . * * 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 #include #include "mongo/base/status.h" #include "mongo/base/status_with.h" #include "mongo/db/repl/member_config.h" #include "mongo/db/repl/replica_set_tag.h" #include "mongo/db/write_concern_options.h" #include "mongo/util/string_map.h" #include "mongo/util/time_support.h" namespace mongo { class BSONObj; namespace repl { /** * Representation of the configuration information about a particular replica set. */ class ReplicaSetConfig { public: typedef std::vector::const_iterator MemberIterator; static const std::string kIdFieldName; static const std::string kVersionFieldName; static const std::string kMembersFieldName; static const std::string kSettingsFieldName; static const std::string kMajorityWriteConcernModeName; static const std::string kStepDownCheckWriteConcernModeName; static const size_t kMaxMembers = 12; static const size_t kMaxVotingMembers = 7; static const Seconds kDefaultHeartbeatTimeoutPeriod; ReplicaSetConfig(); std::string asBson() { return ""; } /** * Initializes this ReplicaSetConfig from the contents of "cfg". */ Status initialize(const BSONObj& cfg); /** * Returns true if this object has been successfully initialized or copied from * an initialized object. */ bool isInitialized() const { return _isInitialized; } /** * Performs basic consistency checks on the replica set configuration. */ Status validate() const; /** * Checks if this configuration can satisfy the given write concern. * * Things that are taken into consideration include: * 1. If the set has enough data-bearing members. * 2. If the write concern mode exists. * 3. If there are enough members for the write concern mode specified. */ Status checkIfWriteConcernCanBeSatisfied(const WriteConcernOptions& writeConcern) const; /** * Gets the version of this configuration. * * The version number sequences configurations of the replica set, so that * nodes may distinguish between "older" and "newer" configurations. */ long long getConfigVersion() const { return _version; } /** * Gets the name (_id field value) of the replica set described by this configuration. */ const std::string& getReplSetName() const { return _replSetName; } /** * Gets the number of members in this configuration. */ int getNumMembers() const { return _members.size(); } /** * Gets a begin iterator over the MemberConfigs stored in this ReplicaSetConfig. */ MemberIterator membersBegin() const { return _members.begin(); } /** * Gets an end iterator over the MemberConfigs stored in this ReplicaSetConfig. */ MemberIterator membersEnd() const { return _members.end(); } /** * Access a MemberConfig element by index. */ const MemberConfig& getMemberAt(size_t i) const; /** * Returns a pointer to the MemberConfig corresponding to the member with the given _id in * the config, or NULL if there is no member with that ID. */ const MemberConfig* findMemberByID(int id) const; /** * Returns a pointer to the MemberConfig corresponding to the member with the given * HostAndPort in the config, or NULL if there is no member with that address. */ const MemberConfig* findMemberByHostAndPort(const HostAndPort& hap) const; /** * Returns a MemberConfig index position corresponding to the member with the given * HostAndPort in the config, or -1 if there is no member with that address. */ const int findMemberIndexByHostAndPort(const HostAndPort& hap) const; /** * Gets the default write concern for the replica set described by this configuration. */ const WriteConcernOptions& getDefaultWriteConcern() const { return _defaultWriteConcern; } /** * Gets the amount of time to wait for a response to hearbeats sent to other * nodes in the replica set. */ Seconds getHeartbeatTimeoutPeriod() const { return _heartbeatTimeoutPeriod; } /** * Gets the amount of time to wait for a response to hearbeats sent to other * nodes in the replica set, as above, but returns a Milliseconds instead of * Seconds object. */ Milliseconds getHeartbeatTimeoutPeriodMillis() const { return Milliseconds(_heartbeatTimeoutPeriod.total_milliseconds()); } /** * Gets the number of nodes that constitutes a "majority" in this replica set, * for purposes of replicating data. */ int getMajorityNumber() const { return _majorityNumber; } /** * Gets the number of votes required to win an election. */ int getMajorityVoteCount() const { return _majorityVoteCount; } /** * Gets the number of voters. */ int getTotalVotingMembers() const { return _totalVotingMembers; } /** * Returns true if automatic (not explicitly set) chaining is allowed. */ bool isChainingAllowed() const { return _chainingAllowed; } /** * Returns a ReplicaSetTag with the given "key" and "value", or an invalid * tag if the configuration describes no such tag. */ ReplicaSetTag findTag(const StringData& key, const StringData& value) const; /** * Returns the pattern corresponding to "patternName" in this configuration. * If "patternName" is not a valid pattern in this configuration, returns * ErrorCodes::NoSuchKey. */ StatusWith findCustomWriteMode(const StringData& patternName) const; /** * Returns the "tags configuration" for this replicaset. * * NOTE(schwerin): Not clear if this should be used other than for reporting/debugging. */ const ReplicaSetTagConfig& getTagConfig() const { return _tagConfig; } /** * Returns the config as a BSONObj. */ BSONObj toBSON() const; /** * Returns a vector of strings which are the names of the WriteConcernModes. * Currently used in unit tests to compare two configs. */ std::vector getWriteConcernNames() const; private: /** * Parses the "settings" subdocument of a replica set configuration. */ Status _parseSettingsSubdocument(const BSONObj& settings); /** * Calculates and stores the majorities for replicating data (_majorityNumber) and for * electing a primary (_majorityVoteCount). */ void _calculateMajorities(); /** * Adds internal write concern modes to the getLastErrorModes list. */ void _addInternalWriteConcernModes(); bool _isInitialized; long long _version; std::string _replSetName; std::vector _members; WriteConcernOptions _defaultWriteConcern; Seconds _heartbeatTimeoutPeriod; bool _chainingAllowed; int _majorityNumber; int _majorityVoteCount; int _totalVotingMembers; ReplicaSetTagConfig _tagConfig; StringMap _customWriteConcernModes; }; } // namespace repl } // namespace mongo