Status UpdatePositionArgs::initialize(const BSONObj& argsObj) { Status status = bsonCheckOnlyHasFields("UpdatePositionArgs", argsObj, kLegalUpdatePositionFieldNames); if (!status.isOK()) return status; // grab the array of changes BSONElement updateArray; status = bsonExtractTypedField(argsObj, kUpdateArrayFieldName, Array, &updateArray); if (!status.isOK()) return status; // now parse each array entry into an update BSONObjIterator i(updateArray.Obj()); while(i.more()) { BSONObj entry = i.next().Obj(); status = bsonCheckOnlyHasFields("UpdateInfoArgs", entry, kLegalUpdateInfoFieldNames); if (!status.isOK()) return status; OpTime ts; status = bsonExtractOpTimeField(entry, kOpTimeFieldName, &ts); if (!status.isOK()) return status; // TODO(spencer): The following three fields are optional in 2.8, but should be made // required or ignored in 3.0 long long cfgver; status = bsonExtractIntegerFieldWithDefault(entry, kConfigVersionFieldName, -1, &cfgver); if (!status.isOK()) return status; OID rid; status = bsonExtractOIDFieldWithDefault(entry, kMemberRIDFieldName, OID(), &rid); if (!status.isOK()) return status; long long memberID; status = bsonExtractIntegerFieldWithDefault(entry, kMemberIdFieldName, -1, &memberID); if (!status.isOK()) return status; _updates.push_back(UpdateInfo(rid, ts, cfgver, memberID)); } return Status::OK(); }
Status HandshakeArgs::initialize(const BSONObj& argsObj) { Status status = bsonCheckOnlyHasFields("HandshakeArgs", argsObj, kLegalHandshakeFieldNames); if (!status.isOK()) return status; BSONElement oid; status = bsonExtractTypedField(argsObj, kRIDFieldName, jstOID, &oid); if (!status.isOK()) return status; _rid = oid.OID(); _hasRid = true; status = bsonExtractIntegerField(argsObj, kMemberIdFieldName, &_memberId); if (!status.isOK()) { // field not necessary for master slave, do not return NoSuchKey Error if (status != ErrorCodes::NoSuchKey) { return status; } _memberId = -1; } else { _hasMemberId = true; } return Status::OK(); }
Status ReplSetRequestVotesArgs::initialize(const BSONObj& argsObj) { Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes", argsObj, kLegalArgsFieldNames); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_cfgver); if (!status.isOK()) return status; status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName); if (!status.isOK()) return status; status = bsonExtractBooleanField(argsObj, kDryRunFieldName, &_dryRun); if (!status.isOK()) return status; status = bsonExtractOpTimeField(argsObj, kLastCommittedOpFieldName, &_lastCommittedOp); if (!status.isOK()) return status; return Status::OK(); }
Status ReplSetRequestVotesResponse::initialize(const BSONObj& argsObj) { Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes", argsObj, kLegalResponseFieldNames); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term); if (!status.isOK()) return status; status = bsonExtractBooleanField(argsObj, kVoteGrantedFieldName, &_voteGranted); if (!status.isOK()) return status; status = bsonExtractStringField(argsObj, kReasonFieldName, &_reason); if (!status.isOK()) return status; status = bsonExtractBooleanField(argsObj, kOkFieldName, &_ok); if (!status.isOK()) return status; return Status::OK(); }
Status LastVote::initialize(const BSONObj& argsObj) { Status status = bsonCheckOnlyHasFields("VotedFar", argsObj, kLegalFieldNames); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId); if (!status.isOK()) return status; return Status::OK(); }
Status ReplSetHeartbeatArgs::initialize(const BSONObj& argsObj) { Status status = bsonCheckOnlyHasFields("ReplSetHeartbeatArgs", argsObj, kLegalHeartbeatFieldNames); if (!status.isOK()) return status; status = bsonExtractBooleanFieldWithDefault(argsObj, kCheckEmptyFieldName, false, &_checkEmpty); if (!status.isOK()) return status; _hasCheckEmpty = true; status = bsonExtractIntegerField(argsObj, kProtocolVersionFieldName, &_protocolVersion); if (!status.isOK()) return status; _hasProtocolVersion = true; status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_configVersion); if (!status.isOK()) return status; _hasConfigVersion = true; status = bsonExtractIntegerFieldWithDefault(argsObj, kSenderIdFieldName, -1, &_senderId); if (!status.isOK()) return status; _hasSenderId = true; status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName); if (!status.isOK()) return status; _hasSetName = true; std::string hostAndPortString; status = bsonExtractStringFieldWithDefault(argsObj, kSenderHostFieldName, "", &hostAndPortString); if (!status.isOK()) return status; if (!hostAndPortString.empty()) { status = _senderHost.initialize(hostAndPortString); if (!status.isOK()) return status; _hasSenderHost = true; } return Status::OK(); }
Status ReplSetRequestVotesArgs::initialize(const BSONObj& argsObj) { Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes", argsObj, kLegalArgsFieldNames); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId); if (!status.isOK()) return status; status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_cfgver); if (!status.isOK()) return status; status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName); if (!status.isOK()) return status; // extracting the lastCommittedOp is a bit of a process BSONObj lastCommittedOp = argsObj[kLastCommittedOpFieldName].Obj(); Timestamp ts; status = bsonExtractTimestampField(lastCommittedOp, kOpTimeFieldName, &ts); if (!status.isOK()) return status; long long term; status = bsonExtractIntegerField(lastCommittedOp, kTermFieldName, &term); if (!status.isOK()) return status; _lastCommittedOp = OpTime(lastCommittedOp[kOpTimeFieldName].timestamp(), lastCommittedOp[kTermFieldName].Long()); return Status::OK(); }
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()); } // // Parse votes field. // BSONElement votesElement = mcfg[kVotesFieldName]; int votes; 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())); } if (votes != 0 && votes != 1) { return Status(ErrorCodes::BadValue, str::stream() << kVotesFieldName << " field value is " << votesElement.numberInt() << " but must be 0 or 1"); } _isVoter = bool(votes); // // 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 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; } return Status::OK(); }
Status ReplSetHeartbeatResponseV1::initialize(const BSONObj& doc) { Status status = bsonCheckOnlyHasFields("ReplSetHeartbeatResponse", doc, kLegalHeartbeatFieldNames); if (!status.isOK()) return status; status = bsonExtractBooleanField(doc, kIsReplSetFieldName, &_isReplSet); if (!status.isOK()) return status; status = bsonExtractStringField(doc, kReplSetFieldName, &_setName); if (!status.isOK()) return status; long long stateInt; status = bsonExtractIntegerField(doc, kMemberStateFieldName, &stateInt); if (!status.isOK()) return status; if (stateInt < 0 || stateInt > MemberState::RS_MAX) { return Status(ErrorCodes::BadValue, str::stream() << "Value for \"" << kMemberStateFieldName << "\" in response to replSetHeartbeat is " "out of range; legal values are non-negative and no more than " << MemberState::RS_MAX); } _state = MemberState(static_cast<int>(stateInt)); // extracting the lastCommittedOp is a bit of a process BSONObj lastOpTime = doc[kLastOpTimeFieldName].Obj(); Timestamp ts; status = bsonExtractTimestampField(lastOpTime, kOpTimeFieldName, &ts); if (!status.isOK()) return status; long long term; status = bsonExtractIntegerField(lastOpTime, kTermFieldName, &term); if (!status.isOK()) return status; _lastOpTime = OpTime(lastOpTime[kOpTimeFieldName].timestamp(), lastOpTime[kTermFieldName].Long()); status = bsonExtractStringField(doc, kSyncSourceFieldName, &_syncingTo); if (!status.isOK()) return status; status = bsonExtractIntegerField(doc, kConfigVersionFieldName, &_configVersion); if (!status.isOK()) return status; status = bsonExtractIntegerField(doc, kPrimaryIdFieldName, &_primaryId); if (!status.isOK()) return status; status = bsonExtractIntegerField(doc, kTermFieldName, &_term); if (!status.isOK()) return status; const BSONElement hasDataElement = doc[kHasDataFieldName]; _hasDataSet = !hasDataElement.eoo(); _hasData = hasDataElement.trueValue(); const BSONElement rsConfigElement = doc[kConfigFieldName]; if (rsConfigElement.eoo()) { _configSet = false; _config = ReplicaSetConfig(); return Status::OK(); } else if (rsConfigElement.type() != Object) { return Status(ErrorCodes::TypeMismatch, str::stream() << "Expected \"" << kConfigFieldName << "\" in response to replSetHeartbeat to have type " "Object, but found " << typeName(rsConfigElement.type())); } _configSet = true; return _config.initialize(rsConfigElement.Obj()); }
Status ReplicaSetConfig::initialize(const BSONObj& cfg) { _isInitialized = false; _members.clear(); Status status = bsonCheckOnlyHasFields("replica set configuration", cfg, kLegalConfigTopFieldNames); if (!status.isOK()) return status; // // Parse replSetName // status = bsonExtractStringField(cfg, kIdFieldName, &_replSetName); if (!status.isOK()) return status; // // Parse version // status = bsonExtractIntegerField(cfg, kVersionFieldName, &_version); if (!status.isOK()) return status; // // Parse members // BSONElement membersElement; status = bsonExtractTypedField(cfg, kMembersFieldName, Array, &membersElement); if (!status.isOK()) return status; for (BSONObj::iterator membersIterator(membersElement.Obj()); membersIterator.more();) { BSONElement memberElement = membersIterator.next(); if (memberElement.type() != Object) { return Status(ErrorCodes::TypeMismatch, str::stream() << "Expected type of " << kMembersFieldName << "." << memberElement.fieldName() << " to be Object, but found " << typeName(memberElement.type())); } _members.resize(_members.size() + 1); const auto& memberBSON = memberElement.Obj(); status = _members.back().initialize(memberBSON, &_tagConfig); if (!status.isOK()) return Status(ErrorCodes::InvalidReplicaSetConfig, str::stream() << status.toString() << " for member:" << memberBSON); } // // Parse configServer // status = bsonExtractBooleanFieldWithDefault(cfg, kConfigServerFieldName, false, &_configServer); if (!status.isOK()) { return status; } // // Parse protocol version // status = bsonExtractIntegerField(cfg, kProtocolVersionFieldName, &_protocolVersion); if (!status.isOK() && status != ErrorCodes::NoSuchKey) { return status; } // // Parse settings // BSONElement settingsElement; status = bsonExtractTypedField(cfg, kSettingsFieldName, Object, &settingsElement); BSONObj settings; if (status.isOK()) { settings = settingsElement.Obj(); } else if (status != ErrorCodes::NoSuchKey) { return status; } status = _parseSettingsSubdocument(settings); if (!status.isOK()) return status; _calculateMajorities(); _addInternalWriteConcernModes(); _isInitialized = true; return Status::OK(); }