diff options
Diffstat (limited to 'src/mongo/db/repl/member_config.cpp')
-rw-r--r-- | src/mongo/db/repl/member_config.cpp | 482 |
1 files changed, 235 insertions, 247 deletions
diff --git a/src/mongo/db/repl/member_config.cpp b/src/mongo/db/repl/member_config.cpp index 02711adedd3..a6f8e311928 100644 --- a/src/mongo/db/repl/member_config.cpp +++ b/src/mongo/db/repl/member_config.cpp @@ -40,280 +40,268 @@ namespace mongo { namespace repl { - const std::string MemberConfig::kIdFieldName = "_id"; - const std::string MemberConfig::kVotesFieldName = "votes"; - const std::string MemberConfig::kPriorityFieldName = "priority"; - const std::string MemberConfig::kHostFieldName = "host"; - const std::string MemberConfig::kHiddenFieldName = "hidden"; - const std::string MemberConfig::kSlaveDelayFieldName = "slaveDelay"; - const std::string MemberConfig::kArbiterOnlyFieldName = "arbiterOnly"; - const std::string MemberConfig::kBuildIndexesFieldName = "buildIndexes"; - const std::string MemberConfig::kTagsFieldName = "tags"; - const std::string MemberConfig::kInternalVoterTagName = "$voter"; - const std::string MemberConfig::kInternalElectableTagName = "$electable"; - const std::string MemberConfig::kInternalAllTagName = "$all"; +const std::string MemberConfig::kIdFieldName = "_id"; +const std::string MemberConfig::kVotesFieldName = "votes"; +const std::string MemberConfig::kPriorityFieldName = "priority"; +const std::string MemberConfig::kHostFieldName = "host"; +const std::string MemberConfig::kHiddenFieldName = "hidden"; +const std::string MemberConfig::kSlaveDelayFieldName = "slaveDelay"; +const std::string MemberConfig::kArbiterOnlyFieldName = "arbiterOnly"; +const std::string MemberConfig::kBuildIndexesFieldName = "buildIndexes"; +const std::string MemberConfig::kTagsFieldName = "tags"; +const std::string MemberConfig::kInternalVoterTagName = "$voter"; +const std::string MemberConfig::kInternalElectableTagName = "$electable"; +const std::string MemberConfig::kInternalAllTagName = "$all"; namespace { - const std::string kLegalMemberConfigFieldNames[] = { - MemberConfig::kIdFieldName, - MemberConfig::kVotesFieldName, - MemberConfig::kPriorityFieldName, - MemberConfig::kHostFieldName, - MemberConfig::kHiddenFieldName, - MemberConfig::kSlaveDelayFieldName, - MemberConfig::kArbiterOnlyFieldName, - MemberConfig::kBuildIndexesFieldName, - MemberConfig::kTagsFieldName - }; - - const int kVotesFieldDefault = 1; - const double kPriorityFieldDefault = 1.0; - const Seconds kSlaveDelayFieldDefault(0); - const bool kArbiterOnlyFieldDefault = false; - const bool kHiddenFieldDefault = false; - const bool kBuildIndexesFieldDefault = true; - - const Seconds kMaxSlaveDelay(3600 * 24 * 366); +const std::string kLegalMemberConfigFieldNames[] = {MemberConfig::kIdFieldName, + MemberConfig::kVotesFieldName, + MemberConfig::kPriorityFieldName, + MemberConfig::kHostFieldName, + MemberConfig::kHiddenFieldName, + MemberConfig::kSlaveDelayFieldName, + MemberConfig::kArbiterOnlyFieldName, + MemberConfig::kBuildIndexesFieldName, + MemberConfig::kTagsFieldName}; + +const int kVotesFieldDefault = 1; +const double kPriorityFieldDefault = 1.0; +const Seconds kSlaveDelayFieldDefault(0); +const bool kArbiterOnlyFieldDefault = false; +const bool kHiddenFieldDefault = false; +const bool kBuildIndexesFieldDefault = true; + +const Seconds kMaxSlaveDelay(3600 * 24 * 366); } // namespace - Status MemberConfig::initialize(const BSONObj& mcfg, ReplicaSetTagConfig* tagConfig) { - Status status = bsonCheckOnlyHasFields( - "replica set member configuration", mcfg, kLegalMemberConfigFieldNames); - if (!status.isOK()) - return status; - - // - // Parse _id field. - // - BSONElement idElement = mcfg[kIdFieldName]; - if (idElement.eoo()) { - return Status(ErrorCodes::NoSuchKey, str::stream() << kIdFieldName << - " field is missing"); - } - if (!idElement.isNumber()) { - return Status(ErrorCodes::TypeMismatch, str::stream() << kIdFieldName << - " field has non-numeric type " << typeName(idElement.type())); - } - _id = idElement.numberInt(); - - // - // Parse h field. - // - std::string hostAndPortString; - status = bsonExtractStringField(mcfg, kHostFieldName, &hostAndPortString); - if (!status.isOK()) - return status; - boost::trim(hostAndPortString); - status = _host.initialize(hostAndPortString); - if (!status.isOK()) - return status; - if (!_host.hasPort()) { - // make port explicit even if default. - _host = HostAndPort(_host.host(), _host.port()); - } +Status MemberConfig::initialize(const BSONObj& mcfg, ReplicaSetTagConfig* tagConfig) { + Status status = bsonCheckOnlyHasFields( + "replica set member configuration", mcfg, kLegalMemberConfigFieldNames); + if (!status.isOK()) + return status; - // - // Parse votes field. - // - BSONElement votesElement = mcfg[kVotesFieldName]; - if (votesElement.eoo()) { - _votes = kVotesFieldDefault; - } - else if (votesElement.isNumber()) { - _votes = votesElement.numberInt(); - } - else { - return Status(ErrorCodes::TypeMismatch, str::stream() << kVotesFieldName << - " field value has non-numeric type " << - typeName(votesElement.type())); - } + // + // Parse _id field. + // + BSONElement idElement = mcfg[kIdFieldName]; + if (idElement.eoo()) { + return Status(ErrorCodes::NoSuchKey, str::stream() << kIdFieldName << " field is missing"); + } + if (!idElement.isNumber()) { + return Status(ErrorCodes::TypeMismatch, + str::stream() << kIdFieldName << " field has non-numeric type " + << typeName(idElement.type())); + } + _id = idElement.numberInt(); - // - // Parse priority field. - // - BSONElement priorityElement = mcfg[kPriorityFieldName]; - if (priorityElement.eoo()) { - _priority = kPriorityFieldDefault; - } - else if (priorityElement.isNumber()) { - _priority = priorityElement.numberDouble(); - } - else { - return Status(ErrorCodes::TypeMismatch, str::stream() << kPriorityFieldName << - " field has non-numeric type " << typeName(priorityElement.type())); - } + // + // Parse h field. + // + std::string hostAndPortString; + status = bsonExtractStringField(mcfg, kHostFieldName, &hostAndPortString); + if (!status.isOK()) + return status; + boost::trim(hostAndPortString); + status = _host.initialize(hostAndPortString); + if (!status.isOK()) + return status; + if (!_host.hasPort()) { + // make port explicit even if default. + _host = HostAndPort(_host.host(), _host.port()); + } - // - // Parse arbiterOnly field. - // - status = bsonExtractBooleanFieldWithDefault(mcfg, - kArbiterOnlyFieldName, - kArbiterOnlyFieldDefault, - &_arbiterOnly); - if (!status.isOK()) - return status; - - // - // Parse slaveDelay field. - // - BSONElement slaveDelayElement = mcfg[kSlaveDelayFieldName]; - if (slaveDelayElement.eoo()) { - _slaveDelay = kSlaveDelayFieldDefault; - } - else if (slaveDelayElement.isNumber()) { - _slaveDelay = Seconds(slaveDelayElement.numberInt()); - } - else { - return Status(ErrorCodes::TypeMismatch, str::stream() << kSlaveDelayFieldName << - " field value has non-numeric type " << - typeName(slaveDelayElement.type())); - } + // + // Parse votes field. + // + BSONElement votesElement = mcfg[kVotesFieldName]; + if (votesElement.eoo()) { + _votes = kVotesFieldDefault; + } else if (votesElement.isNumber()) { + _votes = votesElement.numberInt(); + } else { + return Status(ErrorCodes::TypeMismatch, + str::stream() << kVotesFieldName << " field value has non-numeric type " + << typeName(votesElement.type())); + } + + // + // Parse priority field. + // + BSONElement priorityElement = mcfg[kPriorityFieldName]; + if (priorityElement.eoo()) { + _priority = kPriorityFieldDefault; + } else if (priorityElement.isNumber()) { + _priority = priorityElement.numberDouble(); + } else { + return Status(ErrorCodes::TypeMismatch, + str::stream() << kPriorityFieldName << " field has non-numeric type " + << typeName(priorityElement.type())); + } + + // + // Parse arbiterOnly field. + // + status = bsonExtractBooleanFieldWithDefault( + mcfg, kArbiterOnlyFieldName, kArbiterOnlyFieldDefault, &_arbiterOnly); + if (!status.isOK()) + return status; - // - // Parse hidden field. - // - status = bsonExtractBooleanFieldWithDefault(mcfg, - kHiddenFieldName, - kHiddenFieldDefault, - &_hidden); - if (!status.isOK()) - return status; - - // - // Parse buildIndexes field. - // - status = bsonExtractBooleanFieldWithDefault(mcfg, - kBuildIndexesFieldName, - kBuildIndexesFieldDefault, - &_buildIndexes); - if (!status.isOK()) - return status; - - // - // Parse "tags" field. - // - _tags.clear(); - BSONElement tagsElement; - status = bsonExtractTypedField(mcfg, kTagsFieldName, Object, &tagsElement); - if (status.isOK()) { - for (BSONObj::iterator tagIter(tagsElement.Obj()); tagIter.more();) { - const BSONElement& tag = tagIter.next(); - if (tag.type() != String) { - return Status(ErrorCodes::TypeMismatch, str::stream() << "tags." << - tag.fieldName() << " field has non-string value of type " << - typeName(tag.type())); - } - _tags.push_back(tagConfig->makeTag(tag.fieldNameStringData(), - tag.valueStringData())); + // + // Parse slaveDelay field. + // + BSONElement slaveDelayElement = mcfg[kSlaveDelayFieldName]; + if (slaveDelayElement.eoo()) { + _slaveDelay = kSlaveDelayFieldDefault; + } else if (slaveDelayElement.isNumber()) { + _slaveDelay = Seconds(slaveDelayElement.numberInt()); + } else { + return Status(ErrorCodes::TypeMismatch, + str::stream() << kSlaveDelayFieldName << " field value has non-numeric type " + << typeName(slaveDelayElement.type())); + } + + // + // Parse hidden field. + // + status = + bsonExtractBooleanFieldWithDefault(mcfg, kHiddenFieldName, kHiddenFieldDefault, &_hidden); + if (!status.isOK()) + return status; + + // + // Parse buildIndexes field. + // + status = bsonExtractBooleanFieldWithDefault( + mcfg, kBuildIndexesFieldName, kBuildIndexesFieldDefault, &_buildIndexes); + if (!status.isOK()) + return status; + + // + // Parse "tags" field. + // + _tags.clear(); + BSONElement tagsElement; + status = bsonExtractTypedField(mcfg, kTagsFieldName, Object, &tagsElement); + if (status.isOK()) { + for (BSONObj::iterator tagIter(tagsElement.Obj()); tagIter.more();) { + const BSONElement& tag = tagIter.next(); + if (tag.type() != String) { + return Status(ErrorCodes::TypeMismatch, + str::stream() << "tags." << tag.fieldName() + << " field has non-string value of type " + << typeName(tag.type())); } + _tags.push_back(tagConfig->makeTag(tag.fieldNameStringData(), tag.valueStringData())); } - else if (ErrorCodes::NoSuchKey != status) { - return status; - } + } else if (ErrorCodes::NoSuchKey != status) { + return status; + } - // - // Add internal tags based on other member properties. - // - - // Add a voter tag if this non-arbiter member votes; use _id for uniquity. - const std::string id = str::stream() << _id; - if (isVoter() && !_arbiterOnly) { - _tags.push_back(tagConfig->makeTag(kInternalVoterTagName, id)); - } + // + // Add internal tags based on other member properties. + // - // Add an electable tag if this member is electable. - if (isElectable()) { - _tags.push_back(tagConfig->makeTag(kInternalElectableTagName, id)); - } + // Add a voter tag if this non-arbiter member votes; use _id for uniquity. + const std::string id = str::stream() << _id; + if (isVoter() && !_arbiterOnly) { + _tags.push_back(tagConfig->makeTag(kInternalVoterTagName, id)); + } - // Add a tag for generic counting of this node. - if (!_arbiterOnly) { - _tags.push_back(tagConfig->makeTag(kInternalAllTagName, id)); - } + // Add an electable tag if this member is electable. + if (isElectable()) { + _tags.push_back(tagConfig->makeTag(kInternalElectableTagName, id)); + } - return Status::OK(); + // Add a tag for generic counting of this node. + if (!_arbiterOnly) { + _tags.push_back(tagConfig->makeTag(kInternalAllTagName, id)); } - Status MemberConfig::validate() const { - if (_id < 0 || _id > 255) { - return Status(ErrorCodes::BadValue, str::stream() << kIdFieldName << - " field value of " << _id << " is out of range."); - } + return Status::OK(); +} - if (_priority < 0 || _priority > 1000) { - return Status(ErrorCodes::BadValue, str::stream() << kPriorityFieldName << - " field value of " << _priority << " is out of range"); - } - if (_votes != 0 && _votes != 1) { - return Status(ErrorCodes::BadValue, str::stream() << kVotesFieldName << - " field value is " << _votes << " but must be 0 or 1"); - } - if (_arbiterOnly) { - if (!_tags.empty()) { - return Status(ErrorCodes::BadValue, "Cannot set tags on arbiters."); - } - if (!isVoter()) { - return Status(ErrorCodes::BadValue, "Arbiter must vote (cannot have 0 votes)"); - } - } - if (_slaveDelay < Seconds(0) || _slaveDelay > kMaxSlaveDelay) { - return Status(ErrorCodes::BadValue, str::stream() << kSlaveDelayFieldName << - " field value of " << durationCount<Seconds>(_slaveDelay) << - " seconds is out of range"); - } - if (_slaveDelay > Seconds(0) && _priority != 0) { - return Status(ErrorCodes::BadValue, "slaveDelay requires priority be zero"); - } - if (_hidden && _priority != 0) { - return Status(ErrorCodes::BadValue, "priority must be 0 when hidden=true"); +Status MemberConfig::validate() const { + if (_id < 0 || _id > 255) { + return Status(ErrorCodes::BadValue, + str::stream() << kIdFieldName << " field value of " << _id + << " is out of range."); + } + + if (_priority < 0 || _priority > 1000) { + return Status(ErrorCodes::BadValue, + str::stream() << kPriorityFieldName << " field value of " << _priority + << " is out of range"); + } + if (_votes != 0 && _votes != 1) { + return Status(ErrorCodes::BadValue, + str::stream() << kVotesFieldName << " field value is " << _votes + << " but must be 0 or 1"); + } + if (_arbiterOnly) { + if (!_tags.empty()) { + return Status(ErrorCodes::BadValue, "Cannot set tags on arbiters."); } - if (!_buildIndexes && _priority != 0) { - return Status(ErrorCodes::BadValue, "priority must be 0 when buildIndexes=false"); + if (!isVoter()) { + return Status(ErrorCodes::BadValue, "Arbiter must vote (cannot have 0 votes)"); } - return Status::OK(); } + if (_slaveDelay < Seconds(0) || _slaveDelay > kMaxSlaveDelay) { + return Status(ErrorCodes::BadValue, + str::stream() << kSlaveDelayFieldName << " field value of " + << durationCount<Seconds>(_slaveDelay) + << " seconds is out of range"); + } + if (_slaveDelay > Seconds(0) && _priority != 0) { + return Status(ErrorCodes::BadValue, "slaveDelay requires priority be zero"); + } + if (_hidden && _priority != 0) { + return Status(ErrorCodes::BadValue, "priority must be 0 when hidden=true"); + } + if (!_buildIndexes && _priority != 0) { + return Status(ErrorCodes::BadValue, "priority must be 0 when buildIndexes=false"); + } + return Status::OK(); +} - bool MemberConfig::hasTags(const ReplicaSetTagConfig& tagConfig) const { - for (std::vector<ReplicaSetTag>::const_iterator tag = _tags.begin(); - tag != _tags.end(); - tag++) { - std::string tagKey = tagConfig.getTagKey(*tag); - if (tagKey[0] == '$') { - // Filter out internal tags - continue; - } - return true; +bool MemberConfig::hasTags(const ReplicaSetTagConfig& tagConfig) const { + for (std::vector<ReplicaSetTag>::const_iterator tag = _tags.begin(); tag != _tags.end(); + tag++) { + std::string tagKey = tagConfig.getTagKey(*tag); + if (tagKey[0] == '$') { + // Filter out internal tags + continue; } - return false; + return true; } + return false; +} - BSONObj MemberConfig::toBSON(const ReplicaSetTagConfig& tagConfig) const { - BSONObjBuilder configBuilder; - configBuilder.append("_id", _id); - configBuilder.append("host", _host.toString()); - configBuilder.append("arbiterOnly", _arbiterOnly); - configBuilder.append("buildIndexes", _buildIndexes); - configBuilder.append("hidden", _hidden); - configBuilder.append("priority", _priority); - - BSONObjBuilder tags(configBuilder.subobjStart("tags")); - for (std::vector<ReplicaSetTag>::const_iterator tag = _tags.begin(); - tag != _tags.end(); - tag++) { - std::string tagKey = tagConfig.getTagKey(*tag); - if (tagKey[0] == '$') { - // Filter out internal tags - continue; - } - tags.append(tagKey, tagConfig.getTagValue(*tag)); - } - tags.done(); +BSONObj MemberConfig::toBSON(const ReplicaSetTagConfig& tagConfig) const { + BSONObjBuilder configBuilder; + configBuilder.append("_id", _id); + configBuilder.append("host", _host.toString()); + configBuilder.append("arbiterOnly", _arbiterOnly); + configBuilder.append("buildIndexes", _buildIndexes); + configBuilder.append("hidden", _hidden); + configBuilder.append("priority", _priority); - configBuilder.append("slaveDelay", durationCount<Seconds>(_slaveDelay)); - configBuilder.append("votes", getNumVotes()); - return configBuilder.obj(); + BSONObjBuilder tags(configBuilder.subobjStart("tags")); + for (std::vector<ReplicaSetTag>::const_iterator tag = _tags.begin(); tag != _tags.end(); + tag++) { + std::string tagKey = tagConfig.getTagKey(*tag); + if (tagKey[0] == '$') { + // Filter out internal tags + continue; + } + tags.append(tagKey, tagConfig.getTagValue(*tag)); } + tags.done(); + + configBuilder.append("slaveDelay", durationCount<Seconds>(_slaveDelay)); + configBuilder.append("votes", getNumVotes()); + return configBuilder.obj(); +} } // namespace repl } // namespace mongo |