/**
* 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