BSONObj ShardingCatalogManagerImpl::createShardIdentityUpsertForAddShard( OperationContext* opCtx, const std::string& shardName) { std::unique_ptr<BatchedUpdateDocument> updateDoc(new BatchedUpdateDocument()); BSONObjBuilder query; query.append("_id", "shardIdentity"); query.append(ShardIdentityType::shardName(), shardName); query.append(ShardIdentityType::clusterId(), ClusterIdentityLoader::get(opCtx)->getClusterId()); updateDoc->setQuery(query.obj()); BSONObjBuilder update; { BSONObjBuilder set(update.subobjStart("$set")); set.append( ShardIdentityType::configsvrConnString(), repl::ReplicationCoordinator::get(opCtx)->getConfig().getConnectionString().toString()); } updateDoc->setUpdateExpr(update.obj()); updateDoc->setUpsert(true); std::unique_ptr<BatchedUpdateRequest> updateRequest(new BatchedUpdateRequest()); updateRequest->addToUpdates(updateDoc.release()); BatchedCommandRequest commandRequest(updateRequest.release()); commandRequest.setNS(NamespaceString::kConfigCollectionNamespace); commandRequest.setWriteConcern(ShardingCatalogClient::kMajorityWriteConcern.toBSON()); return commandRequest.toBSON(); }
Status updateShardCollectionsEntry(OperationContext* opCtx, const BSONObj& query, const BSONObj& update, const BSONObj& inc, const bool upsert) { invariant(query.hasField("_id")); if (upsert) { // If upserting, this should be an update from the config server that does not have shard // refresh information. invariant(!update.hasField(ShardCollectionType::refreshing())); invariant(!update.hasField(ShardCollectionType::refreshSequenceNumber())); invariant(inc.isEmpty()); } // Want to modify the document, not replace it. BSONObjBuilder updateBuilder; updateBuilder.append("$set", update); if (!inc.isEmpty()) { updateBuilder.append("$inc", inc); } std::unique_ptr<BatchedUpdateDocument> updateDoc(new BatchedUpdateDocument()); updateDoc->setQuery(query); updateDoc->setUpdateExpr(updateBuilder.obj()); updateDoc->setUpsert(upsert); std::unique_ptr<BatchedUpdateRequest> updateRequest(new BatchedUpdateRequest()); updateRequest->addToUpdates(updateDoc.release()); BatchedCommandRequest request(updateRequest.release()); request.setNS(NamespaceString(ShardCollectionType::ConfigNS)); request.setWriteConcern(kLocalWriteConcern.toBSON()); BSONObj cmdObj = request.toBSON(); try { DBDirectClient client(opCtx); rpc::UniqueReply commandResponse = client.runCommandWithMetadata( "config", cmdObj.firstElementFieldName(), rpc::makeEmptyMetadata(), cmdObj); BSONObj responseReply = commandResponse->getCommandReply().getOwned(); Status commandStatus = getStatusFromCommandResult(commandResponse->getCommandReply()); if (!commandStatus.isOK()) { return commandStatus; } return Status::OK(); } catch (const DBException& ex) { return {ex.toStatus().code(), str::stream() << "Failed to apply the update '" << request.toString() << "' to config.collections" << causedBy(ex.toStatus())}; } }
std::unique_ptr<BatchedUpdateRequest> ShardIdentityType::createUpsertForAddShard() const { invariant(validate().isOK()); std::unique_ptr<BatchedUpdateDocument> updateDoc(new BatchedUpdateDocument()); BSONObjBuilder query; query.append("_id", "shardIdentity"); query.append("shardName", getShardName()); query.append("clusterId", getClusterId()); updateDoc->setQuery(query.obj()); BSONObjBuilder update; BSONObjBuilder setConfigBuilder(update.subobjStart("$set")); setConfigBuilder.append(configsvrConnString(), getConfigsvrConnString().toString()); setConfigBuilder.doneFast(); updateDoc->setUpdateExpr(update.obj()); updateDoc->setUpsert(true); std::unique_ptr<BatchedUpdateRequest> updateRequest(new BatchedUpdateRequest()); updateRequest->addToUpdates(updateDoc.release()); return updateRequest; }